如何无需复制源码使用Conan构建C/C++项目?
问题分析与解决方案
1. 这是否属于不良实践?
不算不良实践,但Conan的核心设计是通过缓存隔离构建环境,保证可复现性,默认会将构建所需文件复制到缓存。你这种仅需打包构建产物、不想复制源码的场景是合理的,有对应的处理方案。
2. 如何在build()中访问原文件夹?
在Conan 1.x中,ConanFile没有直接提供原文件夹路径的属性,但可以通过以下两种方式实现:
方式一:环境变量传递
执行conan create时,将原文件夹路径传入环境变量:
cd /path/of/conanfile/and/sources ORIGINAL_SRC_DIR=$(pwd) conan create . 0.0.1/whatever/hotfix
在build()方法中读取该变量:
def build(self): original_dir = os.getenv("ORIGINAL_SRC_DIR") if not original_dir: raise ValueError("ORIGINAL_SRC_DIR environment variable not set") self.run(f'cmake {original_dir} --preset="my-preset"') # 后续执行构建逻辑
方式二:拆分构建与打包步骤
如果只是需要构建并打包产物,可以拆分流程绕开缓存复制:
- 在原目录执行依赖安装与构建:
cd /path/of/conanfile/and/sources conan install . 0.0.1/whatever/hotfix --install-folder=build cd build cmake .. --preset="my-preset" cmake --build .
- 直接打包构建产物:
conan package . 0.0.1/whatever/hotfix --package-folder=package --source-folder=.. --build-folder=build
3. 1KB文件复制耗时极久的原因与解决办法
常见原因
- 目录扫描开销:Conan处理
exports时,会扫描整个原目录计算配方哈希,即使仅指定单个文件,若原目录存在大量文件/子目录,扫描过程会变慢。 - 存储介质限制:原文件夹或Conan缓存位于网络文件系统(NFS)、慢机械硬盘时,IO开销会被放大。
- 旧版本性能瓶颈:早期Conan 1.x版本在
exports处理上存在性能问题。
解决方案
方案一:手动实现export()方法
放弃exports属性,手动复制指定文件,避免全目录扫描:
def export(self): # 获取原文件夹路径,手动复制CMakeLists.txt到缓存 original_file = os.path.join(os.path.dirname(inspect.getfile(self.__class__)), "CMakeLists.txt") shutil.copy(original_file, self.export_folder)
方案二:迁移缓存到高速存储
修改~/.conan/conan.conf,将Conan缓存迁移到本地SSD:
[storage] path = /path/to/ssd/conan/cache
方案三:升级Conan版本
升级到Conan 1.x的最新稳定版,官方后续版本优化了exports的处理性能。
4. 本地快速构建的替代方案
如果不需要上传包到远程仓库,可使用conan create --no-export参数(部分版本支持),或直接用conan build+conan package的组合,完全绕开缓存的文件复制步骤。
内容的提问来源于stack exchange,提问作者Mert Mertce
相关产品推荐
相关产品推荐

