仅在构建软件包时使用系统需求

在某些情况下,您可能希望仅在构建软件包时使用系统需求,而不是在安装软件包时使用。当您想要在 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 的系统包装软件包的直接软件包使用者在构建软件包时才会执行系统软件包管理器。

在单独的 recipe 中集中和包装 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 软件包来包装系统库信息,这是一种更简单的情况,仅当单个 recipe 需要安装系统软件包时才需要这样做。

尽管如此,如果多个 recipe 使用相同的系统软件包,则此方法可能会导致代码重复。建议谨慎使用此方法,仅用于包含良好的情况。