尝试在交叉编译中链接库时编译错误

时间:2019-09-24 10:45:32

标签: c++ c cmake arm cross-compiling

已解决-帖子末尾的说明

我正在研究一个项目,现在我必须交叉编译两个用于ARM的软件包,一个库和一个依赖该库的应用程序。

我为库和应用程序都有一个.cmake文件,它似乎可以工作,除了以下事实:每当编译过程到达链接阶段时,编译器便说找不到某些库然后关闭。

我已经检查过,并且我的系统满足了从源代码构建这些程序的所有要求,但是,关于项目的配置,还有一些事情要知道。

在交叉编译时,我需要的所有库都必须是它们的ARM版本,这完全不是问题,但是我认为提供这些库的方式是造成所有麻烦的原因。我只是在这里猜测,因为我无法想到可能发生的任何其他原因。

因此,我正在使用.cmake文件提供这些库,该文件如下所示:

set( TC_PATH "/usr/bin/" )
set( ROOTFS_PATH "/home/pc/Desktop/projects/rootfs" )
set( CROSS_LOCAL_PREFIX "/usr" )

set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_SYSTEM_PROCESSOR arm )

set( CROSS_COMPILE arm-linux-gnueabihf- )

set( CMAKE_C_COMPILER "${TC_PATH}${CROSS_COMPILE}gcc" )
set( CMAKE_CXX_COMPILER "${TC_PATH}${CROSS_COMPILE}g++" )
set( CMAKE_LINKER "${TC_PATH}${CROSS_COMPILE}ld" )
set( CMAKE_AR "${TC_PATH}${CROSS_COMPILE}ar" )
set( CMAKE_OBJCOPY "${TC_PATH}${CROSS_COMPILE}objcopy" )

set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY )

set( CMAKE_PREFIX_PATH ${ROOTFS_PATH} )
set( CMAKE_INSTALL_PREFIX "${ROOTFS_PATH}${CROSS_LOCAL_PREFIX}" )
set( CMAKE_FIND_ROOT_PATH ${ROOTFS_PATH} )
set( ENV{PKG_CONFIG_PATH} "${ROOTFS_PATH}${CROSS_LOCAL_PREFIX}/lib/pkgconfig/" )
set( ENV{PKG_CONFIG_SYSROOT_DIR} ${ROOTFS_PATH} )

set( CAER_LOCAL_PREFIX ${CROSS_LOCAL_PREFIX} )
set( CAER_LOCAL_INCDIRS "${ROOTFS_PATH}${CROSS_LOCAL_PREFIX}/include/" )
set( CAER_LOCAL_LIBDIRS "${ROOTFS_PATH}/lib/;${ROOTFS_PATH}${CROSS_LOCAL_PREFIX}/lib/" )

因此,正如文件所指定的那样,保留库的目录是“ $ {ROOTFS_PATH} / lib /”和“ $ {ROOTFS_PATH} $ {CROSS_LOCAL_PREFIX} / lib /”,最终将其翻译为“ / home / pc / Desktop / projects / rootfs / lib /”和“ / home / pc / Desktop / projects / rootfs / usr / lib”。

该路径有点不符合常规,但这就是ARM库所在的位置。原因是“ rootfs”目录包含一个用于小型Linux发行版的文件系统,该发行版旨在在嵌入式硬件上运行,并使用SD卡进行存储,并且除了这两个程序外,它已经具有所需的一切。无法编译。

由于库的目录正确,我希望编译会顺利进行,但事实并非如此。相反,我遇到了多个与库有关的错误:

编译结果:

[  7%] Linking C shared library libcaer.so
/usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/bin/ld: cannot find /lib/libc.so.6
/usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/bin/ld: cannot find /usr/lib/libc_nonshared.a
/usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/bin/ld: cannot find /lib/ld-linux-armhf.so.3
collect2: error: ld returned 1 exit status
src/CMakeFiles/caer.dir/build.make:248: recipe for target 'src/libcaer.so.3.1.0' failed
make[2]: *** [src/libcaer.so.3.1.0] Error 1
CMakeFiles/Makefile2:135: recipe for target 'src/CMakeFiles/caer.dir/all' failed
make[1]: *** [src/CMakeFiles/caer.dir/all] Error 2
Makefile:151: recipe for target 'all' failed
make: *** [all] Error 2

但是,这就是令我发疯的原因,当错误弹出时,他们说 /lib/libc.so.6 或其他缺少的库,不是说 /缺少home / pc / Desktop / projects / rootfs / usr / lib /任何内容

由此,我猜即使没有在.cmake文件中指定正确的目录,也没有在正确的目录中查找库。

我以前已经成功构建了这两个程序,但是唯一一次做到这一点,我不得不将未找到的特定库复制到编译器告诉我要在其中查找的特定路径中。 / p>

这意味着我将“ /home/pc/Desktop/projects/rootfs/usr/lib/libc_nonshared.a”复制到“ /usr/lib/libc_nonshared.a”,依此类推。

这种方法是不可接受的,因为我可能必须给其他人一些指令,以便他们自己编译应用程序,并复制其他地方已经存在的库,只是因为编译器“忽略”它们只是感觉不对。

所以,这是我所能做到的,我希望有人能够对此事有所启发。预先非常感谢。

更新-已解决

因此,最后我徘徊在cmake工具链文件文档页面(https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html)上,我偶然发现了一个名为“ CMAKE_SYSROOT”的变量,该变量是可选的,如果有其他sysroot则可以使用而不是主机系统中的情况(在这种情况下)。因此,我尝试像这样设置变量:

set(CMAKE_SYSROOT "${ROOTFS_PATH}")

奇迹般地奏效了;它停止在我的根系统(/ lib /...、/ usr / lib / ...)中寻找库,所以我猜文件系统中的库提供了最终使用的库,编译成功结束了库和相关应用程序。

0 个答案:

没有答案