默认版本控制方法

当对软件包的源代码进行更改并创建此类软件包时,一个好的做法是增加软件包的版本,以表示这些更改的范围和影响。“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 二进制模型 参考中进行了描述。

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

默认的 Conan 行为可以提供一些关于在对软件包源代码进行不同更改时建议的版本更改的提示

  • 不修改版本通常意味着我们希望 Conan 自动的配方修订版本来处理这种情况。一个常见的用例是当 C/C++ 源代码根本没有修改,而只更改了 conanfile.py 配方时。由于源代码相同,我们可能希望保持相同的版本号,而只拥有该版本的新修订版本。

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

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

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

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

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

注意

最佳实践

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

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