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

如何使用Conan打包二进制项目?解决共享库加载失败问题

问题描述

包使用方无法加载该包内二进制文件依赖的共享库。

find_package(MyThirdParty REQUIRED) # MyThirdParty 是通过Conan安装的
find_program(binary_paty MyThirdParty REQUIRED)
execute_process(COMMAND ${binary_path} COMMAND_ERROR_IS_FATAL ANY)

上述execute_process命令会执行失败,原因是找不到MyThirdParty依赖的共享库,需要明确第三方二进制项目的正确打包方式。

最小复现示例

第三方项目CMakeLists.txt内容

file(WRITE Library.hh "void Func();")
file(WRITE Library.cc "void Func() {}")
add_library(Library SHARED Library.hh Library.cc)

file(WRITE Main.cc "#include \"Library.hh\"\nint main() { Func(); }")
add_executable(MyThirdParty Main.cc)
target_link_libraries(MyThirdParty PRIVATE Library)

install(TARGETS MyThirdParty Library EXPORT MyThirdPartyConfig)
install(EXPORT MyThirdPartyConfig
  NAMESPACE MyThirdParty::
  DESTINATION lib/cmake/MyThirdParty
)

Conan打包脚本conanfile.py实现

from conans import ConanFile, CMake, tools

class MyThirdPartyConan(ConanFile):
  name = "MyThirdParty"
  version = "1.0.0"
  settings = "os", "compiler", "build_type", "arch"

  def source(self):
    tools.download(
      filename = "CMakeLists.txt",
      url = "<上游CMakeLists.txt下载地址>")

  def build(self):
    cmake = CMake(self)
    cmake.configure()
    cmake.build()

  def package(self):
    cmake = CMake(self)
    cmake.install()

使用方CMake代码

find_package(MyThirdParty REQUIRED)
find_program(binary_paty MyThirdParty REQUIRED)
execute_process(COMMAND ${binary_path} COMMAND_ERROR_IS_FATAL ANY)

使用方conanfile.txt配置

[requires]
MyThirdParty/1.0.0@Ghasem/Test

[generators]
cmake_find_package

使用方通过Conan引入该包后执行CMake流程失败,原因是第三方二进制依赖的共享库无法找到:当CMake尝试执行MyThirdParty二进制文件时,会因找不到libLibrary.so文件报错。


运行环境
  • 操作系统:Fedora 35
  • 内核版本:Linux 5.18.9-100.fc35.x86_64
  • 编译器:GCC 11.3.1 20220421
  • CMake版本:3.22.2
  • Conan版本:1.47.0

解决方案

问题本质是Linux ELF格式可执行文件默认不会自动查找同安装目录下的依赖共享库,当前打包流程没有给可执行文件配置正确的依赖查找路径,运行时自然找不到同包内的libLibrary.so。

优先选择第一种修复方式,对使用方完全无侵入:

  • 给安装的可执行文件设置相对RPATH
    修改上游CMakeLists.txt,在所有目标定义前添加如下配置:
    set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
    set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
    
    这两行配置的作用是:可执行文件安装后,会自动从自身所在目录的上级lib目录查找依赖库——Conan安装包默认把可执行文件放在bin目录、共享库放在lib目录,$ORIGIN是ELF格式内置的变量,代表可执行文件自身的所在路径,配置后无论包被Conan缓存到哪个路径,可执行文件都能准确定位到同包内的依赖库,不需要使用方做任何额外配置。
    如果需要兼容macOS,把RPATH值换成@loader_path/../lib即可;Windows默认会查找可执行文件同目录下的DLL,不需要额外配置。

如果没法修改上游CMake代码,可以用第二种兼容方案:

  • 通过Conan生成运行时环境配置
    让使用方在conanfile.txt的generators里添加VirtualRunEnv,Conan会自动生成环境激活脚本,把所有依赖包的lib目录加入LD_LIBRARY_PATH,使用方执行CMake前先运行source conanrun.sh(Windows下是conanrun.bat)激活环境,再执行构建流程就能正常找到依赖库。这种方案需要使用方额外执行激活步骤,不如第一种方案干净。

额外注意事项:

  1. 打包时要确认所有依赖的共享库都被正确install到包的lib目录,不要出现漏装
  2. 不要硬编码绝对路径作为RPATH,否则包迁移路径后会直接失效
  3. 如果包内的可执行文件是提供给使用方的构建期工具,必须优先用RPATH方案,保证开箱即用,不要给使用方增加额外配置成本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:54:22