自定义 Conan 生成器¶
如果您需要使用 Conan 开箱即用不支持的构建系统或工具,则可以使用自定义生成器创建自己的自定义集成。 这可以通过三种不同的方式完成。
作为 python_requires 的自定义生成器¶
在 Conan 中拥有自己的自定义生成器的一种方法是将它们用作 python_requires。 您可以声明一个 MyGenerator 类,其中包含在 mygenerator/1.0 python_requires 包中生成某些文件的所有逻辑
from conan import ConanFile
from conan.tools.files import save
class MyGenerator:
def __init__(self, conanfile):
self._conanfile = conanfile
def generate(self):
deps_info = ""
for dep, _ in self._conanfile.dependencies.items():
deps_info += f"{dep.ref.name}, {dep.ref.version}\n"
save(self._conanfile, "deps.txt", deps_info)
class PyReq(ConanFile):
name = "mygenerator"
version = "1.0"
package_type = "python-require"
然后 conan create mygenerator
,并在您自己的包的 generate 方法中使用它,如下所示
from conan import ConanFile
class MyPkg(ConanFile):
name = "pkg"
version = "1.0"
python_requires = "mygenerator/1.0"
requires = "zlib/1.2.11", "bzip2/1.0.8"
def generate(self):
mygenerator = self.python_requires["mygenerator"].module.MyGenerator(self)
mygenerator.generate()
然后,在这个 pkg
recipe 上执行 conan install pkg
,将创建一个包含以下内容的 deps.txt
文本文件
zlib, 1.2.11
bzip2, 1.0.8
这样做的好处是您可以将自己的自定义生成器作为包进行版本控制,并且还可以将这些生成器作为 Conan 包进行共享。
使用全局自定义生成器¶
如果将自定义生成器存储在 [CONAN_HOME]/extensions/generators
文件夹中,则也可以全局使用它们。 您可以直接将它们放置在该文件夹中,也可以使用 conan config install
命令安装。
from conan.tools.files import save
class MyGenerator:
def __init__(self, conanfile):
self._conanfile = conanfile
def generate(self):
deps_info = ""
for dep, _ in self._conanfile.dependencies.items():
deps_info = f"{dep.ref.name}, {dep.ref.version}"
save(self._conanfile, "deps.txt", deps_info)
然后,您可以通过名称在 recipe 中或使用 -g 参数在命令行中使用它们
conan install --requires=zlib/1.2.13 -g MyGenerator
来自 tool_requires 的生成器¶
警告
此功能是实验性的,可能会发生重大更改。 有关更多信息,请参见 Conan 稳定性 部分。
直接依赖项工具 requires 也可用于提供自定义生成器。 以下示例显示了如何创建一个自定义生成器,该生成器生成一个包含包依赖项的文件,就像上面的示例一样,但使用 tool_require
而不是 python_require
将生成器注入到 recipe 中,方法是将它们添加到 package_info
方法中的 self.generator_info
列表中。
from conan import ConanFile
from conan.tools.files import save
class MyGenerator:
def __init__(self, conanfile):
self._conanfile = conanfile
def generate(self):
deps_info = ""
for dep, _ in self._conanfile.dependencies.items():
deps_info = f"{dep.ref.name}, {dep.ref.version}"
save(self._conanfile, "deps.txt", deps_info)
class MyToolReq(ConanFile):
name = "mygenerator-tool"
version = "1.0"
def package_info(self):
self.generator_info = [MyGenerator]
然后,在您的 recipe 中对 mygenerator-tool
包进行 tool_requires
将自动将生成器注入到 recipe 中。
注意
请注意,也可以使用 tool_requires 注入内置生成器,方法是按名称添加它们:self.generator_info.append("CMakeDeps")
。 tool_require``ing this package will inject the ``CMakeDeps
生成器到 recipe 中,就像在它的 generators
属性中声明的一样。