linux - scp 后 C++ 可执行文件无法链接到共享库

标签 linux cmake centos shared-libraries

所以我正在开发一个旨在在远程服务器上运行的项目。我在本地电脑上开发程序,编译它,然后上传到远程服务器。本地电脑和远程服务器都运行在CentOS 7.7上。

该程序使用 CLion IDE 开发,并使用 CMake 配置。该程序依赖于一些共享库,根据我在 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 中配置的目录中查找,其中不包含部署路径。

注意:通常您不会部署整个构建目录,而只会部署已编译的工件和依赖项。对于这个答案,我假设您将二进制文件及其依赖项部署到相同目录。

您有两个选择:

  • 要求程序的用户自行或通过包装脚本设置LD_LIBRARY_PATH。该变量也将指示动态链接器在指定的目录中查找。即使您不喜欢此解决方案,它也是迄今为止最常见的方法。
  • -Wl,-rpath='$ORIGIN' 添加到链接器选项中。这会将 DT_RUNPATH 属性添加到可执行文件的动态部分。当您使用 CMake 时,您还可以使用 BUILD_RPATH 和/或 INSTALL_RPATH 目标属性进行设置。 ld.so 联机帮助页对此属性的描述如下:

    If a shared object dependency does not contain a slash, then it is searched for in the following order:

    • ...
    • Using the directories specified in the DT_RUNPATH dynamic section attribute of the binary if present.

    $ORIGIN 部分扩展到包含程序或共享的目录 对象。

如果您确实坚持发布构建目录(例如在开发期间),您可以查看 CMake BUILD_RPATH_USE_ORIGIN属性(及其通常的全局对应项 CMAKE_BUILD_RPATH_USE_ORIGIN),这会将相对路径嵌入到二进制文件中,而不是绝对路径。

关于linux - scp 后 C++ 可执行文件无法链接到共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58969832/

相关文章:

linux - 为什么.bss段没有可执行属性?

linux - unix中 "../"的含义是什么?

c++ - 在 Ubuntu 上构建库,在 Arch 上的项目中使用它 - 不构建

linux - 如何通过 linux shell 检查 url 是否正常工作

makefile - 是否可以在CMake中更改生成的Makefile的名称?

python - 将 conda HDF4 链接到 conda GDAL(Anaconda Python)

centos - 由于 PyYAML,DevStack 安装失败

c++ - Cmake target_precompile_headers 导致重新定义错误

windows - Windows下使用通过MSYS2安装的cmake 3.5.2, "MinGW Makefiles"生成器丢失

ansible - 使用 Ansible 时如何将选项传递给 dnf