原文Conan Documentation — Release 2.29.0第一部分使用 Conan 仓库3.3.1 管理远程仓库remotesConan 默认从ConanCenter获取包。你可以添加其他远程仓库。# 查看已配置的远程仓库$ conan remote list conancenter: https://center2.conan.io[Verify SSL: True]# 添加远程仓库$ conan remoteaddmyremote https://mycompany.jfrog.io/api/conan/myrepo# 添加本地目录作为远程仓库$ conan remoteaddmylocalrepo ./repo --allowed-packageshello/*# 删除远程仓库$ conan remote remove myremote3.3.2 上传包# 上传包仅最新 recipe revision 所有二进制$ conan upload hello/1.0-c-rmyremote# 上传所有 revisions$ conan upload hello/1.0#* -c -rmyremote3.3.3 搜索包# 从远程仓库搜索$ conan list*-rconancenter# 搜索特定包$ conan listzlib/*-rconancenter# 搜索本地缓存$ conan list hello3.3.4 从 ConanCenter 获取包从 Conan 2.9.2 开始默认远程仓库已更改为https://center2.conan.io。如果遇到旧的默认远程配置更新$ conan remote update conancenter--urlhttps://center2.conan.io贡献到 ConanCenter 请访问https://github.com/conan-io/conan-center-index3.3.5 本地配方索引仓库对于不适合 ConanCenter 的包可以创建本地配方索引仓库$mkdirrepocdrepo $ conan new local_recipes_index-dnamehello-dversion0.1\-durlhttps://github.com/conan-io/libhello/archive/refs/tags/0.0.1.zip\-dsha2561dfb66cfd1e2fb7640c88cc4798fe25853a51b628ed9372ffc0ca285fe5be16b目录结构repo/ recipes/ hello/ all/ conandata.yml conanfile.py test_package/ config.yml添加为本地远程$ conan remoteaddmylocalrepo ./repo --allowed-packageshello/*从本地索引安装$ conan list*-rmylocalrepo $ conaninstall--requireshello/0.1-rmylocalrepo--buildmissing注意本地配方索引仓库不存储二进制包每个消费者需要自行--buildmissing。第二部分本地开发包3.4.1 包开发流程每次改代码都运行conan create很慢。Conan 提供了本地开发流程让你在本地目录中测试 recipe 的各个阶段。第一步conan source测试source()方法从远程获取源代码到本地src/目录$ conansource.conanfile.py(hello/1.0): Calling source()in.../src Downloading main.zip conanfile.py(hello/1.0): Unzipping3.7KB Unzipping100%第二步conan install安装依赖、生成构建配置$ conaninstall.-------- Finalizinginstall(deploy, generators)-------- conanfile.py(hello/1.0): GeneratorCMakeDepscallinggenerate()conanfile.py(hello/1.0): Generating aggregatedenvfiles会在build/目录生成 toolchain 和环境文件build/ Release/ generators/ conan_toolchain.cmake conanbuild.sh conanrun.sh ...第三步conan build构建包$ conan build.... -- Conan toolchain: C Standard11with extensions ON -- Conan toolchain: Setting BUILD_SHARED_LIBSOFF -- Configuringdone-- Generatingdone[100%]Built target hello也可以直接用 CMake 构建CMake 3.23$cdsrc $ cmake--presetconan-release $ cmake--build--presetconan-release[100%]Built target hello第四步conan export-pkg将本地构建的产物打包到 cache 中同时运行 test_package$ conan export-pkg.conanfile.py(hello/1.0): Packaged1.hfile: hello.h conanfile.py(hello/1.0): Packaged1.afile: libhello.a conanfile.py(hello/1.0): Packageb1d267f77ddd5d10d06d2ecf5a6bc433fbb7eeedcreated... -------- Testing the package: Running test()-------- hello/1.0(test package): RUN: ./example hello/1.0: Hello World Release!3.4.2 可编辑模式下的包Editable ModeEditable mode 让其他包直接引用你本地工作目录中的包而无需先conan create。场景你在本地开发say/1.0库同时hello包依赖它。你想修改say后立即在hello中看到效果。第一步启用 editable mode$cdsay $ conan editableadd.--namesay--version1.0输出Reference say/1.0 added to editable packages第二步构建 say 包本地$cdsay $ conaninstall.-sbuild_typeRelease $ cmake--presetconan-release $ cmake--build--presetconan-release[100%]Built target say第三步hello 消费包引用 editable say$cd../hello $ conaninstall.-sbuild_typeRelease# Linux/macOS$ cmake--presetconan-release --log-levelVERBOSE# Windows$ cmake--presetconan-default --log-levelVERBOSE... -- Conan: Target declaredsay::say-- Conan: Library say foundlocal_folder/say/build/Release/libsay.a... $ cmake--build--presetconan-release[100%]Built target hello注意输出中say::say从本地的say/build/Release/libsay.a链接而不是 Conan 缓存。第四步修改 say 代码立即生效修改say/src/say.cpp后只需重新构建say不需要任何 Conan 操作$cd../say $ cmake--build--presetconan-release[100%]Built target say# hello 下次构建时自动使用新的 libsay.a$cd../hello $ cmake--build--presetconan-release第五步退出 editable mode$cd../say $ conan editable remove--refssay/1.03.4.3 理解 Conan 包布局Package Layout为了支持 cached 和 editable 两种模式共存需要在layout()方法中正确配置。完整的 layout() 示例importosfromconanimportConanFilefromconan.tools.cmakeimportCMakeclassSayConan(ConanFile):namesayversion1.0exports_sourcesCMakeLists.txt,src/*,include/*deflayout(self):# 1. 定义文件夹结构self.folders.source.self.folders.buildos.path.join(build,str(self.settings.build_type))self.folders.generatorsos.path.join(self.folders.build,generators)# 2. cpp.package — 告诉消费者在缓存中找什么self.cpp.package.libs[say]self.cpp.package.includedirs[include]self.cpp.package.libdirs[lib]# 3. cpp.source — 告诉消费者在 editable 模式下找头文件self.cpp.source.includedirs[include]# 4. cpp.build — 告诉消费者在 editable 模式下找库文件self.cpp.build.libdirs[.]defbuild(self):cmakeCMake(self)cmake.configure()cmake.build()缓存模式查找路径$ cmake--presetconan-release --log-levelVERBOSE... -- Conan: Library say foundCACHE/p/say8938ceae216fc/p/lib/libsay.aEditable 模式查找路径$ cmake--presetconan-release --log-levelVERBOSE... -- Conan: Library say foundLOCAL/say/build/Release/libsay.a3.4.4 Workspaces工作区⚠️ 警告Workspace 是实验性功能需要设置环境变量CONAN_WORKSPACE_ENABLEwill_break_next才能启用。生产环境不可用。用于管理多个 editable 模式下包之间的依赖关系。# 创建工作区模板$ conan new workspace目录结构. ├── CMakeLists.txt ├── app1/ ├── liba/ ├── libb/ ├── conanws.py └── conanws.yml创建自定义工作区$mkdirmyprojectcdmyproject $ conan workspace init.$ conan new cmake_lib-dnamehello-dversion1.0-ohello $ conan new cmake_exe-dnameapp-dversion1.0-drequireshello/1.0-oapp# 将包添加到工作区$ conan workspaceaddhello $ conan workspaceaddapp# 构建所有包$ conan workspace build $ app/build/Release/app hello/1.0: Hello World Release!app/1.0: Hello World Release!第三部分版本管理3.5.1 版本最基本的版本管理——手动修改conanfile.pyclasspkgRecipe(ConanFile):namepkgversion1.0$ conan create.$ conan listpkg/*Local Cache pkg pkg/1.0创建多个版本$ conan create.--version1.0$ conan create.--version1.1$ conan create.--version1.2$ conan listpkg/*Local Cache pkg pkg/1.0 pkg/1.1 pkg/1.2自动版本设置——从文件读取fromconan.tools.filesimportloadclasspkgRecipe(ConanFile):namepkgdefset_version(self):self.versionload(self,version.txt)自动版本设置——从 Git Tag 获取fromconan.tools.scmimportGitclasspkgRecipe(ConanFile):namepkgdefset_version(self):gitGit(self)taggit.run(describe --tags)self.versiontag$gittag1.5$ conan create.... pkg/1.53.5.2 版本范围classappRecipe(ConanFile):nameapprequirespkg/[1.0 2.0]行为演示$ conan create pkg--version1.0$ conaninstallapp# → 使用 pkg/1.0$ conan create pkg--version1.1$ conaninstallapp# → 自动使用 pkg/1.1不需改 app$ conan create pkg--version2.0$ conaninstallapp# → 仍然使用 pkg/1.22.0 不在范围内版本范围表达式对照表表达式含义匹配示例[1.0 2.0]明确范围1.0, 1.5, 1.9[~1]近似 1.x1.3, 1.8.1[~2.5]近似 2.5.x2.5.0, 2.5.3[^1.2]兼容 1.x1.2.1, 1.3, 1.51[^0.1.2]兼容 0.1.x0.1.2.1, 0.1.3[1.2.3.*]字符串前缀匹配1.2.3.5, 1.2.3.abcConan 版本排序规则数字按数值比较字母按字典序预发布版本小于正式版本。3.5.3 Revisions修订版本每次构建包时即使版本号不改变Conan 也会自动跟踪变更# 第一次创建$ conan new cmake_lib-dnamehello-dversion1.0$ conan create.hello/1.0: Hello World Release!$ conan listhello/1.0#*revisions 2475ece651f666f42c155623228c75d2# 修改 src/hello.cpp 中 Hello → Bye$ conan create.hello/1.0: Bye World Release!$ conan listhello/1.0#*revisions 2475ece651f666f42c155623228c75d2 2b547b7f20f5541c16d0b5cbcf207502# ← 新 revision版本号还是 1.0Recipe revision conanfile.py 所有导出文件的哈希Package revision 二进制内容的哈希锁定特定 revisiondefrequirements(self):self.requires(hello/1.0#2475ece651f666f42c155623228c75d2)上传 revisions# 仅最新 revision$ conan upload hello/1.0-c-rmyremote# 所有 revisions$ conan upload hello/1.0#* -c -rmyremoteWindows 注意Git 默认使用 CRLF 换行符这会导致 Windows 和 Linux 计算出不同的 revision。3.5.4 Lockfiles锁定文件Lockfile 锁定依赖图的快照确保后续构建可重现。创建 lockfile$ conan lock create.生成的conan.lock{version:0.5,requires:[matrix/1.0#905c3f0babc520684c84127378fefdd0%1675278126.0552447],build_requires:[],python_requires:[]}使用 lockfile创建新版本不会影响已锁定的项目$ conan create matrix--version1.1$cdengine $ conaninstall.Requirements matrix/1.0#905c3f0babc520684c84127378fefdd0 - Cache # 仍然用 1.0没有显式指定--lockfile时Conan 自动查找当前目录的conan.lock。部分 lockfile$ conaninstall.-sarchx86 --lockfile-partial演进 lockfile# 添加新版本到 lockfile$ conan lockadd--requiresmatrix/1.1# 更新并清理 lockfile$ conaninstall.-sarchx86 --lockfile-outconan.lock --lockfile-clean多配置 lockfile 合并$ conan lock create.--lockfile-out64.lock --lockfile-clean $ conan lock create.-sarchx86 --lockfile-out32.lock --lockfile-clean $ conan lock merge--lockfile32.lock--lockfile64.lock --lockfile-outconan.lock3.5.5 依赖冲突当依赖图中不同包要求不同版本的同一包时会产生冲突。创建冲突场景game/1.0 ├── engine/1.0 → matrix/1.0 └── intro/1.0 → matrix/1.1$ conan create matrix--version1.0$ conan create matrix--version1.1$ conan create engine--version1.0$ conan create intro--version1.0$ conaninstallgame输出ERROR: Version conflict: matrix/1.0 required by engine/1.0, while matrix/1.1 required by intro/1.0解决方案使用版本范围让上游作者统一到一个版本区间使用 lockfile 固定所有依赖到一致的状态升级或降级其中一个依赖以消除冲突完整命令速查表场景命令创建包conan new cmake_lib -d namexxx -d version1.0构建包conan create .查看缓存conan list xxx配置不同构建-s build_typeDebug,-o sharedTrue上传包conan upload hello/1.0 -c -rmyremote添加远程conan remote add xxx url本地开发sourceconan source .本地开发installconan install .本地开发buildconan build .本地开发打包conan export-pkg .Editable 模式conan editable add . --namexxx --version1.0退出 Editableconan editable remove --refsxxx/1.0创建 lockfileconan lock create .锁定 revisionself.requires(pkg/1.0#hash)版本范围self.requires(pkg/[1.0 2.0])自动版本号conan create . --version1.0或set_version()
Conan 进阶:仓库管理、本地开发与版本控制
原文Conan Documentation — Release 2.29.0第一部分使用 Conan 仓库3.3.1 管理远程仓库remotesConan 默认从ConanCenter获取包。你可以添加其他远程仓库。# 查看已配置的远程仓库$ conan remote list conancenter: https://center2.conan.io[Verify SSL: True]# 添加远程仓库$ conan remoteaddmyremote https://mycompany.jfrog.io/api/conan/myrepo# 添加本地目录作为远程仓库$ conan remoteaddmylocalrepo ./repo --allowed-packageshello/*# 删除远程仓库$ conan remote remove myremote3.3.2 上传包# 上传包仅最新 recipe revision 所有二进制$ conan upload hello/1.0-c-rmyremote# 上传所有 revisions$ conan upload hello/1.0#* -c -rmyremote3.3.3 搜索包# 从远程仓库搜索$ conan list*-rconancenter# 搜索特定包$ conan listzlib/*-rconancenter# 搜索本地缓存$ conan list hello3.3.4 从 ConanCenter 获取包从 Conan 2.9.2 开始默认远程仓库已更改为https://center2.conan.io。如果遇到旧的默认远程配置更新$ conan remote update conancenter--urlhttps://center2.conan.io贡献到 ConanCenter 请访问https://github.com/conan-io/conan-center-index3.3.5 本地配方索引仓库对于不适合 ConanCenter 的包可以创建本地配方索引仓库$mkdirrepocdrepo $ conan new local_recipes_index-dnamehello-dversion0.1\-durlhttps://github.com/conan-io/libhello/archive/refs/tags/0.0.1.zip\-dsha2561dfb66cfd1e2fb7640c88cc4798fe25853a51b628ed9372ffc0ca285fe5be16b目录结构repo/ recipes/ hello/ all/ conandata.yml conanfile.py test_package/ config.yml添加为本地远程$ conan remoteaddmylocalrepo ./repo --allowed-packageshello/*从本地索引安装$ conan list*-rmylocalrepo $ conaninstall--requireshello/0.1-rmylocalrepo--buildmissing注意本地配方索引仓库不存储二进制包每个消费者需要自行--buildmissing。第二部分本地开发包3.4.1 包开发流程每次改代码都运行conan create很慢。Conan 提供了本地开发流程让你在本地目录中测试 recipe 的各个阶段。第一步conan source测试source()方法从远程获取源代码到本地src/目录$ conansource.conanfile.py(hello/1.0): Calling source()in.../src Downloading main.zip conanfile.py(hello/1.0): Unzipping3.7KB Unzipping100%第二步conan install安装依赖、生成构建配置$ conaninstall.-------- Finalizinginstall(deploy, generators)-------- conanfile.py(hello/1.0): GeneratorCMakeDepscallinggenerate()conanfile.py(hello/1.0): Generating aggregatedenvfiles会在build/目录生成 toolchain 和环境文件build/ Release/ generators/ conan_toolchain.cmake conanbuild.sh conanrun.sh ...第三步conan build构建包$ conan build.... -- Conan toolchain: C Standard11with extensions ON -- Conan toolchain: Setting BUILD_SHARED_LIBSOFF -- Configuringdone-- Generatingdone[100%]Built target hello也可以直接用 CMake 构建CMake 3.23$cdsrc $ cmake--presetconan-release $ cmake--build--presetconan-release[100%]Built target hello第四步conan export-pkg将本地构建的产物打包到 cache 中同时运行 test_package$ conan export-pkg.conanfile.py(hello/1.0): Packaged1.hfile: hello.h conanfile.py(hello/1.0): Packaged1.afile: libhello.a conanfile.py(hello/1.0): Packageb1d267f77ddd5d10d06d2ecf5a6bc433fbb7eeedcreated... -------- Testing the package: Running test()-------- hello/1.0(test package): RUN: ./example hello/1.0: Hello World Release!3.4.2 可编辑模式下的包Editable ModeEditable mode 让其他包直接引用你本地工作目录中的包而无需先conan create。场景你在本地开发say/1.0库同时hello包依赖它。你想修改say后立即在hello中看到效果。第一步启用 editable mode$cdsay $ conan editableadd.--namesay--version1.0输出Reference say/1.0 added to editable packages第二步构建 say 包本地$cdsay $ conaninstall.-sbuild_typeRelease $ cmake--presetconan-release $ cmake--build--presetconan-release[100%]Built target say第三步hello 消费包引用 editable say$cd../hello $ conaninstall.-sbuild_typeRelease# Linux/macOS$ cmake--presetconan-release --log-levelVERBOSE# Windows$ cmake--presetconan-default --log-levelVERBOSE... -- Conan: Target declaredsay::say-- Conan: Library say foundlocal_folder/say/build/Release/libsay.a... $ cmake--build--presetconan-release[100%]Built target hello注意输出中say::say从本地的say/build/Release/libsay.a链接而不是 Conan 缓存。第四步修改 say 代码立即生效修改say/src/say.cpp后只需重新构建say不需要任何 Conan 操作$cd../say $ cmake--build--presetconan-release[100%]Built target say# hello 下次构建时自动使用新的 libsay.a$cd../hello $ cmake--build--presetconan-release第五步退出 editable mode$cd../say $ conan editable remove--refssay/1.03.4.3 理解 Conan 包布局Package Layout为了支持 cached 和 editable 两种模式共存需要在layout()方法中正确配置。完整的 layout() 示例importosfromconanimportConanFilefromconan.tools.cmakeimportCMakeclassSayConan(ConanFile):namesayversion1.0exports_sourcesCMakeLists.txt,src/*,include/*deflayout(self):# 1. 定义文件夹结构self.folders.source.self.folders.buildos.path.join(build,str(self.settings.build_type))self.folders.generatorsos.path.join(self.folders.build,generators)# 2. cpp.package — 告诉消费者在缓存中找什么self.cpp.package.libs[say]self.cpp.package.includedirs[include]self.cpp.package.libdirs[lib]# 3. cpp.source — 告诉消费者在 editable 模式下找头文件self.cpp.source.includedirs[include]# 4. cpp.build — 告诉消费者在 editable 模式下找库文件self.cpp.build.libdirs[.]defbuild(self):cmakeCMake(self)cmake.configure()cmake.build()缓存模式查找路径$ cmake--presetconan-release --log-levelVERBOSE... -- Conan: Library say foundCACHE/p/say8938ceae216fc/p/lib/libsay.aEditable 模式查找路径$ cmake--presetconan-release --log-levelVERBOSE... -- Conan: Library say foundLOCAL/say/build/Release/libsay.a3.4.4 Workspaces工作区⚠️ 警告Workspace 是实验性功能需要设置环境变量CONAN_WORKSPACE_ENABLEwill_break_next才能启用。生产环境不可用。用于管理多个 editable 模式下包之间的依赖关系。# 创建工作区模板$ conan new workspace目录结构. ├── CMakeLists.txt ├── app1/ ├── liba/ ├── libb/ ├── conanws.py └── conanws.yml创建自定义工作区$mkdirmyprojectcdmyproject $ conan workspace init.$ conan new cmake_lib-dnamehello-dversion1.0-ohello $ conan new cmake_exe-dnameapp-dversion1.0-drequireshello/1.0-oapp# 将包添加到工作区$ conan workspaceaddhello $ conan workspaceaddapp# 构建所有包$ conan workspace build $ app/build/Release/app hello/1.0: Hello World Release!app/1.0: Hello World Release!第三部分版本管理3.5.1 版本最基本的版本管理——手动修改conanfile.pyclasspkgRecipe(ConanFile):namepkgversion1.0$ conan create.$ conan listpkg/*Local Cache pkg pkg/1.0创建多个版本$ conan create.--version1.0$ conan create.--version1.1$ conan create.--version1.2$ conan listpkg/*Local Cache pkg pkg/1.0 pkg/1.1 pkg/1.2自动版本设置——从文件读取fromconan.tools.filesimportloadclasspkgRecipe(ConanFile):namepkgdefset_version(self):self.versionload(self,version.txt)自动版本设置——从 Git Tag 获取fromconan.tools.scmimportGitclasspkgRecipe(ConanFile):namepkgdefset_version(self):gitGit(self)taggit.run(describe --tags)self.versiontag$gittag1.5$ conan create.... pkg/1.53.5.2 版本范围classappRecipe(ConanFile):nameapprequirespkg/[1.0 2.0]行为演示$ conan create pkg--version1.0$ conaninstallapp# → 使用 pkg/1.0$ conan create pkg--version1.1$ conaninstallapp# → 自动使用 pkg/1.1不需改 app$ conan create pkg--version2.0$ conaninstallapp# → 仍然使用 pkg/1.22.0 不在范围内版本范围表达式对照表表达式含义匹配示例[1.0 2.0]明确范围1.0, 1.5, 1.9[~1]近似 1.x1.3, 1.8.1[~2.5]近似 2.5.x2.5.0, 2.5.3[^1.2]兼容 1.x1.2.1, 1.3, 1.51[^0.1.2]兼容 0.1.x0.1.2.1, 0.1.3[1.2.3.*]字符串前缀匹配1.2.3.5, 1.2.3.abcConan 版本排序规则数字按数值比较字母按字典序预发布版本小于正式版本。3.5.3 Revisions修订版本每次构建包时即使版本号不改变Conan 也会自动跟踪变更# 第一次创建$ conan new cmake_lib-dnamehello-dversion1.0$ conan create.hello/1.0: Hello World Release!$ conan listhello/1.0#*revisions 2475ece651f666f42c155623228c75d2# 修改 src/hello.cpp 中 Hello → Bye$ conan create.hello/1.0: Bye World Release!$ conan listhello/1.0#*revisions 2475ece651f666f42c155623228c75d2 2b547b7f20f5541c16d0b5cbcf207502# ← 新 revision版本号还是 1.0Recipe revision conanfile.py 所有导出文件的哈希Package revision 二进制内容的哈希锁定特定 revisiondefrequirements(self):self.requires(hello/1.0#2475ece651f666f42c155623228c75d2)上传 revisions# 仅最新 revision$ conan upload hello/1.0-c-rmyremote# 所有 revisions$ conan upload hello/1.0#* -c -rmyremoteWindows 注意Git 默认使用 CRLF 换行符这会导致 Windows 和 Linux 计算出不同的 revision。3.5.4 Lockfiles锁定文件Lockfile 锁定依赖图的快照确保后续构建可重现。创建 lockfile$ conan lock create.生成的conan.lock{version:0.5,requires:[matrix/1.0#905c3f0babc520684c84127378fefdd0%1675278126.0552447],build_requires:[],python_requires:[]}使用 lockfile创建新版本不会影响已锁定的项目$ conan create matrix--version1.1$cdengine $ conaninstall.Requirements matrix/1.0#905c3f0babc520684c84127378fefdd0 - Cache # 仍然用 1.0没有显式指定--lockfile时Conan 自动查找当前目录的conan.lock。部分 lockfile$ conaninstall.-sarchx86 --lockfile-partial演进 lockfile# 添加新版本到 lockfile$ conan lockadd--requiresmatrix/1.1# 更新并清理 lockfile$ conaninstall.-sarchx86 --lockfile-outconan.lock --lockfile-clean多配置 lockfile 合并$ conan lock create.--lockfile-out64.lock --lockfile-clean $ conan lock create.-sarchx86 --lockfile-out32.lock --lockfile-clean $ conan lock merge--lockfile32.lock--lockfile64.lock --lockfile-outconan.lock3.5.5 依赖冲突当依赖图中不同包要求不同版本的同一包时会产生冲突。创建冲突场景game/1.0 ├── engine/1.0 → matrix/1.0 └── intro/1.0 → matrix/1.1$ conan create matrix--version1.0$ conan create matrix--version1.1$ conan create engine--version1.0$ conan create intro--version1.0$ conaninstallgame输出ERROR: Version conflict: matrix/1.0 required by engine/1.0, while matrix/1.1 required by intro/1.0解决方案使用版本范围让上游作者统一到一个版本区间使用 lockfile 固定所有依赖到一致的状态升级或降级其中一个依赖以消除冲突完整命令速查表场景命令创建包conan new cmake_lib -d namexxx -d version1.0构建包conan create .查看缓存conan list xxx配置不同构建-s build_typeDebug,-o sharedTrue上传包conan upload hello/1.0 -c -rmyremote添加远程conan remote add xxx url本地开发sourceconan source .本地开发installconan install .本地开发buildconan build .本地开发打包conan export-pkg .Editable 模式conan editable add . --namexxx --version1.0退出 Editableconan editable remove --refsxxx/1.0创建 lockfileconan lock create .锁定 revisionself.requires(pkg/1.0#hash)版本范围self.requires(pkg/[1.0 2.0])自动版本号conan create . --version1.0或set_version()