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 属性在同一 recipe 的 self.immutable_package_folder 中以及通过依赖项 recipe 中的 self.dependencies[<package_name>].immutable_package_folder 属性中都可用。此信息也作为图形信息的一部分序列化在 conan graph info 等命令中。

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

注意

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

警告

这不能替代 post_package hook。hook 在包创建后运行,以便在计算 package_id 之前有机会修改它,但它不适用于为特定运行机器修改包。