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

问题描述 投票:-1回答:1

因此,我正在开发一个打算在远程服务器上运行的项目。我在本地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的远程服务器上运行。我想知道这里到底发生了什么,而不是解决。谢谢!

c++ cmake linker shared-libraries dynamic-linking
1个回答
0
投票

如果我正确理解了您的问题,则希望将已编译的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路径转换为二进制而不是绝对路径。

© www.soinside.com 2019 - 2024. All rights reserved.