configure()

configure() 方法应用于在 recipe 中配置设置和选项,以便在 generate()build()package() 等不同的方法中后续使用。 此方法在构建依赖关系图和扩展包依赖关系时执行,这意味着当此方法执行时,依赖关系仍然不存在,并且无法访问 self.dependencies

例如,对于 C (不是 C++) 库,compiler.libcxxcompiler.cppstd 设置在 build() 期间甚至不应该存在。 这不仅因为它们不是 package_id 的一部分,而且它们根本不应该在构建过程中使用。 它们将在 profile 中定义,因为图中的其他包可以是 C++ 包并且需要它们,但此 recipe 有责任删除它们,以便它们不会在 recipe 中使用

settings = "os", "compiler", "build_type", "arch"

def configure(self):
    # Not all compilers have libcxx subsetting, so we use rm_safe
    # to avoid exceptions
    self.settings.rm_safe("compiler.libcxx")
    self.settings.rm_safe("compiler.cppstd")

def package_id(self):
    # No need to delete those settings here, they were already deleted
    pass

注意

从 Conan 2.4 开始,如果定义了 languages = "C" recipe 属性(实验性),则不需要上述 configure()

对于要删除设置的每个子设置的包,可以使用带有通配符的 rm_safe 方法

settings = "os", "compiler", "build_type", "arch"

def configure(self):
    self.settings.rm_safe("compiler.*")

这将删除 compiler 设置的所有子设置,例如 compiler.libcxxcompiler.cppstd,但保留 compiler 设置本身(self.settings.rm_safe("compiler") 会将其删除)。

同样,对于包含库的包,fPIC 选项实际上仅在库编译为静态库时适用,否则 fPIC 选项没有意义,因此应该删除它

options = {"shared": [True, False], "fPIC": [True, False]}
default_options = {"shared": False, "fPIC": True}

def configure(self):
    if self.options.shared:
        # fPIC might have been removed in config_options(), so we use rm_safe
        self.options.rm_safe("fPIC")

可用的自动实现

警告

此功能是实验性的,可能会有重大更改。 有关详细信息,请参阅 Conan 稳定性 部分。

如果未定义 configure() 方法,如果 implements ConanFile 属性中指定了某些常规选项,Conan 可以自动管理它们

auto_shared_fpic

自动管理的选项

  • fPIC(True,False)。

  • shared(True,False)。

  • header_only(True,False)。

可以像这样添加到 recipe 中

from conan import ConanFile

class Pkg(ConanFile):
    implements = ["auto_shared_fpic"]
    ...

然后,如果在 recipe 中没有指定 configure() 方法,Conan 将在 configure 步骤中自动管理 fPIC 设置,如下所示

if conanfile.options.get_safe("header_only"):
    conanfile.options.rm_safe("fPIC")
    conanfile.options.rm_safe("shared")
elif conanfile.options.get_safe("shared"):
    conanfile.options.rm_safe("fPIC")

请注意,将此实现添加到 recipe 也可能会影响 configure 步骤。

如果需要在 recipe 中实现自定义行为,但也需要此逻辑,则必须显式声明

def configure(self):
    if conanfile.options.get_safe("header_only"):
        conanfile.options.rm_safe("fPIC")
        conanfile.options.rm_safe("shared")
    elif conanfile.options.get_safe("shared"):
        conanfile.options.rm_safe("fPIC")
    self.settings.rm_safe("compiler.libcxx")
    self.settings.rm_safe("compiler.cppstd")

Recipe 可以为其依赖项选项建议值,如 default_options = {"*:shared": True},但无法有条件地执行此操作。 为此目的,也可以使用 configure() 方法

def configure(self):
    if something:
        self.options["*"].shared = True

注意

最佳实践

  • 请记住,不能在 recipe 中定义 settingsconf 值,它们是只读的。

  • options 值的定义只是一个“建议”,根据图计算、优先级等,options 的最终值可能与 recipe 设置的值不同。

另请参阅