仅在构建包时使用系统要求

在某些情况下,您可能希望仅在构建包时使用系统要求,而在安装包时不使用。当您想在 CI/CD 管道中构建一个包,但又不想在不同环境中安装 Conan 包时运行系统包管理器时,这可能很有用。对于这些情况,有几种方法可以实现此目标。

将系统包的 Conan 包包装器用作构建要求

在这种方法中,您可以使用 Conan 包来包装 包装的系统包。然后,可以使用 build_requirements() 方法常规地使用该包。

from conan import ConanFile

class MyPackage(ConanFile):
    name = "mypackage"
    settings = "os", "compiler", "build_type", "arch"

    def build_requirements(self):
        self.tool_requires("ncurses/system")

    ...

这确保了包mypackage的下游使用者不会直接调用系统包管理器(例如 apt-get)。只有系统包装包的直接使用者,用于 ncurses 的包,才会在构建该包时执行系统包管理器。

ncurses 集中并包装在单独的配方中,使其可以在多种情况下重用,并且是避免代码重复的好方法。

直接在 build() 方法中使用系统包

如果您想仅在构建包时运行系统包管理器,但又没有 Conan 包来包装系统库信息,则可以在 build() 方法中运行系统包管理器。

from conan import ConanFile
from conan.tools.system import package_manager

class MyPackage(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    ...

    def build(self):
        if self.settings.os == "Linux":
            apt = package_manager.Apt(self)
            apt.install(["libncurses-dev"], update=True, check=True)

这样,系统包管理器将在构建包时调用,而不会在安装包时调用。它的优点是不需要创建单独的 Conan 包来包装系统库信息,这是一种更简单的情况,只有单个配方需要安装系统包。

但是,如果多个配方使用相同的系统包,此方法可能会导致代码重复。建议谨慎使用此方法,仅用于定义明确的情况。