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

如何为Conan包创建多目标,实现单独链接子库?

问题

我正尝试创建一个Conan包,以便能在任意项目中安装并选择需要引入的子库。目前已完成以下操作:
我的包文件夹(命名为mypkg)包含一个CMakeLists.txt,用于编译所有子文件夹;每个子文件夹含.cpp/.hpp文件及如下模板的CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.12)

project(library1)


if(NOT TARGET ${PROJECT_NAME})
    add_library(${PROJECT_NAME} STATIC
    library1.cpp
    library1.hpp
    )
endif()

该代码会生成N个.a静态库。对应的conanfile.py代码如下:

class mypkg(ConanFile):
    ...
    settings = "os", "arch", "compiler", "build_type"

    options = {"shared": [True, False]}
    default_options = "shared=True"
    generators = "cmake","cmake_find_package"


    def build(self):
        cmake = CMake(self)
        cmake.definitions['CMAKE_EXPORT_COMPILE_COMMANDS'] = "ON"
        cmake.configure()
        cmake.build()

    def package(self):
        self.copy("*.h", dst="include", src="src", keep_path=True)
        self.copy("*.a", dst="lib", keep_path=False)


    def package_info(self):
        self.cpp_info.libs = tools.collect_libs(self)

执行conan create .创建包后,在项目中引入时只能整体链接,无法单独链接子库:
可正常使用:

find_package(mypkg REQUIRED)
target_link_libraries(${PROJECT_NAME} mypkg::mypkg)

无法使用:

find_package(mypkg REQUIRED)
target_link_libraries(${PROJECT_NAME} mypkg::library1)

请问该如何解决此问题?

解决方法

要实现单独链接子库,核心是在Conan的package_info中为每个子库声明独立的组件(Component),具体步骤如下:

1. 修改conanfile.py的package_info方法

替换原有的package_info逻辑,为每个子库创建对应组件,明确每个组件的链接信息:

def package_info(self):
    # 自动收集所有子库名称,无需手动枚举
    libs = tools.collect_libs(self)
    for lib in libs:
        # 为每个子库注册组件
        self.cpp_info.components[lib].libs = [lib]
        # 设置头文件搜索路径,根据你的实际目录结构调整
        self.cpp_info.components[lib].includedirs = ["include"]
        # 如果子库间有依赖,比如library2依赖library1,添加如下声明:
        # if lib == "library2":
        #     self.cpp_info.components[lib].requires = ["library1"]

    # 保留整体链接目标,兼容原有使用方式
    self.cpp_info.libs = libs

2. 确认打包内容完整性

确保你的package方法已经正确复制了所有子库的静态库和头文件:

  • 静态库:self.copy("*.a", dst="lib", keep_path=False) 已经将所有子库的.a文件复制到包的lib目录
  • 头文件:self.copy("*.h", dst="include", src="src", keep_path=True) 确保子库的头文件路径结构正确,方便项目引用

3. 验证使用效果

重新执行conan create .生成更新后的包,在项目中即可单独链接子库:

find_package(mypkg REQUIRED)
# 单独链接指定子库
target_link_libraries(${PROJECT_NAME} mypkg::library1)
# 同时链接多个子库
target_link_libraries(${PROJECT_NAME} mypkg::library1 mypkg::library2)
# 依然支持整体链接所有子库
target_link_libraries(${PROJECT_NAME} mypkg::mypkg)

关键说明

  • 组件机制会自动将Conan中声明的组件映射为CMake目标(如mypkg::library1),和你CMakeLists.txt中定义的子库目标对应
  • 子库间的依赖必须通过requires声明,Conan会自动处理链接顺序,避免手动调整库顺序的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:30:19