PkgConfigDeps

PkgConfigDeps 是 pkg-config 的依赖生成器。生成名为 <PKG-NAME>.pc 的 pkg-config 文件,其中包含有效的 pkg-config 文件语法。

此生成器可以在 conanfile 中按名称使用

conanfile.py
class Pkg(ConanFile):
    generators = "PkgConfigDeps"
conanfile.txt
[generators]
PkgConfigDeps

它也可以在 conanfile 的 generate() 方法中完全实例化

from conan import ConanFile
from conan.tools.gnu import PkgConfigDeps

class App(ConanFile):
    settings = "os", "arch", "compiler", "build_type"
    requires = "zlib/1.2.11"

    def generate(self):
        pc = PkgConfigDeps(self)
        pc.generate()

生成的文件

名为 <PKG-NAME>.pcpkg-config 格式文件,其中包含有效的 pkg-config 文件语法。prefix 变量会自动调整为 package_folder

prefix=/Users/YOUR_USER/.conan/data/zlib/1.2.11/_/_/package/647afeb69d3b0a2d3d316e80b24d38c714cc6900
libdir=${prefix}/lib
includedir=${prefix}/include
bindir=${prefix}/bin

Name: zlib
Description: Conan package: zlib
Version: 1.2.11
Libs: -L"${libdir}" -lz -F Frameworks
Cflags: -I"${includedir}"

自定义

命名

默认情况下,*.pc 文件将按照以下规则命名

  • 对于包,它使用包名,例如,包 zlib/1.2.11 -> zlib.pc

  • 对于组件,包名 + 连字符 + 组件名,例如,具有 self.cpp_info.components["crypto"]openssl/3.0.0 -> openssl-crypto.pc

您可以使用 pkg_config_namepkg_config_aliases 属性更改该默认行为。请参阅下面的属性部分

如果配方使用组件,则生成的文件将是 <[PKG-NAME]-[COMP-NAME]>.pc,其中包含它们对应的标志和依赖关系。

此外,还会生成一个 <PKG-NAME>.pc 文件,以保持与开始支持组件的配方的消费者的兼容性。此 <PKG-NAME>.pc 文件声明包的所有组件为依赖项,而其余字段将为空,依赖于来自组件 <[PKG-NAME]-[COMP-NAME]>.pc 文件的标志传播。

参考

class PkgConfigDeps(conanfile)
property content

获取所有 .pc 文件的内容

generate()

保存所有 *.pc 文件

set_property(dep, prop, value)

使用此方法,您可以覆盖使用者从 Conan 配方设置的属性值。这可以针对 pkg_config_namepkg_config_aliasespkg_config_custom_content 属性完成。

参数:
  • dep – 要设置属性的依赖项的名称。对于组件,使用语法:dep_name::component_name

  • prop属性的名称。

  • value – 属性的值。使用 None 使上游配方设置的任何值无效。

属性

build_context_activated

当您有一个 build-require 时,默认情况下不会生成 *.pc 文件。但是您可以使用 build_context_activated 属性激活它

tool_requires = ["my_tool/0.0.1"]
def generate(self):
    pc = PkgConfigDeps(self)
    # generate the *.pc file for the tool require
    pc.build_context_activated = ["my_tool"]
    pc.generate()

build_context_folder

Conan 2.2.0 的新功能

当您将同一个包作为 build-requireregular require 时,它会在生成器中引起冲突,因为 *.pc 文件的文件名以及名称、依赖项名称等会发生冲突。

例如,这是具有一些要求(capnproto、protobuf...)的典型情况,这些要求包含一个用于在构建时生成源代码的工具(因此它是 build_require),但也提供一个链接到最终应用程序的库,因此您也有一个 regular require。当我们进行交叉构建时,解决此冲突尤其重要,因为该工具(将在构建机器中运行)属于与库不同的二进制包,该库将在主机上“运行”。

您可以使用 build_context_folder 属性来指定一个文件夹,以保存由 build_context_activated 中列出的所有构建要求创建的 *.pc 文件

tool_requires = ["my_tool/0.0.1"]
requires = ["my_tool/0.0.1"]
def generate(self):
    pc = PkgConfigDeps(self)
    # generate the *.pc file for the tool require
    pc.build_context_activated = ["my_tool"]
    # save all the *.pc files coming from the "my_tool" build context and its requirements
    pc.build_context_folder = "build"  # [generators_folder]/build/
    pc.generate()

build_context_suffix

已弃用:请改用 build_context_folder 属性

与上面引用的 build_context_folder 属性相同的概念,但这旨在为要求指定一个后缀,因此构建上下文(工具要求)中要求的 文件/依赖项/名称将被重命名

tool_requires = ["my_tool/0.0.1"]
requires = ["my_tool/0.0.1"]
def generate(self):
    pc = PkgConfigDeps(self)
    # generate the *.pc file for the tool require
    pc.build_context_activated = ["my_tool"]
    # disambiguate the files, requires, names, etc
    pc.build_context_suffix = {"my_tool": "_BUILD"}
    pc.generate()

重要

此属性不应与 build_context_folder 属性同时使用。

属性

以下属性会影响 PkgConfigDeps 生成器

  • pkg_config_name 属性将定义生成的 *.pc 文件 (xxxxx.pc) 的名称

  • pkg_config_aliases 属性为 pkg_config 生成器设置任何包/组件名称的一些别名。此属性仅接受类似列表的 Python 对象。

  • pkg_config_custom_content 属性会将用户定义的内容作为自由格式变量添加到此生成器创建的 .pc 文件中。该内容可以是字符串或类似字典的 Python 对象。请注意,此处声明的变量将覆盖 Conan 已定义的那些变量。单击此处,获取有关 *.pc 文件中变量类型的更多信息。

  • system_package_version: 属性设置一个自定义版本,用于属于为包创建的 *.pc 文件的 Version 字段。

  • component_version 属性设置一个自定义版本,用于属于为该组件创建的 *.pc 文件的 Version 字段(优先于 system_package_version 属性)。

这些属性可以在全局 cpp_info 级别或组件级别定义。

示例

def package_info(self):
    custom_content = {"datadir": "${prefix}/share"}  # or "datadir=${prefix}/share"
    self.cpp_info.set_property("pkg_config_custom_content", custom_content)
    self.cpp_info.set_property("pkg_config_name", "myname")
    self.cpp_info.components["mycomponent"].set_property("pkg_config_name", "componentname")
    self.cpp_info.components["mycomponent"].set_property("pkg_config_aliases", ["alias1", "alias2"])
    self.cpp_info.components["mycomponent"].set_property("component_version", "1.14.12")