我正在尝试在ubuntu机器上交叉编译树莓派(32位armv8)的项目。我使用crosstool-NG建立了工具链并进行了编译,但是链接失败。我的CMake工具链文件如下:
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSROOT /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/sysroot)
SET(CMAKE_C_COMPILER /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/bin/armv8-rpi3-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/bin/armv8-rpi3-linux-gnueabihf-g++)
SET(CMAKE_FIND_ROOT_PATH /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
我有一些链接器找不到的库。问题出在我的sysroot上。我从pi复制了/usr
和/lib
到由crosstool-NG创建的sysroot文件夹。链接的库位于sysroot/usr/lib/arm-linux-gnueabihf
中。
但是,链接器没有检查该目录,而是检查sysroot / usr / lib和其他一些目录,但是由于某种原因,它不检查arm-linux-gnueabihf目录。
在pi上,我可以运行ld -lasound --verbose
并获得以下输出:
attempt to open //usr/local/lib/arm-linux-gnueabihf/libasound.so failed
attempt to open //usr/local/lib/arm-linux-gnueabihf/libasound.a failed
attempt to open //lib/arm-linux-gnueabihf/libasound.so failed
attempt to open //lib/arm-linux-gnueabihf/libasound.a failed
attempt to open //usr/lib/arm-linux-gnueabihf/libasound.so succeeded
因此可以在pi上正确找到它。
当我使用crosstool-NG生成的ld执行相同操作时:
attempt to open /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/bin/../sysroot/home/stone/x-tools/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/lib/libasound.so failed
attempt to open /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/bin/../sysroot/home/stone/x-tools/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/lib/libasound.a failed
attempt to open /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/bin/../sysroot/usr/local/lib/libasound.so failed
attempt to open /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/bin/../sysroot/usr/local/lib/libasound.a failed
attempt to open /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/bin/../sysroot/lib/libasound.so failed
attempt to open /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/bin/../sysroot/lib/libasound.a failed
attempt to open /home/stone/development/raspberry_pi/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/bin/../sysroot/usr/lib/libasound.so failed
找不到它,因为它不在arm-linux-gnueabihf目录中。我将库.so文件从sysroot / usr / lib / arm-linux-gnueabihf复制到sysroot / usr / lib,它可以成功编译和链接,但是我想这样做,因此不必这样做。如何使链接程序检查arm-linux-gnueabihf目录?
编辑:我还从pi复制了/etc/ld.so.conf和/etc/ld.so.conf.d到我的sysroot中,但是它似乎并不影响链接器。
编辑:经过进一步研究,看来这可能是由于gcc-multiarch引起的。我不确定那是什么,但希望我能弄清楚
编辑:我验证了链接器的确没有在搜索arm-linux-gnueabihf路径:
./armv8-rpi3-linux-gnueabihf-ld --verbose | grep -i "search"
输出:
SEARCH_DIR("=/home/stone/x-tools/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
答案 0 :(得分:1)
好吧,我知道了。 here是我从中了解到使它起作用的技巧的仓库。我对此回购表示感谢,没有它,我将无法正常工作。
问题出在链接器上。由crosstool-ng插入的普通旧binutils附带的链接器不会搜索arm-linux-gnueabihf子目录。这些目录是由于Debian多体系结构而存在的,为了获得在该目录中看起来的链接器,需要对binutils进行修补。以下说明假定您已经基于rpi3示例生成了ct-ng配置。
在树莓派上,我安装了binutils-source软件包:
$ sudo apt install binutils-source
这将允许访问/ usr / src / binutils / patches中的补丁文件。
在主机上,您需要在构建工具链的目录(ct-ng配置文件所在的目录)中添加一个patchs目录。它必须具有反映crosstool-ng存储库中packages的结构的特定结构(即,在patch /中,您必须具有包含软件包名称的目录,在其中必须具有版本号,并且在其中是放置补丁的位置。):
$ cd your_toolchain_directory
$ mkdir -p patches/binutils/2.31.1/
现在我们可以将补丁文件从pi复制到主机。我们需要的特定补丁是129_multiarch_libpath.patch:
$ cd patches/binutils/2.31.1/
$ scp pi@raspberrypi:/usr/src/binutils/129_multiarch_libpath.patch
现在我们有了补丁,我们需要更新配置文件以告知ct-ng包括本地补丁,并为gcc启用multiarch标志。您可以使用ct-ng menuconfig来执行此操作,因此请使用配置文件返回目录并运行:
$ ct-ng menuconfig
在路径和其他选项中,您需要将修补程序源更改为捆绑的,然后更改为本地,然后将$ {CT_TOP_DIR} / patches添加为本地修补程序目录。这应该在.config文件的解压缩部分下产生以下几行:
CT_PATCH_BUNDLED_LOCAL=y
CT_PATCH_ORDER="bundled,local"
CT_PATCH_USE_LOCAL=y
CT_LOCAL_PATCH_DIR="${CT_TOP_DIR}/patches"
接下来,您需要在gcc选项中添加--enable-multiarch标志。再次使用menuconfig,转到C编译器设置。将--enable-multiarch添加到gcc Extra配置设置中。配置文件在gcc设置中应具有以下内容:
CT_CC_GCC_EXTRA_CONFIG_ARRAY="--enable-multiarch"
保存配置。我们需要做的最后一件事是导出变量。
$ export DEB_TARGET_MULTIARCH=arm-linux-gnueabihf
现在我们可以构建工具链:
$ ct-ng build
完成后,您可以进入生成的工具链的bin目录并运行:
$ ./ld --verbose | grep -i "search"
,您应该看到arm-linux-gnueabihf目录现在位于搜索路径中。真是个过程。
答案 1 :(得分:-1)
您需要改用静态库。然后可执行文件将包含库的二进制文件。 但是请记住,可执行文件会更大(显然取决于哪个lib ...)。 使用交叉编译时,应检查所使用的库在执行程序的其他环境中是否存在。 解决方法是根据CmakeList.txt文件添加STATIC字