finalize()

警告

此功能处于实验阶段,可能存在重大更改。有关详细信息,请参阅 Conan 稳定性 部分。

包不变性是 Conan 中一个重要的概念。它确保包在构建和打包后不会被修改,从而保证包 ID 一致,并在不同的机器上重复使用。

此方法旨在自定义正在运行的机器上的包,允许对包进行修改,这些修改将由包的使用者使用,但不会修改 Conan 缓存中的原始包。此方法在包安装到本地缓存后调用,并且修改不会上传到任何远程服务器,它们仅限于本地。

此方法的主要用例包括

  • 拥有在运行时被修改的不同包(例如,作为执行的一部分生成 pycache 文件的 python 工具)

  • 修改要在本地机器上使用的包(例如,创建包含包在本地机器上使用所需的环境变量的 conf 文件)

这些更改对包的使用者是透明的,他们将使用自定义的包,就像他们正在处理原始包一样,因此在此方法中进行的更改应该有效。

finalize() 用法示例

此方法最常见的用例是避免破坏包的不变性。

例如,如果某个包在执行期间生成一些文件,例如生成 pycache 文件的 python 包,则可以使用此方法在本地机器上生成这些文件,而不会影响原始包。Meson 等工具就是这样。

from conan import ConanFile, conan_version
from conan.tools.files import copy


class MesonPackage(ConanFile):
    ...

    def package(self):
        copy(self, "*", src=self.source_folder, dst=os.path.join(self.package_folder, "bin"))
        ...

    def finalize(self):
        copy(self, "*", src=self.immutable_package_folder, dst=self.package_folder)

在这里,我们将文件从不可变的包文件夹复制到最终的包文件夹,在 finalize 方法(以及此方法之后的所有地方)中,它将成为新的包文件夹,以便包进行的任何修改都在本地最终文件夹中进行,而不会影响原始包。

对于需要访问原始包的情况,immutable_package_folder 属性在同一个配方的 self.immutable_package_folder 中以及通过从属配方的 self.dependencies[<package_name>].immutable_package_folder 属性中可用。此信息也作为 conan graph info 等中的图形信息的一部分进行序列化。

由于此方法必须与生成的包 ID 具有 1 对 1 的对应关系,因此在 finalize() 方法内部禁止访问 self.settingsself.optionsself.cpp_info,并且**必须**通过 self.info 属性进行访问。

注意

如果不使用这种方法,包将在包文件夹中生成 pycache 文件,因此需要设置 PYTHONDONTWRITEBYTECODE 以避免修改包,但这会影响性能,并且通过 conan cache check-integrity 或作为 conan upload ... --check 中上传过程的一部分执行缓存完整性检查如果修改后的包被检查,则会引发错误。

警告

这不是 post_package 钩子的替代品。钩子在创建包后运行,以便在计算包 ID 之前修改它,但它并非旨在为特定运行机器修改包。