【发布时间】: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