在Linux上构建程序的链接阶段,依赖于运行路径的库无法找到它的依赖关系

时间:2018-01-08 11:21:48

标签: c++ linux cmake libraries

我试图了解在macOS和Linux上使用运行路径依赖库时写了tutorial projectsimpleapp取决于libmymathslibfastmatrix依赖于libmymaths./run.sh是一个运行路径依赖库,您可以看到项目here的结构。我正在尝试使用特定于操作系统的宏(用于macOS的@executable_path和用于linux的$ ORIGIN),以便允许二进制文件轻松移动而不会中断,因为它们的位置将在运行时解析并替换为宏。然而,虽然到目前为止我编写的程序在macOS上运行得很好,但它并不适用于Linux。具体来说,我在simpleapp的链接阶段遇到以下错误(您可以使用/usr/bin/ld: warning: libfastmatrix.so, needed by /home/thomas/Developer/rpath_tutorial/libmymaths/libmymaths.so, not found (try using -rpath or -rpath-link)简单地重现):

ldd libmymaths.so

libmymaths' CMakeLists.txt中,我指定了可以找到其依赖项(libfastmatrix)的rpath,并且一旦构建了libmymaths,就可以使用if(APPLE) set(TOKEN "@loader_path") elseif(UNIX AND NOT APPLE) set(TOKEN "$ORIGIN") endif() set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11 CXX_EXTENSIONS FALSE BUILD_WITH_INSTALL_RPATH TRUE INSTALL_NAME_DIR "@rpath" # Necessary prior CMP0042 introduction. INSTALL_RPATH "${TOKEN}/../libfastmatrix" ) 进行验证。

# # Fix 1, -rpath-link (linux-specific ld option)
# LINK_FLAGS "-Wl,-rpath-link,${CMAKE_CURRENT_SOURCE_DIR}/../libfastmatrix/"

# # Fix 2, additional (unecessary for macOS) rpath, overwrites line 47
# INSTALL_RPATH "${TOKEN}/../libmymaths;${CMAKE_CURRENT_SOURCE_DIR}/../libfastmatrix"

我已经在Simpleapp的主CMake script中将ld的建议实现为修复1和修复2,这允许项目构建。

{{1}}

然而,这与我正在尝试实现的目标相反 - 让每个库负责自己的依赖关系而不会污染其他具有依赖关系的项目。

1)我在Linux上实现目标需要做哪些改变?就像我在macOS上所做的那样? 2)如果这是不可行的,因为我所采取的整个方法都是不正确的,你能提供一些证据或来源吗?

我正在使用:
CMake 3.5.1
ld 2.26.1
gcc 5.4.0

感谢。

1 个答案:

答案 0 :(得分:0)

我在游戏项目中这样做。以下是我使用它来完成工作的步骤。

cmake_minimum_required(VERSION 3.5)

if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
  set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
  set(CMAKE_INSTALL_RPATH "$ORIGIN/lib/:$$ORIGIN/lib/")
endif()

if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    install(TARGETS SpeedBlocks DESTINATION ${PROJECT_SOURCE_DIR}/build)
endif()

请注意,我使用的是较高的CMAKE版本,因此可能与您在2.8中需要做的有点不同。

在此之后,我需要构建项目,然后运行make install。构建的二进制文件没有正确设置RPATH,但是当我运行make install(基本上只是复制二进制文件并从我可以告诉的方法应用RPATH)时,它被正确设置。

您可以使用

检查二进制文件是否正确设置了RPATH
objdump -x path_to_binary_or_lib | grep RPATH

应输出类似

的内容
RPATH                $ORIGIN/lib/:$$ORIGIN/lib/:/usr/local/lib