默认版本控制方法

当对包的源代码进行更改并创建该包时,一个好的实践是增加包的版本号,以反映这些更改的范围和影响。“semver”标准规范定义了一种 MAJOR.MINOR.PATCH 版本控制方法,其中每个数字的更改都具有特定的含义。

Conan 基于“semver”规范实现了版本控制,但增加了一些 C 和 C++ 生态系统所要求的扩展功能

  • Conan 版本可以包含任意数量的数字,例如 MAJOR.MINOR.PATH.MICRO.SUBMICRO...

  • Conan 版本也可以包含字母而不仅仅是数字,它们也按字母顺序排序,例如 1.a.21.b.1 旧。

  • 版本范围同样可以定义为任意数量的数字,例如 dependency/[>=1.0.0.0 <1.0.0.10]

阅读教程中的版本控制简介

但与其他语言相比,C 和 C++ 构建模型的一个非常不同的方面是依赖项如何影响使用它们的消费者的二进制文件。这在Conan 二进制模型参考中有所描述。

基本上,当某些包更改其版本时,这会对该包的“消费者”产生不同的影响,要求这些“消费者”从源代码重建,或者不集成新的依赖项更改。这还取决于包类型,因为链接共享库或静态库时的逻辑会发生变化。Conan 二进制模型通过 dependency traitspackage_typepackage_id 模式,能够表示此逻辑并有效计算哪些需要从源代码重建。

默认的 Conan 行为可以为对包源代码进行不同更改时推荐的版本更改提供一些提示

  • 不修改版本通常意味着我们希望由 Conan 自动的recipe 修订版来处理。一个常见的用例是,C/C++ 源代码根本没有修改,只更改了 conanfile.py recipe。由于源代码相同,我们可能希望保留相同的版本号,只生成该版本的一个新修订版。

  • 补丁:增加包的补丁版本意味着只进行了内部更改,实际上是指对非包公共头文件的文件进行的更改。这种“补丁”版本可以避免重新构建此包的消费者,例如,如果当前获得新“补丁”版本的包是静态库,则所有依赖于此包并实现静态库的其他包都不需要从源代码重新构建,因为依赖相同的公共接口头文件可以保证相同的二进制文件。

  • 次版本:如果对包的公共头文件进行了更改,并且更改方式与 API 源兼容,那么建议增加包的次版本。这意味着依赖于此包的其他包将能够编译,但由于公共头文件中存在修改(可能包含 C++ 模板或其他可以在消费者包中内联的内容),因此这些消费者包需要从源代码重新构建以包含这些更改。

  • 主版本:如果对包的公共头文件进行了 API 不兼容的更改,建议增加主版本。由于最常见的推荐版本范围类似于 dependency/[>1.0 <2],其中排除了下一个主版本,这意味着发布这些新版本不会破坏现有消费者,因为这些消费者根本不会使用它们,因为它们的版本范围会排除它们。需要修改消费者 recipe 和源代码(以修复 API 不兼容的更改)才能使用新的主版本。

请注意,虽然这接近标准“semver”对版本和版本范围的定义,但 C/C++ 编译模型需要引入一个新的副作用,即“需要重新构建消费者”,这遵循了上面在 embednon_embed 情况下解释的逻辑。

这只是默认推荐的版本控制方法,但 Conan 允许更改这些默认设置,因为它实现了“semver”标准的扩展,允许任意数量的数字、字母等,并且还允许更改 package_id 模式,以定义依赖项的不同版本如何影响消费者的二进制文件。请参阅如何自定义依赖项的 package_id 模式

注意

最佳实践

  • 不建议使用其他包引用字段(如 userchannel)来表示源代码更改或 git 分支等其他信息,因为这会像“病毒”一样要求更改消费者的 requires。此外,它们在构建模型中没有实现任何关于哪些消费者需要重新构建的逻辑。

  • 推荐的方法是使用版本控制和多个服务器仓库来托管不同的包,这样它们就不会干扰其他构建。阅读持续集成教程了解更多详细信息。