build_id()

build_id() 方法允许重用相同的构建来在缓存中创建不同的二进制包,这可能会节省构建时间,因为它可避免一些不必要的重复构建。因此,它是一种优化方法。

在通常情况下,每个二进制包对应一个构建文件夹,并且其 package_id 与包的 package_id 完全相同。然而,这种行为是可以改变的,在一些场景下这可能很有用

  • 包构建脚本在同一次运行中同时生成几种不同的配置(例如 debug 和 release 构建产物),并且无法单独构建每种配置。

  • 包构建脚本生成一种二进制配置,但产生可以单独打包的不同构建产物。例如,如果有一些测试可执行文件,您可能希望创建两个包:一个只包含库供一般使用,另一个还包含测试(用于合规性、后续可重现性、调试等)。

在第一种情况下,我们可以例如这样写

settings = "os", "compiler", "arch", "build_type"

def build_id(self):
    self.info_build.settings.build_type = "Any"

此 recipe 将为 debug 和 release 配置生成最终不同的包,具有不同的 package_id。但是,由于 build_id() 将为任何 build_type 生成相同的 build_id,因此只会执行一次构建(一个文件夹和一个 build() 调用),构建出 debug 和 release 的构建产物,然后会为每种配置调用 package() 方法,并且它应该根据 self.settings.build_type 的值有条件地打包构建产物。如果使用不同的编译器或架构,仍会执行不同的构建。

其他信息,如自定义包选项,也可以更改

def build_id(self):
    self.info_build.options.myoption = 'MyValue' # any value possible
    self.info_build.options.fullsource = 'Always'

如果 build_id() 方法不修改 info_build 数据,并且它仍然生成与 package_id 不同的 ID,则将应用标准行为。请考虑以下示例

settings = "os", "compiler", "arch", "build_type"

def build_id(self):
    if self.settings.os == "Windows":
        self.info_build.settings.build_type = "Any"

这仅当包用于 Windows 时才会生成不同的 build_id,因此只需为所有 build_type 值运行一次 build()。在任何其他操作系统中,行为将是标准的,就好像没有定义 build_id() 方法一样,为每个 build_type 运行一次不同的 build()

注意

最佳实践

Conan 强烈建议为每种不同的配置使用一个带有其自己的 package_id 的包二进制文件。build_id() 方法的目标是处理那些无法轻松更改为每次构建一种配置的遗留构建脚本。