因此,我正在开发一个打算在远程服务器上运行的项目。我在本地PC上开发程序,将其编译,然后将其上传到远程服务器。本地计算机和远程服务器都在CentOS 7.7上运行。
该程序是使用配置了CMake的CLion IDE开发的。该程序依赖于一些共享库,这些共享库应该根据我在CMake中编写的内容链接到可执行文件。在本地PC上,我可以完美地编译和运行该程序。但是,将项目的整个目录压缩到远程服务器后,可执行文件将无法运行。根据“ ldd”的说法,它找不到任何“ .so”文件。
这是我的CMakeList.txt,每个路径都是相对路径,而不是绝对路径。
cmake_minimum_required(VERSION 3.15)
project(YS_Test)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_PATH_ src)
file(GLOB SOURCE_FILES_ ${SOURCE_PATH_}/*.*)
set(PROJECT_LIBS_ libTapQuoteAPI.so libTapTradeAPI.so libTapDataCollectAPI.so)
include_directories(api/include)
link_directories(api/lib/linux)
add_executable(YS_Test ${SOURCE_FILES_})
target_link_libraries(YS_Test ${PROJECT_LIBS_})
请不要告诉我设置LD_LIBRARY_PATH来解决我的问题。该程序可以在没有LD_LIBRARY_PATH的本地计算机上正常运行,因此我希望它可以在没有LD_LIBRARY_PATH的远程服务器上运行。我想知道这里到底发生了什么,而不是解决。谢谢!
如果我正确理解了您的问题,则希望将已编译的YS_Test
程序与某些依赖项一起提供,并使其在远程服务器上运行。默认情况下,可执行文件将仅查找在/etc/ld.so
中配置的目录,其中不包括部署路径。
注意:通常,您不部署整个构建目录,而仅部署已编译的工件和依赖项。对于此答案,我假设您将二进制文件及其依赖项部署到same目录。
您有两个选择:
LD_LIBRARY_PATH
。此变量将指示动态链接器也查找指定的目录。即使您不喜欢此解决方案,它也是迄今为止最常用的方法。将-Wl,-rpath='$ORIGIN'
添加到链接器选项。当您使用CMake时,也可以使用进行设置。这将在可执行文件的动态部分添加DT_RUNPATH
属性。ld.so联机帮助页描述了此属性,如下所示:
如果共享库依赖项不包含斜杠,则为按以下顺序搜索:
- ...
- 使用在DT_RUNPATH动态部分中指定的目录二进制文件的属性(如果存在)。
$ORIGIN
部分扩展到包含程序或共享目录对象。
如果您really坚持要交付构建目录(例如在开发过程中),则可以查看CMake BUILD_RPATH_USE_ORIGIN
属性(及其通常的全局对应的CMAKE_BUILD_RPATH_USE_ORIGIN),这将嵌入relative路径转换为二进制而不是绝对路径。