【问题标题】:CMake cross compile target rpathCMake交叉编译目标rpath
【发布时间】:2015-08-04 16:37:34
【问题描述】:

我正在使用 CMake 进行交叉编译。

在我的 CMakeLists.txt 中(用于编译和交叉编译):

set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
find_package(foo REQUIRED)
add_library(mylib SHARED ${SRCS})
target_link_libraries(mylib ${FOO_LIBRARIES)

在我的 toolchain.cmake 中:

set(CMAKE_CXX_FLAGS "... --sysroot=/path/to/sysroot/ ... ")
set(CMAKE_CXX_LINK_FLAGS "... --sysroot=/path/to/sysroot/ ... )
...
set(CMAKE_FIND_ROOT_PATH /path/to/sysroot)

考虑 foo 位于 /path/to/sysroot/usr/local/lib/foo.so,当我为 mylib/path/to/sysroot/usr/local/lib

我希望运行时路径是 /usr/local/lib 以反映我的目标文件系统。

如果不在我的 CMakelists.txt 中定义硬编码的 CMAKE_INSTALL_RPATH 变量,我怎么能做到这一点?

编辑:我使用 /usr/local/lib 作为示例,但 foo lib 位于不属于系统目录的特定文件夹中:/path/to/sysroot/usr /local/share/mypackage/lib/foo.so

【问题讨论】:

    标签: cmake cross-compiling rpath


    【解决方案1】:

    您只需要:

    set(CMAKE_BUILD_RPATH "/my/libs/location")

    指定运行时路径 (RPATH) 条目以添加到构建树中链接的二进制文件(对于支持它的平台)。这些条目不会用于安装树中的二进制文件。另请参阅 CMAKE_INSTALL_RPATH 变量。

    【讨论】:

      【解决方案2】:

      查看CMake RPATH handling 上的 wiki。

      默认情况下,CMake 使用指向主机系统库位置 (/crosssdk/sysroot/usr/lib/) 的 RPATH 编译您的可执行文件,然后(我相信)在安装时(即 make install)它会编辑可执行文件中的 RPATH 以替换它与适当的目标 RPATH (/usr/lib 或任何你有它)。我认为这个想法是,您可以更改共享库并在主机系统上执行输出,而无需每次都安装共享库和可执行文件。 就我而言,我的主机是 x86,目标是 ARM,所以我告诉 CMake 将构建 RPATH 设置为与安装 RPATH 相同:

      set_target_properties(mytarget PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
      

      【讨论】:

      • 这个想法不能在我的情况下使用,因为我的库与位于非标准位置的其他库链接。所以,除了 /usr/local/lib 之外,我还需要将 rpath 设置为额外的位置。
      • 由于它是一个非标准位置,您必须将路径设置为库somewhere。在目标系统上设置 LD_LIBRARY_PATH 可能是一种解决方案。
      【解决方案3】:

      我不确定您使用的是哪个交叉编译工具链。

      您需要指定 C/CXX 编译器、链接器等。 除此之外,一些重要的变量是 CMAKE_FIND_ROOT_PATH_MODE_LIBRARY 和 CMAKE_FIND_ROOT_PATH_MODE_INCLUDE。如果您将它们设置为“ONLY”,当您调用 FindXXX() 时,搜索只会在目标根文件系统目录中进行,而不是在构建机器中进行。

      在我的例子中,我不必指定 sysroot,因为交叉编译器已经知道它是交叉编译,并且它还知道目标根文件系统的位置。

      使用这个工具链文件,我只需编译源代码而不需要任何额外的标志,在目标上加载可执行文件,它运行良好,直接从正确的路径获取 *.so 文件。

      试一试,告诉我进展如何。

      这是我的工具链文件:

      set(ELDK_DIR /opt/eldk/ppc-v42-1)
      
      
      set (CMAKE_C_COMPILER ${ELDK_DIR}/usr/bin/ppc_6xx-gcc)
      set (CMAKE_CXX_COMPILER ${ELDK_DIR}/usr/bin/ppc_6xx-g++)
      set (CMAKE_LINKER ${ELDK_DIR}/usr/bin/ppc_6xx-ld CACHE STRING "Set the cross-compiler tool LD" FORCE)
      set (CMAKE_AR ${ELDK_DIR}/usr/bin/ppc_6xx-ar CACHE STRING "Set the cross-compiler tool AR" FORCE)
      set (CMAKE_NM ${ELDK_DIR}/usr/bin/ppc_6xx-nm CACHE STRING "Set the cross-compiler tool NM" FORCE)
      set (CMAKE_OBJCOPY ${ELDK_DIR}/usr/bin/ppc_6xx-objcopy CACHE STRING "Set the cross-compiler tool OBJCOPY" FORCE)
      set (CMAKE_OBJDUMP ${ELDK_DIR}/usr/bin/ppc_6xx-objdump CACHE STRING "Set the cross-compiler tool OBJDUMP" FORCE)
      set (CMAKE_RANLIB ${ELDK_DIR}/usr/bin/ppc_6xx-ranlib CACHE STRING "Set the cross-compiler tool RANLIB" FORCE)
      set (CMAKE_STRIP ${ELDK_DIR}/usr/bin/ppc_6xx-strip CACHE STRING "Set the cross-compiler tool RANLIB" FORCE)
      
      # Target environment
      set (CMAKE_FIND_ROOT_PATH ${ELDK_DIR}/ppc_6xx)
      
      # Don't search for programs in the host environment
      set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
      
      # Search for the libraries and headers in the target environment
      set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
      set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
      

      【讨论】:

      • 我的工具链文件定义了编译器等...我的代码比我的工具链文件短。控制 findXXX 命令的 Cmake 变量已正确设置为您的。我除了你没有链接到不在你的 sysroot 的默认系统文件夹中的共享库,这就是你的 rpath 设置正确的原因,因为 CMake 没有改变(你的 rpath 是系统目录)
      猜你喜欢
      • 2012-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 2017-05-08
      • 2016-12-28
      • 2021-05-03
      相关资源
      最近更新 更多