【问题标题】:cmake cross-compiling arm transitional dependencies libs not found未找到 cmake 交叉编译 arm 过渡依赖库
【发布时间】:2021-10-15 17:51:42
【问题描述】:

我有一个 C++ 大程序,我为 Jetson TX2 交叉编译 这个程序的结构是这样的:

root  
| - module1  
| | - CMakeLists.txt  
| - module2  
| | - CMakeLists.txt  
| - CMakeLists.txt  
| - toolchain.cmake

每个模块子文件夹创建一个共享库,我的主要目标链接。
jetson 的工具链是

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)

SET(CROSS_COMPILE "jetson")

SET(CMAKE_C_COMPILER   aarch64-linux-gnu-gcc-5)
SET(CMAKE_CXX_COMPILER aarch64-linux-gnu-gcc-5)

SET(CMAKE_SYSROOT /usr/local/sysroot_jetson)

set(ENV{PKG_CONFIG_DIR} "")
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig:${CMAKE_SYSROOT}/usr/local/lib/pkgconfig:${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig")
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})

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)

到目前为止,我完全没有问题,直到现在我需要包含一个具有 tensorflow 依赖的新模块。

我已经在 /usr/local/lib 中安装了 tensorflow_cc 库。 这个 TF 库是在 GPU 支持下编译的,因此连接了安装在 jetson 上的 cuda-9.0 中的许多东西。

模块的 CMakeLists.txt 只需链接到 tensorflow,如下所示。
这当然是简化的。

target_link_libraries(${LIB_NAME} -ltensorflow_cc)

只要我不交叉编译它就可以正常工作。
直接在 jetson 或我的主机上编译可以正常工作。

但添加工具链无济于事。
编译时,tensorflow模块的共享库实际上编译得很好,但链接最终目标只是输出以下内容

/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libcublas.so.9.0, needed by /usr/local/sysroot_jetson/usr/local/lib/libtensorflow_cc.so, not found (try using -rpath or -rpath-link)
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libcusolver.so.9.0, needed by /usr/local/sysroot_jetson/usr/local/lib/libtensorflow_cc.so, not found (try using -rpath or -rpath-link)
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libcudart.so.9.0, needed by /usr/local/sysroot_jetson/usr/local/lib/libtensorflow_cc.so, not found (try using -rpath or -rpath-link)
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libcuda.so.1, needed by /usr/local/sysroot_jetson/usr/local/lib//libtensorflow_framework.so, not found (try using -rpath or -rpath-link)
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libcufft.so.9.0, needed by /usr/local/sysroot_jetson/usr/local/lib//libtensorflow_framework.so, not found (try using -rpath or -rpath-link)
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libcurand.so.9.0, needed by /usr/local/sysroot_jetson/usr/local/lib//libtensorflow_framework.so, not found (try using -rpath or -rpath-link)
/usr/local/sysroot_jetson/usr/local/lib//libtensorflow_framework.so: undefined reference to `cublasDrotm_v2@libcublas.so.9.0'
/usr/local/sysroot_jetson/usr/local/lib/libtensorflow_cc.so: undefined reference to `cusolverDnZgeqrf@libcusolver.so.9.0'
/usr/local/sysroot_jetson/usr/local/lib//libtensorflow_framework.so: undefined reference to `cuEventElapsedTime'
......

所有需要的文件都可以在 /usr/local/sysroot_jetson/usr/local/cuda/lib64 的 sysroot 中找到

我的理解是,在 /etc/ld.so.conf.d 中设置的所有 ld 额外路径都没有被使用或读取。
我应该能够指示 cmake 寻找那些额外的搜索路径,但我尝试了所有我能读到的东西而没有任何改变。
pkg-config 有所有 cuda 库的文件,所以我可以做

pkg_check_modules(cudaall REQUIRED cuda-9.0 cublas-9.0 cusolver-9.0 cudart-9.0 cufft-9.0 curand-9.0)

它找到了它们,但它只是失败了

/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: cannot find -lcublas
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: cannot find -lcusolver
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: cannot find -lcudart
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: cannot find -lcufft
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: cannot find -lcurand

添加一个 -L${CMAKE_SYSROOT}/usr/local/cuda-9.0/lib64(我不应该这样做)只会螺旋到其他未找到的 nvidia 库。

/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libnvrm_gpu.so, needed by /usr/local/sysroot_jetson/usr/lib/aarch64-linux-gnu/libcuda.so, not found (try using -rpath or -rpath-link)
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libnvrm.so, needed by /usr/local/sysroot_jetson/usr/lib/aarch64-linux-gnu/libcuda.so, not found (try using -rpath or -rpath-link)
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libnvidia-fatbinaryloader.so.28.2.1, needed by /usr/local/sysroot_jetson/usr/lib/aarch64-linux-gnu/libcuda.so, not found (try using -rpath or -rpath-link)

我真正不明白的是,为什么 cmake 关心 tensorflow_cc.so 链接哪些库?
这不应该是运行时问题吗?
我不能只链接到 tensorflow_cc.so 并在编译时关心它的依赖关系吗?

这一切都让我很困惑。

任何见解都将不胜感激。

【问题讨论】:

  • "为什么 cmake 关心 tensorflow_cc.so 链接的库?" - CMake 什么都不在乎。看,警告来自 linker (.../aarch64-linux-gnu/bin/ld),而不是来自 CMake。当与共享库链接时,链接器也链接到它们所依赖的所有库。所以它需要找到那些依赖库。而且您的 RPATH 设置不允许链接器找到这些库。请注意,该警告消息并未将 -L 选项列为问题的解决方案。
  • 好的,但是我如何在交叉编译环境中指示链接器的附加路径来完成与 /etc/ld.so.conf.d 中的相同的工作?/ld.so.conf.d跨度>

标签: cmake


【解决方案1】:

在 CMakeLists.txt 中添加:

set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS_INIT} $ENV{LDFLAGS}")

在控制台运行:

export LDFLAGS="-Wl,-rpath=/sysroot/lib/aarch64-linux-gnu "$LDFLAGS

构建应用后

【讨论】:

    猜你喜欢
    • 2013-07-17
    • 1970-01-01
    • 2016-10-28
    • 2016-01-15
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多