应改用 imports 声明 + conan install 统一流程替代手动拷贝:imports 自动从 conan 缓存复制 include/lib 文件到 ./deps/,解决版本分散、跨平台路径敏感、重复编译问题;cmakelists.txt 中需删除全局 include/link 目录,改用 find_package 和 target_link_libraries(... private pkg::pkg)。

直接回答:不用重写构建逻辑,重点是把“手动拷贝路径”替换成 imports 声明 + 统一 conan install 流程,同时补全 package() 中的文件复制规则。
为什么不能继续用脚本硬拷贝
你原来在 cmake/external.cmake 里用 ExternalProject_Add 拉源码、编译、再 file(COPY ...) 到 deps/ 下——这套流程的问题不是“不能用”,而是:
• 版本散落在 CMake 脚本里,fast-lzma2 升级时得改三处(下载 URL、SHA256、install 目标路径);
• macOS 上编译 cppstub 不报错,但头文件路径大小写敏感,Linux 下就找不到 CppStub.h;
• 每次 CI 构建都要重新编译 lz4,哪怕只是改了自己一行业务代码。
imports 怎么替代手工 file(COPY)
Conan 的 imports 就是专为这种场景设计的:它不改包本身,只控制“从 Conan 缓存里把哪些文件复制到哪”。你不需要动 fast-lzma2 的配方,只需在项目根目录的 conanfile.txt 或 conanfile.py 里加几行:
[imports] include, *.h -> ./deps/include lib, *.a -> ./deps/lib bin, *.so* -> ./deps/lib
关键点:
-
include和lib是 Conan 包内部约定路径(不是你本地的src/),所有通过conan create打包的库都必须把头文件放进include/,静态库放进lib/,否则imports找不到 - 如果依赖是
cppstub这种 header-only 库,它没lib/目录,imports会静默跳过那行,不会报错 - 目标路径
./deps/include是相对于conanfile所在目录的,不是build/目录 —— 这和你原来 CMake 里写的${CMAKE_SOURCE_DIR}/deps行为一致
CMakeLists.txt 里要改什么
原来你可能这样写:
include_directories(${CMAKE_SOURCE_DIR}/deps/include)
link_directories(${CMAKE_SOURCE_DIR}/deps/lib)
target_link_libraries(myapp PRIVATE lzma2)
现在得改成 Conan 推荐的方式:
- 删掉
include_directories和link_directories—— 它们是全局作用域,容易污染其他 target - 用
find_package替代硬编码库名:find_package(fast-lzma2 REQUIRED CONFIG)(前提是conan install用了CMakeDeps生成器) -
target_include_directories改成基于目标的:target_include_directories(myapp PRIVATE ${fast-lzma2_INCLUDE_DIRS})或更推荐target_link_libraries(myapp PRIVATE fast-lzma2::fast-lzma2)
注意:fast-lzma2::fast-lzma2 这个别名来自它的 conanfile.py 里 cpp_info.set_property("cmake_target_name", "fast-lzma2::fast-lzma2"),不是默认就有 —— 如果你迁入的是社区包(比如 lz4/1.9.4),得确认它是否导出了 CMake target。
最容易被忽略的兼容点
迁移后第一次 conan install 失败,八成卡在这三处:
-
conan install必须在conanfile.txt所在目录执行,不是build/目录 —— 很多人习惯在build/里跑命令,结果提示No conanfile.py or conanfile.txt found -
fast-lzma2的 Conan 配方默认生成静态库,但你的旧构建脚本链接的是liblzma2.so;得在conan install里加-o fast-lzma2:shared=True,或者改 CMakeLists.txt 适配静态链接 -
cppstub是 header-only,但旧代码里写了target_link_libraries(myapp PRIVATE cppstub)—— Conan 不会生成 .a 文件,链接时报undefined reference;得删掉这行,只保留target_include_directories











