答案是开发阶段用本地缓存(conan create),交付或 CI 用私有远程(conan upload)。混用会导致 conan.lock 出现同名包冲突,CMake 找不到 config 文件。

直接复用内部库的关键是让 Conan 认出它不是第三方包,而是你可控的、带版本和构建逻辑的本地或私有组件。 不靠 conan install 下载,而靠 conan create 或 conan export 注册进本地缓存,再在项目中像普通依赖一样写进 conanfile.txt 或 conanfile.py。
怎么把内部库变成 Conan 可识别的“包”
内部库不能只扔个头文件+静态库进去就完事。Conan 需要明确的“配方”(conanfile.py)来定义:它叫什么名、支持哪些编译器、要不要 shared、怎么编译、头文件放哪、库文件放哪。
- 在内部库根目录下必须有
conanfile.py,至少包含name、version、exports_sources和package()方法 - 不要用
conanfile.txt—— 它不支持自定义构建逻辑,没法处理你自己的 CMakeLists.txt 或 Makefile -
name建议用组织前缀,比如myorg/coolutils,避免和 ConanCenter 的fmt或boost冲突 - 如果内部库本身用 CMake 构建,
build()方法里调self.run("cmake ... && cmake --build .")是最稳的
如何在跨平台项目中稳定引用它
引用时最容易翻车的是路径硬编码或 profile 不一致。Conan 2.x 默认按 settings(如 os、arch、compiler)区分二进制,同一份源码在 Windows + MSVC 和 Linux + GCC 下生成的包完全隔离。
- 在主项目的
conanfile.txt中写myorg/coolutils/1.2.0,而不是../internal/coolutils—— 后者 Conan 直接报错 - 确保
conan install时用的-s和你conan create内部库时用的一致,否则找不到二进制,会 fallback 到源码构建(可能失败) - 推荐在 CI 或团队共享的 profile 文件里固定
compiler.version和compiler.libcxx,比如gcc-12-libstdc++11,避免本地环境差异导致conan.lock不一致 - 如果内部库需要不同平台不同编译选项(比如 ARM64 要加
-march=armv8.2-a),在conanfile.py的configure()里动态设置self.settings.compiler.cppstd
私有远程 vs 本地缓存:选哪个
答案是:开发阶段用本地缓存(conan create),交付或 CI 用私有远程(conan upload)。混用会导致 conan.lock 里出现两个来源的同名包,CMake 找不到 config 文件。
-
conan create . myorg/stable把内部库打成包并存进本地缓存(~/.conan2),所有本机项目都能直接requires = myorg/coolutils/1.2.0 - 上传到私有远程前,先
conan remote add myremote https://artifactory.myorg.com/conan,再conan upload "myorg/*" -r=myremote --force - 上传后,其他开发者只需
conan remote add+conan install,无需 clone 内部库源码 - 注意:私有远程必须启用 v2 协议(Conan 2.x 默认),旧版 Artifactory 需升级,否则
conan upload会静默失败
真正卡住人的从来不是命令敲不对,而是内部库的 conanfile.py 没声明清楚 self.cpp_info.libs,或者 package() 里漏拷了 .so 或 .dll;还有就是跨平台时忘了在 profile 里显式指定 os.subsystem(比如 WSL2 要设 linux 而不是 windows),结果 Conan 给你生成了一套 Windows 头文件配 Linux 库路径。


















