我们已经知道,conan会根据设定的构建选项或者其他设置(也即package info)来完成pacakge ID的计算,这个过程是自动的。
如果出现这样一种情况,比如用户设置了使用4.9版本的gcc编译器进行构建整个工程,但是其中有一个包我们没有使用gcc 4.9构建过,找不到对应的二进制文件,那么我们就可以做一次fallback:
from conans import ConanFile
class Pkg(ConanFile):
settings = "os", "compiler", "arch", "build_type"
def package_id(self):
if self.settings.compiler == "gcc" and self.settings.compiler.version == "4.9":
for version in ("4.8", "4.7"):
compatible_pkg = self.info.clone()
compatible_pkg.settings.compiler.version = version
self.compatible_packages.append(compatible_pkg)
还有一点要注意的是,比如构建不支持windows平台,你可能会写一个validate函数:
def validate(self):
if self.settings.os == "Windows":
raise ConanInvalidConfiguration("Windows not supported")
这样的话,最好在package_id函数中排除windows:
def package_id(self):
if self.settings.build_type == "Debug" and self.settings.os != "Windows":
compatible_pkg = self.info.clone()
compatible_pkg.settings.build_type = "Release"
self.compatible_packages.append(compatible_pkg)
如果不加的话,虽然compatible package会有api来检查这些信息,但是会浪费资源。

conan在计算package ID时,也会受requires的影响,在默认模式下,依赖包中只有major version会影响最终的package ID计算,minor version和patch version不会被考虑,当然,间接依赖的包也不会被考虑进来。
如果你希望将这些因素全部考虑进来,你需要使用full version mode:

另外,你也可以不在recipe,而是在config文件中修改:

接下来,我们进入到package_id练习:
conan remove "*" -f
conan create hello hello/1.0@user/testing
conan create chat user/testing
conan create app user/testing

然后,我们在hello/src/hello.h中改动一点东西

conan create hello hello/1.1@user/testing
conan create app user/testing

输出信息并没有变!
现在,我们将config改为full_version_mode:
conan config set general.default_package_id_mode=full_version_mode
然后执行:
conan create app user/testing
会报错,没有对应的chat二进制文件

conan create app user/testing --build=missing
conan search chat/1.0@user/testing
