finalize()¶
警告
此功能是实验性的,可能会发生重大更改。有关更多信息,请参阅 Conan 稳定性 部分。
包的不可变性是 Conan 中的一个重要概念。它确保包在构建和打包后不会被修改,从而保证包 ID 的一致性,并且包可以在不同的机器上重复使用。
此方法旨在定制在运行机器上的包,允许对包进行修改,这些修改将由包的消费者使用,但不会修改 Conan 缓存中的原始包。此方法在包安装到本地缓存后调用,并且修改不会上传到任何远程服务器,仅为本地修改。
此方法的主要用例包括
拥有在运行时被修改的包(例如,Python 工具在执行过程中生成 pycache 文件)
修改包以在本地机器上使用(例如,创建一个
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.settings、self.options 和 self.cpp_info,并且**必须**通过 self.info 属性进行访问。
注意
如果不使用这种方法,该包将在包文件夹中生成 pycache 文件,因此需要设置 PYTHONDONTWRITEBYTECODE 以避免修改包,但这会影响性能,并且执行缓存完整性检查(通过 conan cache check-integrity 或 conan upload ... --check 中的上传过程)如果修改后的包被检查,则会引发错误。
警告
这不是 post_package 钩子的替代品。该钩子在创建包之后运行,以便有机会在计算 package_id 之前修改它,但它不适用于针对特定运行机器的包的修改。