You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译C++程序后分享他人出现libCommon.so加载失败问题求助

问题

本地编译C++程序后运行正常,但将整个build目录打包发送给朋友后,朋友运行时出现以下错误:

error while loading shared libraries: libCommon.so: cannot open shared object file: No such file or directory

怀疑共享库未正确链接,主CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.16)

project(Vibranium_Core)

#set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 17)
set(FLATBUFFERS_MAX_PARSING_DEPTH 16)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(CMAKE_INSTALL_RPATH "$ORIGIN")
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)

if(APPLE)
    set(OPENSSL_INCLUDE_DIR "/opt/homebrew/opt/openssl@1.1/include")
endif()

if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
    execute_process(
            COMMAND git rev-list --count HEAD
            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
            OUTPUT_VARIABLE GIT_VERSION
            OUTPUT_STRIP_TRAILING_WHITESPACE
    )
    execute_process(
            COMMAND git rev-parse --abbrev-ref HEAD
            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
            OUTPUT_VARIABLE GIT_BRANCH
            OUTPUT_STRIP_TRAILING_WHITESPACE
    )
    execute_process(
            COMMAND git log -1 --format=%h
            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
            OUTPUT_VARIABLE GIT_COMMIT_HASH
            OUTPUT_STRIP_TRAILING_WHITESPACE
    )
    execute_process(
            COMMAND git --no-pager log -1 --format=%ai
            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
            OUTPUT_VARIABLE GIT_RELEASED_ON
            OUTPUT_STRIP_TRAILING_WHITESPACE
    )
else(EXISTS "${CMAKE_SOURCE_DIR}/.git")
    set(GIT_BRANCH "")
    set(GIT_COMMIT_HASH "")
endif(EXISTS "${CMAKE_SOURCE_DIR}/.git")

message(STATUS "VibraniumCore current branch: ${GIT_BRANCH}")
message(STATUS "VibraniumCore Version: ${GIT_VERSION}")
message(STATUS "VibraniumCore commit hash: ${GIT_COMMIT_HASH}")
message(STATUS "Released on: ${GIT_RELEASED_ON}")

message(STATUS "Generating version.h")

configure_file(
        ${CMAKE_SOURCE_DIR}/cmake/version.h.in
        ${CMAKE_SOURCE_DIR}/Source/Common/Version.h
)

add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
add_definitions(-DGIT_BRANCH="${GIT_BRANCH}")
add_definitions(-DGIT_VERSION="${GIT_VERSION}")
add_definitions(-DGIT_RELEASED_ON="${GIT_RELEASED_ON}")

if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
    message(STATUS "Target is 64 bits")
    if (WIN32)
        set(WINXXBITS Win64)
    endif(WIN32)
else("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
    message(STATUS "Target is 32 bits")
    if (WIN32)
        set(WINXXBITS Win32)
    endif(WIN32)
endif("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")

# set macro-directory
list(APPEND CMAKE_MODULE_PATH
        "${CMAKE_SOURCE_DIR}/cmake/macros")

find_package(CURL REQUIRED)
find_package(MySQL REQUIRED)
find_package(Flatbuffers REQUIRED
        PATHS /usr/local/flatbuffers)
        
find_package(Protobuf REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(gRPC CONFIG REQUIRED)

include_directories(${MYSQL_INCLUDE_DIR})
if(APPLE)
include_directories(/opt/homebrew/include)
include_directories(/usr/local/include)
endif()
# set default buildoptions and print them
include(cmake/options.cmake)

# Find revision ID and hash of the sourcetree
include(cmake/genrev.cmake)

# print out the results before continuing
include(cmake/showoptions.cmake)

# add dependencies
add_subdirectory(dep)

# add libraries and projects
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Source/Common)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Source/WorldServer)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Source/AuthServer)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Source/ClientEmulator)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Source/GameServerClientEmulator)
add_subdirectory(Tests)


set_target_properties(VibraniumCoreTests PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(gtest PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(gmock PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(gtest_main PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(gmock_main PROPERTIES EXCLUDE_FROM_ALL TRUE)

set_target_properties(
        Common WorldServer AuthServer ClientEmulator
        PROPERTIES
        ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/lib"
        LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/lib"
        RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
原因分析
  • RPATH配置仅对安装阶段生效:当前设置的CMAKE_INSTALL_RPATH和CMAKE_BUILD_WITH_INSTALL_RPATH是针对make install流程的,直接打包build目录下的编译产物时,这些RPATH规则不会被应用到可执行文件中,导致动态链接器找不到libCommon.so。
  • 库与可执行文件的路径关系:可执行文件位于bin/目录,libCommon.so在bin/lib/目录,系统默认的动态链接路径不包含这个相对位置,因此无法自动定位到库文件。
修复方案

方案一:修改CMake配置,让编译阶段生效RPATH

替换原CMakeLists.txt中的RPATH相关设置,让build目录下的可执行文件直接携带正确的动态链接路径:

# 替换原有的CMAKE_INSTALL_RPATH相关两行代码
set(CMAKE_RPATH "$ORIGIN/lib")
set(CMAKE_BUILD_WITH_RPATH TRUE)
# 确保编译时不跳过RPATH设置
set(CMAKE_SKIP_BUILD_RPATH FALSE)
# 安装时保留RPATH规则
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

$ORIGIN代表可执行文件所在的目录,$ORIGIN/lib会直接指向bin/lib/,动态链接器运行时会自动到该路径查找libCommon.so。修改后重新编译,打包build目录即可正常分发。

方案二:通过make install生成可分发包

保留现有CMake配置,通过安装流程生成带有正确RPATH的文件:

# 在build目录执行以下命令
cmake -DCMAKE_INSTALL_PREFIX=./install ..
make
make install
# 打包安装目录
tar -czf vibranium_core.tar.gz install/

将打包后的vibranium_core.tar.gz发给朋友,解压后直接运行install/bin/下的可执行文件即可。

方案三:朋友端临时解决(快速测试用)

让朋友在运行前设置环境变量,指定动态链接库的路径:

# 进入bin目录后执行
export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH
# 运行可执行文件,例如
./WorldServer

或者直接在运行时临时指定:

LD_LIBRARY_PATH=./lib ./WorldServer

内容的提问来源于stack exchange,提问作者Venelin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 06:35:20