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)
在这里,我们将文件从不可变的软件包文件夹复制到最终确定的软件包文件夹,该文件夹在 finalize 方法内部(以及此后的任何地方)都将是新的软件包文件夹,以便软件包所做的任何修改都在本地最终确定的文件夹中完成,而不会影响原始软件包。
对于需要访问原始软件包的情况,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 之前有机会修改它,但它并非旨在修改特定运行机器的软件包。