c++ - 跨平台 Poco 库链接问题
问题描述
我使用特殊的 arm 工具链文件和构建脚本在 Ubuntu amd 平台上使用 cmake 编译了 Poco:
#!/bin/sh
cd cmake_build
cmake \
-G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_TOOLCHAIN_FILE=~/RPi/Toolchain-RaspberryPi.cmake \
-DCMAKE_INSTALL_PREFIX=~/RPi/rootfs/usr/local \
..
make -j4
工具链文件:
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
# Specify the cross compiler
SET(CMAKE_C_COMPILER $ENV{HOME}/RPi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER $ENV{HOME}/RPi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-g++)
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/RPi/rootfs)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
# Search for programs only in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Search for libraries and headers only in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
我将 poco 安装make install
到预配置文件夹:~/RPi/rootfs/usr/local/
.
我将所有 Poco 文件复制到 Raspberry 文件系统 - lib
, lib/cmake
, include
.
我有跟随cmake的小测试项目:
cmake_minimum_required (VERSION 3.7)
# Name of the project
project(raspi_ld_test)
message("BUILD ENVIRONMENT SET TO -${BUILD_ENV}-")
if (${BUILD_ENV} STREQUAL "UBUNTU")
set(POCO_PATH "~/RPi/rootfs/usr/local")
elseif(${BUILD_ENV} STREQUAL "RASPI")
set(POCO_PATH "/usr/local")
else()
message(FATAL_ERROR "Undefined environment")
endif()
find_package(Poco REQUIRED Foundation Util HINTS ${POCO_PATH} NO_CMAKE_FIND_ROOT_PATH)
find_package(Threads REQUIRED)
# Alert the user if we do not find it
if(NOT WPI_LIB)
message(FATAL_ERROR "wiringPi library not found")
endif()
# Add the local ‘include’ directory and the wiringPi directory to grab headers
include_directories("${POCO_PATH}/include")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED on)
# Add all the *.cpp files in our source directory to our executable output
file(
GLOB_RECURSE
SOURCES
"src/*.cpp"
)
add_executable(raspi_ld_test ${SOURCES})
link_directories(${POCO_PATH}/lib)
# Link the pre-compiled wiringPi library to the executable we just declared
target_link_libraries(
raspi_ld_test
${CMAKE_THREAD_LIBS_INIT}
Poco::Foundation
)
我只有一个 src/main.cpp:
#include "Poco/BasicEvent.h"
#include "Poco/Delegate.h"
#include <iostream>
using Poco::BasicEvent;
using Poco::Delegate;
class Source
{
public:
BasicEvent<int> theEvent;
void fireEvent(int n)
{
theEvent(this, n);
}
};
class Target
{
public:
void onEvent(const void* pSender, int& arg)
{
std::cout << "onEvent: " << arg << std::endl;
}
};
int main(int argc, char** argv)
{
Source source;
Target target;
source.theEvent += Delegate<Target, int>(
&target, &Target::onEvent);
source.fireEvent(42);
source.theEvent -= Delegate<Target, int>(
&target, &Target::onEvent);
return 0;
}
现在,我可以在 Ubuntu 上成功编译项目了。如果我将 raspi_ld_test 复制到 Raspberry,我可以成功运行它。但!我无法在 Raspberry 上构建项目,出现以下错误:
CMakeFiles/raspi_ld_test.dir/src/main.cpp.o: 在函数
Poco::MutexImpl::lockImpl()': /usr/local/include/Poco/Mutex_POSIX.h:60: undefined reference to
Poco::SystemException::SystemException(std::__cxx11::basic_string, std::allocator > const&, int)' CMakeFiles/raspi_ld_test.dir/src/ main.cpp.o: 在函数Poco::MutexImpl::unlockImpl()': /usr/local/include/Poco/Mutex_POSIX.h:79: undefined reference to
Poco::SystemException::SystemException(std::__cxx11::basic_string, std::allocator > const&, int)' collect2: 错误: ld 返回 1 退出状态 CMakeFiles/raspi_ld_test.dir/build .make:99: 目标 'raspi_ld_test' 的配方失败 make[2]: * [raspi_ld_test] 错误 1 CMakeFiles/Makefile2:67: 目标'CMakeFiles/raspi_ld_test.dir/all' 的配方失败 make[1]: * [CMakeFiles /raspi_ld_test.dir/all] 错误 2 Makefile:83: 目标“all”的配方失败 make: *** [all] 错误 2
我看到库链接成功:
pi@raspberrypi:/usr/local/lib $ ldd libPocoFoundationd.so
linux-vdso.so.1 (0x7ef90000)
/usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76bfe000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76bd5000)
libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76bc2000)
librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76bab000)
libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x76a63000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x769e4000)
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x769b7000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76878000)
/lib/ld-linux-armhf.so.3 (0x76f03000)
更新
这是在 amd 上编译并复制到 arm 可执行文件的 ldd 输出:
pi@raspberrypi:~/raspi_ld_test/build $ ldd raspi_ld_test
linux-vdso.so.1 (0x7efd0000)
/usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76f0f000)
libwiringPi.so => /usr/lib/libwiringPi.so (0x76ef1000)
libPocoUtild.so.60 => /usr/local/lib/libPocoUtild.so.60 (0x76e35000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76e0c000)
libPocoXMLd.so.60 => /usr/local/lib/libPocoXMLd.so.60 (0x76d1f000)
libPocoJSONd.so.60 => /usr/local/lib/libPocoJSONd.so.60 (0x76c8b000)
libPocoFoundationd.so.60 => /usr/local/lib/libPocoFoundationd.so.60 (0x7699c000)
libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76989000)
librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76972000)
libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x7682a000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x767ab000)
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x7677e000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x7663f000)
libcrypt.so.1 => /lib/arm-linux-gnueabihf/libcrypt.so.1 (0x76600000)
/lib/ld-linux-armhf.so.3 (0x76f25000)
这是运行的输出:
pi@raspberrypi:~/raspi_ld_test/build $ ./raspi_ld_test
onEvent: 42
问题是:在 amd 上为 arm 编译的 Poco 库怎么可能有利于 arm 上的运行时链接,但不适合 arm 上的构建时链接,以及我需要做什么才能在 arm 上构建项目?
更新
因此,正如我从评论中看到的那样,使用不同版本的 g++ 在 amd 上使用 arm 工具链编译的库是不可能在 arm 上编译项目的......
我有以下版本:
Ubuntu 上的 ARM 工具链:
olga@olga-MS-7758:~/raspi_ld_test$ ~/RPi/tools/arm-bcm2708/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ --version
arm-linux-gnueabihf-g++ (crosstool-NG crosstool-ng-1.22.0-88-g8460611) 4.9.3
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Raspbian 上的 ARM 工具链:
pi@raspberrypi:~/Poco/cmake $ g++ --version
g++ (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
所以我需要搜索为 Ubuntu 编译的 BCM (raspberry) 6.3 g++?
解决方案
推荐阅读
- content-management-system - 在 webtop 6.8.2 中,我导入了 documentum,其中文件夹 r_object_type 与实际必须是不匹配的
- python - Pylint:__init__ [abstract-method] vs [useless-super-delegation] 警告
- laravel - ElasticBeanstalk 的 EC2 实例未在终端/ssh 中检索 Laravel 应用程序的 Beanstalk 控制台中设置的 .env 变量
- javascript - 请求输入,然后使用输入的数据重定向到网站
- android - Android BLE 扫描 - 无法在屏幕关闭时开始未经过滤的扫描
- javascript - 如何创建稳定的可拖动元素?
- javascript - 如何使用 Sequalize 连接到数据库 - Mocha Node 和 javascript
- assembly - CMP dword ptr [EBP + local_c],0xdeadbeef 是什么意思?
- path - Grep:搜索较短的文件路径,忽略较长的文件路径
- csv - 仅下载 locust csv 中的相关列