本地 Recipe 索引仓库¶
本地 Recipe 索引是 Conan 中引入的一种 实验性 仓库类型,旨在增强管理 C/C++ 软件包 recipe 的灵活性。这种仓库类型允许用户使用本地目录作为 Conan 远端仓库,其中目录结构镜像了 conan-center-index GitHub 仓库的结构。
这种设置尤其适用于
从私有的 conan-center-index 分支构建二进制文件。
分享您自己针对某些库或工具的 recipe,由于许可限制或专有性质,这些库或工具不适合 ConanCenter。查看如何在文档的专用章节中使用它以达到此目的 本地 Recipe 索引仓库。
从私有的 conan-center-index 分支构建二进制文件¶
正如我们在 Conan DevOps 指南的前一节 中已经介绍的那样,一些组织,特别是大型企业,更倾向于不使用从互联网下载的二进制文件。相反,他们使用 conan-center-index recipe 在内部构建自己的二进制文件。这些组织通常需要自定义这些 recipe 以满足不适用于更广泛社区的独特要求,使得此类贡献不适合上游仓库。
local-recipes-index 允许用户维护一个本地文件夹,其结构与 conan-center-index GitHub 仓库相同,并将其用作软件包 recipe 的来源。这种新型仓库仅包含 recipe,因此需要在使用软件包的每台机器上从源码构建软件包二进制文件。为了在团队之间共享二进制文件,我们仍然建议 使用像 Artifactory 这样的 Conan 远端服务器 用于生产目的。

local-recipes-index 仓库允许您轻松地从 conan-center-index 的分支构建二进制文件,然后将它们托管在像 Artifactory 这样的 Conan 远端仓库上。与 前一节 中解释的过程的主要区别在于,它可以立即测试多个本地更改,而无需每次修改 recipe 时都导出。
请注意,在这种情况下,出于以下几个原因,不建议将来自 ConanCenter 的二进制文件与本地构建的二进制文件混合使用
二进制兼容性:ConanCenter CI 和用户 CI 之间的设置可能存在细微差异。为所有二进制文件维护一致的设置可以缓解一些问题。
完全控制构建:自行构建所有二进制文件可确保您完全控制编译环境和依赖版本。
相反,建议从分支构建所有直接和传递依赖项。首先,删除上游 ConanCenter,因为它将不再使用,一切都将来自我们自己的分支
$ conan remote remove conancenter
然后我们将克隆我们的分支(在本例中,我们直接克隆上游用于演示目的,但您应该克隆您的分支)
$ git clone https://github.com/conan-io/conan-center-index
将其添加为我们的 mycenter 远端仓库
# Add the mycenter remote pointing to the local folder
$ conan remote add mycenter ./conan-center-index
就这样!现在您已设置为列出和使用来自您的 conan-center-index 本地文件夹的软件包
$ conan list "zlib/*" -r=mycenter
mycenter
zlib
zlib/1.2.11
zlib/1.2.12
zlib/1.2.13
zlib/1.3
zlib/1.3.1
我们也可以从此仓库安装软件包,例如我们可以这样做
$ conan install --requires=zlib/1.3
...
======== Computing dependency graph ========
zlib/1.3: Not found in local cache, looking in remotes...
zlib/1.3: Checking remote: mycenter
zlib/1.3: Downloaded recipe revision 5c0f3a1a222eebb6bff34980bcd3e024
Graph root
cli
Requirements
zlib/1.3#5c0f3a1a222eebb6bff34980bcd3e024 - Downloaded (mycenter)
======== Computing necessary packages ========
Requirements
zlib/1.3#5c0f3a1a222eebb6bff34980bcd3e024:72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a - Missing
ERROR: Missing binary: zlib/1.3:72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a
正如我们所见,Conan 设法从 mycenter
获取了 zlib/1.3
的 recipe,但随后失败了,因为没有二进制文件。这是预期的,仓库仅包含 recipe,但不包含二进制文件。我们可以使用 --build=missing
参数从源码构建二进制文件
$ conan install --requires=zlib/1.3 --build=missing
...
zlib/1.3: package(): Packaged 2 '.h' files: zconf.h, zlib.h
zlib/1.3: package(): Packaged 1 file: LICENSE
zlib/1.3: package(): Packaged 1 '.a' file: libz.a
zlib/1.3: Created package revision 0466b3475bcac5c2ce37bb5deda835c3
zlib/1.3: Package '72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a' created
zlib/1.3: Full package reference: zlib/1.3#5c0f3a1a222eebb6bff34980bcd3e024:72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a#0466b3475bcac5c2ce37bb5deda835c3
zlib/1.3: Package folder /home/conan/.conan2/p/b/zlib1ed9fe13537a2/p
WARN: deprecated: Usage of deprecated Conan 1.X features that will be removed in Conan 2.X:
WARN: deprecated: 'cpp_info.names' used in: zlib/1.3
======== Finalizing install (deploy, generators) ========
cli: Generating aggregated env files
cli: Generated aggregated env files: ['conanbuild.sh', 'conanrun.sh']
Install finished successfully
我们现在可以在本地缓存中看到二进制软件包
$ conan list "zlib:*"
Local Cache
zlib
zlib/1.3
revisions
5c0f3a1a222eebb6bff34980bcd3e024 (2024-04-10 11:50:34 UTC)
packages
72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a
info
settings
arch: x86_64
build_type: Release
compiler: gcc
compiler.version: 9
os: Linux
options
fPIC: True
shared: False
最后,将二进制软件包上传到我们的 Artifactory 仓库,以便我们的组织、用户和 CI 作业可以使用
$ conan remote add myartifactoryrepo <artifactory_url>
$ conan upload zlib* -r=myartifactoryrepo -c
这样,软件包的使用者不仅可以享受预编译的二进制文件,避免总是需要从源码重新构建所有依赖项,而且还将更强烈地保证依赖项构建和工作正常,所有依赖项和传递依赖项都能很好地协同工作等等。将二进制文件创建过程与二进制文件消费过程解耦是实现更快、更可靠的依赖项使用方式。
请记住,在生产环境中,conan upload 命令应由 CI 而不是开发人员执行,遵循 Conan 指南。这种方法确保软件包使用者可以享受预编译的二进制文件以及依赖项之间的一致性。
修改 local-recipes-index 仓库文件¶
这种方法的一个优点是,我们在每个 recipe 中所做的所有更改都会自动提供给 Conan 客户端。例如,对 recipes/zlib/config.yml 文件的更改会立即被 Conan 客户端识别。如果您编辑该文件并删除除最新版本之外的所有版本,然后我们 list recipe
$ conan list "zlib/*" -r=mycenter
mycenter
zlib
zlib/1.3.1
当某些 recipe 发生更改时,请注意当前的 Conan home 已经包含软件包的缓存副本,因此除非我们显式使用 --update
,否则它不会更新它,就像任何其他 Conan 远端仓库一样。
因此,如果我们在 recipes/zlib/all/conanfile.py
中的 zlib
recipe 中进行更改并重复
$ conan install --requires=zlib/1.3.1 -r=mycenter --update --build=missing
我们将立即在我们的 Conan home 中从新的修改后的 recipe 本地构建来自源码的新软件包二进制文件。
在生产中使用 local-recipes-index 仓库¶
使用此新功能时,应考虑以下几个重要事项
它专为 第三方软件包 而设计,其中一个仓库中的 recipe 正在创建具有位于其他位置的源码的软件包。为了打包您自己的代码,建议采用标准做法,即将 conanfile.py recipe 与源码一起添加,并使用标准的 conan create 流程。
local-recipes-index 仓库指向 文件系统中的本地文件夹。虽然用户可以选择将该文件夹与 git 仓库或其他版本控制机制同步,但 Conan 对此是不可知的,因为它只知道文件系统中指向仓库(当前)状态的文件夹。用户可以选择直接运行 git 命令来切换分支/提交/标签,Conan 将自动识别更改
这种方法在源码级别运行,不会生成软件包二进制文件。对于开发和生产环境的部署,使用像 Artifactory 这样的远端软件包服务器至关重要。重要的是要注意,此功能不能替代 Conan 的远端软件包服务器,后者在托管软件包以供常规使用方面起着至关重要的作用。
另请注意,服务器远端仓库可以保留更改历史记录,存储多个 recipe 修订版本。相比之下,local-recipes-index 远端仓库在任何给定时间只能表示单个快照。
ConanCenter 不使用
python-requires
,因为这是一种更适合第一方软件包的机制。目前,在local-recipes-index
仓库中使用python-requires
是可能的(并且是实验性的),但前提是python-requires
也位于同一索引仓库中。它不打算或计划支持将这些python-requires
放在其他仓库或用户 Conan 缓存中。
此外,此功能不支持将服务器 URL 直接放在 recipe 中;必须使用 conan remote add 显式添加远端仓库。将抽象软件包需求(例如 “zlib/1.3.1”)与其特定来源解耦对于正确解析依赖项和利用 Conan 的图功能至关重要,包括版本冲突检测和解决、版本范围解析、选择加入预发布版本、platform_requires、replace_requires 等。这种分离还有助于实现现代 DevOps 实践,例如软件包不可变性、完全可重定位性和软件包晋升。