configure()

configure() 方法应该用于在 recipe 中配置设置(settings)和选项(options),以供后续在 `generate()`、`build()` 或 `package()` 等方法中使用。此方法在构建依赖图并展开包依赖时执行,这意味着当此方法执行时,依赖项尚不存在,它们并不存在,因此无法访问 `self.dependencies`。

例如,对于 C(非 C++)库,`compiler.libcxx` 和 `compiler.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 开始,如果 recipe 属性 `languages = "C"`(实验性)已定义,则上述 `configure()` 不是必需的。

对于您希望移除设置的每个子集(subsetting)的包,您可以使用带有通配符的 `rm_safe` 方法。

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

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

这将移除 `compiler` 设置的所有子设置,例如 `compiler.libcxx` 或 `compiler.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()` 方法未定义时,Conan 可以自动管理一些约定俗成的选项(options),如果它们在 `implements` ConanFile 属性中指定。

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")

Recipes 可以为其依赖项的选项建议值,例如 `default_options = {"*:shared": True}`,但这不能有条件地设置。为此目的,还可以使用 `configure()` 方法。

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

注意

最佳实践

  • 请记住,**不能**在 recipes 中定义 `settings` 或 `conf` 值,它们是只读的。

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

另请参阅