版本范围¶
在上一节中,我们结束时有几个版本的 pkg 包。让我们删除它们并创建以下简单项目
from conan import ConanFile
class pkgRecipe(ConanFile):
name = "pkg"
from conan import ConanFile
class appRecipe(ConanFile):
name = "app"
requires = "pkg/1.0"
让我们创建 pkg/1.0 并安装 app,以查看它需要 pkg/1.0
$ conan remove "pkg*" -c
$ conan create pkg --version=1.0
... pkg/1.0 ...
$ conan install app
...
Requirements
pkg/1.0
然后,如果我们创建 pkg/1.1 的新版本,它将不会自动被 app 使用
$ conan create pkg --version=1.1
... pkg/1.0 ...
# Note how this still uses the previous 1.0 version
$ conan install app
...
Requirements
pkg/1.0
因此,我们可以修改 app conanfile 以显式使用新的 pkg/1.1 版本,但与其那样做,让我们使用以下版本范围表达式(由 [expression] 方括号引入)
from conan import ConanFile
class appRecipe(ConanFile):
name = "app"
requires = "pkg/[>=1.0 <2.0]"
当我们现在安装 app 的依赖项时,它将自动使用范围内的最新版本,即使我们创建一个新版本,也无需修改 app conanfile
# this will now use the newer 1.1
$ conan install app
...
Requirements
pkg/1.1
$ conan create pkg --version=1.2
... pkg/1.2 ...
# Now it will automatically use the newest 1.2
$ conan install app
...
Requirements
pkg/1.2
只要较新的版本位于定义的范围内,这仍然成立。如果创建 pkg/2.0 版本,app 将不会使用它
$ conan create pkg --version=2.0
... pkg/2.0 ...
# Conan will use the latest in the range
$ conan install app
...
Requirements
pkg/1.2
在使用版本范围时,缓存中的版本优先于远程版本,因此,如果您有一个本地的 pkg/1.2 包,它将被使用而不是远程版本,即使远程版本较新。要确保使用最新的可用版本,您可以使用 --update 参数在 install / create 命令中。请注意,--update 参数将查找命令中指定的所有远程存储库中是否有较新的版本,并且不会在找到第一个较新的版本时停止。
版本范围可以在多个地方定义
在
conanfile.py脚本的requires、tool_requires、test_requires、python_requires中在
conanfile.txt文件中的[requires]、[tool_requires]、[test_requires]部分在命令行参数中,如
--requires=和--tool_requires。在配置文件的
[tool_requires]部分
语义化版本控制¶
语义化版本控制规范或 semver,指定软件包应使用始终由点分隔的 3 位数字进行版本控制,例如 MAJOR.MINOR.PATCH,其中每个数字都有非常具体的含义。
Conan 将 semver 规范扩展到任意数量的数字,并允许在其中包含小写字母。这是因为在 1.X 期间,收集了大量的经验和用户反馈,并且很明显,在 C++ 中版本控制方案通常更复杂,并且用户要求更高的灵活性,如果需要,允许使用像 1.2.3.a.8 这样的版本。
Conan 的非数字标识符版本遵循与软件包名称相同的规则,它们只能包含小写字母。这是为了避免 1.2.3-Beta 与 1.2.3-beta 成为不同的版本,这可能存在问题,甚至存在安全风险。
在必要时对版本进行排序(例如,确定版本范围内的最新版本),是通过从左到右逐个比较版本中由点分隔的每个实体来完成的。数字将进行数值比较,因此 2 < 11,包含字母的条目将按字母顺序进行比较(即使它们也包含一些数字)。
与 semver 规范类似,Conan 可以管理 **预发布** 和 **构建** 的形式:VERSION-prerelease+build。Conan 也会根据相同的规则对预发布和构建进行排序,并且它们中的每一个都可以包含任意数量的项目,例如 1.2.3-pre.1.2.1+build.45.a。请注意,semver 标准不适用于构建的排序,但 Conan 确实如此,并使用与排序主版本和预发布版本相同的逻辑。
重要
请注意,预发布的排序有时会令人困惑。预发布发生的时间早于它所限定的发布。因此,1.1-alpha.1 比 1.1 旧,而不是更新。
范围表达式¶
范围表达式可以对下限和上限使用比较运算符,并用空格分隔。此外,允许单独使用下限和上限,尽管通常不建议在正常的版本控制方案下使用它们,特别是仅使用下限。 requires = "pkg/[>=1.0 <2.0]" 将包含版本 1.0、1.2.3 和 1.9,但不包括 0.3、2.0 或 2.1 版本。
波浪号 ~ 运算符可用于定义“近似”相等版本范围。 requires = "pkg/[~1]" 将包含版本 1.3 和 1.8.1,但不包括版本 0.8 或 2.0。同样,requires = "pkg/[~2.5]" 将包含 2.5.0 和 2.5.3,但不包括 2.1、2.7、2.8。
插入符号 ^ 运算符与波浪号非常相似,但允许在第一个非零数字之后的变化。 requires = "pkg/[^1.2]" 将包含 1.2.1、1.3 和 1.51,但不包括 1.0、2、2.0。 ^1.2.0 的作用相同,而 ^0.1.2 将包含 0.1.2.1 和 0.1.3,但不包括 0.1.1 和 0.2.0。
也可以使用 OR 运算符应用多个条件,例如 requires = "pkg/[>1 <2.0 || ^3.2]",但这种复杂的表达式在实践中不建议使用,仅应在非常极端的情况下使用。
可以使用字符串匹配来简化某些范围的末尾,否则需要更复杂的条件(此功能是实验性的)。定义 requires=pkg/[1.2.3.*] 将匹配任何以 1.2.3. 开头的版本,并丢弃其他版本。例如,它将匹配 1.2.3.5 和 1.2.3.abc,但会丢弃 1.2.3(因为它没有最后的点)。
最后,请注意,默认情况下不会解析预发布。包含它们在范围内的途径是使用 include_prerelease 选项(requires = "pkg/[>1 <2, include_prerelease]")或通过 core.version_ranges:resolve_prereleases=True 配置,您可以在此处了解更多信息。在此示例中,将包含 1.0-pre.1 和 1.5.1-pre1,但将排除 2.0-pre1。
注意
虽然可以在 requires 版本范围内硬编码 include_prerelease,但通常不建议这样做。预发布应该是选择加入的,并由用户控制,用户决定是否要使用预发布。此外,请注意,include_prerelease 不接受任何参数,因此无法使用 include_prerelease=False 停用预发布。
有关有效范围表达式的更多信息,请转到 Requires 参考