本文档翻译自:https://docs.conan.io/en/latest/creating_packages/define_abi_compatibility.html#compatible-packages
    :::success Waring**
    这是一项实验性功能,可能会在将来的版本中发生重大更改。 ::: 上面的方法为不同的输入配置定义了1个程序包ID。 例如,范围内的所有 gcc 版本 (v >= "4.5" and v < "5.0") 将具有完全相同的软件包ID,无论用于构建它的gcc版本是什么。 它会去除原始信息,一旦构建了二进制文件,就不知道使用哪个版本的gcc来构建了它。

    但是可以定义具有不同程序包ID的兼容二进制文件。 例如,每个gcc版本可能有不同的二进制文件,因此gcc 4.8软件包将是一个与gcc 4.9软件包具有不同软件包ID的软件包,并且仍然定义在构建时可以使用gcc 4.8软件包 使用gcc 4.9

    我们可以定义一个兼容软件包的有序列表,如果我们的配置文件定义的软件包ID不可用,则会对其进行检查。 让我们看一个例子:
    可以说,我们正在使用gcc 4.9进行配置。 但是对于给定的软件包,如果我们找不到使用gcc 4.9构建的二进制文件,我们希望退回到使用gcc 4.8gcc 4.7构建的二进制文件。 可以定义为:

    1. from conans import ConanFile
    2. class Pkg(ConanFile):
    3. settings = "os", "compiler", "arch", "build_type"
    4. def package_id(self):
    5. if self.settings.compiler == "gcc" and self.settings.compiler.version == "4.9":
    6. for version in ("4.8", "4.7"):
    7. compatible_pkg = self.info.clone()
    8. compatible_pkg.settings.compiler.version = version
    9. self.compatible_packages.append(compatible_pkg)

    请注意,如果输入配置为gcc 4.8,则由于不满足条件,它将不会尝试回退到gcc 4.7的二进制文件。

    self.info.clone() 方法从配方的当前实例中复制settingsoptionsrequires的值,以便可以对其进行修改以模拟兼容性。
    开发人员有责任确保此类二进制文件确实兼容。例如:

    1. from conans import ConanFile
    2. class Pkg(ConanFile):
    3. options = {"optimized": [1, 2, 3]}
    4. default_options = {"optimized": 1}
    5. def package_id(self):
    6. for optimized in range(int(self.options.optimized), 0, -1):
    7. compatible_pkg = self.info.clone()
    8. compatible_pkg.options.optimized = optimized
    9. self.compatible_packages.append(compatible_pkg)

    此配方定义二进制文件与其本身以较低的优化值构建的二进制文件兼容。 它最多可以具有3个不同的二进制文件,每个optimized选项的不同值对应一个。 package_id()定义了一个以optimized=1构建的二进制文件可以完美链接,即使有人在其配置中定义了optimized=2optimized=3的二进制文件也可以运行。 但是,如果所请求的二进制数被optimized=1,则将不考虑使用optimized=2构建的二进制文件。

    二进制文件应在所有效果上都是可互换的。 这也适用于该配置的其他用法。 如果此示例使用optimized的选项有条件地要求不同的依赖项,则不会考虑。 在构建了整个依赖关系图之后,将处理package_id()步骤,因此无法根据此兼容性模型定义如何解决依赖关系,它仅适用于二进制文件可以互换的用例。 :::info Note
    兼容软件包是依赖关系图中二进制文件的匹配项。 当找到兼容的软件包时,**--build=missing** 构建策略将不会从该软件包的源进行构建。 ::: 查看 “兼容编译器” 部分,以了解如何利用兼容包的另一个示例。