CMake 交叉编译目标 rpath

CMake cross compile target rpath

我正在使用 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)

当我交叉编译 [=26 的运行时路径时,考虑 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

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

您需要指定 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)

查看 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)

您只需要:

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

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