finalize()¶
警告
此功能是实验性的,可能会发生重大更改。有关更多信息,请参阅 Conan 稳定性 部分。
包的不可变性是 Conan 的一个重要概念。它确保包在构建和打包后不会被修改,从而使包 ID 保持一致,并且包可以在不同的机器上重用。
此方法旨在用于定制运行在本地机器上的包,允许修改将供包的消费者使用的包,但不会修改 Conan 缓存中的原始包。此方法在包安装到本地缓存后调用,并且修改不会上传到任何远程服务器,它们仅是本地的。
此方法的主要用例包括:
拥有不同的包,这些包在运行时会被修改(例如,python 工具在执行过程中生成 pycache 文件)
修改要在本地机器上使用的包(例如,创建一个包含包在本地机器上使用所需环境变量的
conf文件)
这些更改对包的消费者来说是透明的,他们将使用定制的包,就像处理原始包一样,因此在此方法中所做的更改应该可以正常工作。
finalize() 示例用法¶
此方法最常见的用例是避免破坏包的不可变性。
例如,如果一个包在其执行过程中生成了一些文件,例如一个 python 包生成 pycache 文件,您可以使用此方法在本地机器上生成这些文件,而不会影响原始包。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)
在这里,我们将文件从不可变包文件夹复制到 finalized 包文件夹,在 finalize 方法(以及之后的所有点)中,这将是新的包文件夹,因此包所做的任何修改都将在本地 finalized 文件夹中进行,而不会影响原始包。
对于需要访问原始包的情况,immutable_package_folder 属性在同一个 recipe 的 self.immutable_package_folder 以及依赖方的 recipe 中通过 self.dependencies[<package_name>].immutable_package_folder 属性可用。这些信息也作为图信息的一部分被序列化,例如在 conan graph info 中。
由于此方法必须与生成的包 ID 具有一对一的对应关系,因此在 finalize() 方法中禁止访问 self.settings、self.options 和 self.cpp_info,**必须**通过 self.info 属性进行访问。
注意
如果不使用此方法,包将在包文件夹中生成 pycache 文件,因此需要设置 PYTHONDONTWRITEBYTECODE 以避免修改包,但这会影响性能。并且,无论是通过 conan cache check-integrity 还是在 conan upload ... --check 的上传过程的一部分执行的缓存完整性检查,如果修改后的包被检查,都会引发错误。
警告
这并不是 post_package hook 的替代品。该 hook 在包创建后运行,有机会在计算 package_id 之前修改它,但它并不适用于针对特定运行机器进行的包修改。