因此,我正在研究一个旨在在远程服务器上运行的项目。我在本地PC上开发程序,将其编译,然后将其上传到远程服务器。本地计算机和远程服务器都在CentOS 7.7上运行。
该程序是使用配置了CMake的CLion IDE开发的。该程序依赖于一些共享库,这些共享库应该根据我在CMake中编写的内容链接到可执行文件。在本地PC上,我可以完美地编译和运行该程序。但是,将项目的整个目录scp
到远程服务器后,可执行文件将无法运行。根据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
中配置的目录中查找,其中不包括部署路径。
注意:通常,您不会部署整个构建目录,而只会部署已编译的 Artifact 和依赖项。对于此答案,我将假定您将二进制文件及其依赖项部署到与目录相同的目录中。
您有两种选择:
LD_LIBRARY_PATH
或通过包装脚本设置。此变量将指示动态链接器也查找指定的目录。即使您不喜欢此解决方案,它也是迄今为止最常用的方法。 -Wl,-rpath='$ORIGIN'
添加到链接器选项。这会将DT_RUNPATH
属性添加到可执行文件的动态部分。在使用CMake时,还可以使用BUILD_RPATH
和/或INSTALL_RPATH
目标属性进行设置。ld.so联机帮助页对该属性的描述如下:
$ORIGIN
部分扩展到包含程序或共享目录目的。
如果真的坚持要交付构建目录(例如,在开发过程中),则可以查看CMake
BUILD_RPATH_USE_ORIGIN
属性(及其通常的全局对应的CMAKE_BUILD_RPATH_USE_ORIGIN),这会将相对路径嵌入到二进制文件中,而不是绝对路径中。