Conan 1.37 带来了几个重要的新功能。首先,Conan 客户端附带的默认 remotes.txt 文件中添加了 Conan Center 的新 URL。此版本还包括一个名为 layout() 的主要新方法,用于 conanfile.py,以及一些用于与 Bazel 构建系统集成的新的类。此外,还新增了一个名为 neverbuild_policy,以及一个名为 --build-require 的新标记,可与 conan installconan create 命令一起使用。

ConanCenter 的新默认 URL

在此版本中,Conan 客户端将安装以下 2 个 URL 到 remotes.txt 文件中(按以下顺序):

  • https://center.conan.io
  • https://conan.bintray.com

需要理解的是,这些 URL 指向两个独立的 Conan 存储库,它们之间存在以下差异:

https://conan.bintray.com

此存储库包含所有 Conan 包的副本,包括新的和旧的(“旧的”是指早于 ConanCenterIndex 的包)。目前,所有新包的构建和二进制文件副本都上传到这里。在 **7月1日**,新的包将 **停止** 上传到这里,并且该存储库将有效地变为只读。

https://center.conan.io

此存储库仅包含从 ConanCenterIndex 构建的所有 Conan 包的副本(没有旧的包)。目前,所有新包的构建和二进制文件副本都上传到这里。在 **7月1日**,此存储库将成为上传新包的 **唯一** 位置。这就是我们在客户端中将其放在第一位的原因。

长期弃用:https://conan.bintray.com

我们尚未确定从默认远程列表中删除 conan.bintray.com URL 或物理删除存储库及其包的日期。这些事件可能要到很久以后才会发生。但是,每个人都应该理解,它们最终会被删除。

用于 conanfile.py 的新 layout() 方法

新的 layout() 方法是 conanfile.py 中最有趣且期待已久的新增功能之一。因此,我们将在此解释其基本价值主张,但首先,让我们看一个简单的示例。

def layout(self):
    self.cpp.source.includedirs = ["include"]
    self.cpp.build.libdirs = ["."]
    self.cpp.build.libs = ["mylib"]
    self.cpp.build.includedirs = ["gen_include"]
    self.cpp.package.libs = ["mylib"]

我们首先要强调的一个好处是,当包处于 editable_mode 时,它提供了一种新的方式来声明信息供下游使用者使用。从历史上看,声明使用者信息的场所是在 package_info() 方法内部。但是,该方法并非设计用于处理 editable_mode 下包的情况,因此最初我们提供了一种单独的机制来处理 editable_mode 案例,称为 布局文件。但是,这些文件位于配方外部,因此 layout() 方法带来的重大改进在于,配方作者可以在配方内部声明信息,这感觉更自然,并且得到了许多用户的强烈要求。

layout() 方法中定义适当的值还有另一个主要好处。它使用户能够更准确地重现 conan create 命令执行的步骤,这些步骤专门在 Conan 缓存中进行(在他们的本地工作区中使用“本地开发工作流”)。因此,现在用户可以在本地目录中拥有配方,并运行本地流程命令。

    conan source
    conan build
    conan package

Conan 将有效地执行与 conan create 相同的操作,但这些操作将使用用户空间中的目录。

最后,我们正在尝试使用 layout 方法中声明所有适当信息的另一个可能好处。也就是说,能够“自动”实现 package() 方法的传统 self.copy 步骤,这些步骤在许多配方中都以样板的形式出现。因此,将来,我们可能只需要编写类似以下内容……

def package(self):
    LayoutPackager(self).package()

……来替换目前可能看起来像这样的 package() 方法……

def package(self):
    self.copy("*.h", src="include", dst="include")
    self.copy("*.hpp", src="include", dst="include")
    self.copy("*.hxx", src="include", dst="include")
    self.copy("*.a", src=".", dst="lib")
    self.copy("*.so", src=".", dst="lib")
    self.copy("*.so.*", src=".", dst="lib")
    self.copy("*.lib", src=".", dst="lib")
    self.copy("*.dylib", src=".", dst="lib")
    self.copy("*.dll", src=".", dst="bin")
    self.copy("*.exe", src=".", dst="bin")

需要注意的是,我们已经发现该策略存在一些挑战,并且在即将发布的版本中讨论了对 LayoutPackager 的重大更改和改进,因此绝对不建议将其用于生产配方。我们在此版本中仅将其提供给高级用户进行实验并提供反馈。

新的 Bazel 集成

我们为 Bazel 构建系统 添加了以下两个新的生成器,它们在本质上类似于 CMakeDepsCMakeToolchain 生成器。

  • BazelDeps
  • BazelToolchain

我们还添加了一个名为 Bazel 的标准构建帮助器类,以使从 CLI 调用 Bazel 减少错误(类似于 CMakeMSBuild 构建帮助器)。

    def build(self):
        bazel = Bazel(self)
        bazel.configure()
        bazel.build(label="//main:hello-world")

虽然与其他一些构建系统相比,目前使用 Bazel 的开源项目不多,但一些企业团队将其用于其内部组件,并且他们也提出了此需求。

新的 build_policy=never

创建 Conan 包基本上有两种方式:

  • conan create:将源代码编译成二进制文件,然后打包。
  • conan export-pkg:获取预编译的二进制文件并将其打包。

Conan 的一项特色功能是能够将 --build 传递给 conan install 命令,并使 Conan 从源代码重新构建图中的一些或所有依赖项。不幸的是,对于使用 conan export-pkg 命令创建的依赖项图中的任何包,都无法从源代码重新构建。这会导致在传递 --build 时出现尴尬的问题。

现在,配方作者可以并且应该将以下属性添加到任何旨在与 conan export-pkg 一起使用的配方中:

    build_policy=never

当 Conan 遇到具有 build_policy=never 的配方时,它将理解此配方无法从源代码重新构建,并将继续执行下一个配方而不会出错。

新的 --build-require 标记

conan installconan create 命令现在支持一个额外的标记:--build-require。发现需要此标记是由于用于交叉构建的新 buildhost“上下文”导致的。它的用例并非最常见的工作流,因此我们将尝试在此澄清其用途。

在 Conan 中构建工具作为 build_requires 的最常见方法是在 conanfileprofile 中将其列出。在这些情况下,Conan 很容易理解这些包属于 build 上下文,并为这些包使用 build 配置文件。因此,在这些情况下,我们根本不需要 --build-require 标记。

但是,在某些情况下,用户希望单独使用构建工具的配方或包。例如,当您通过引用安装它并运行 conan install build_tool/1.0.0 ... 时。或者,当您使用 test_package 创建或修改/测试构建工具的配方时。在这些情况下,您在构建工具配方上调用 conan create,并且您可以传递一个单独的“主机配置文件”(-pr:h windows)和“构建配置文件”(-pr:b linux),但 Conan 将无法知道正在创建的配方应该使用“构建配置文件”而不是“主机配置文件”。这就是 --build-require 标记的原因。它告诉 Conan 正在安装或创建的配方或包应该使用“构建配置文件”(-pr:b)。



除了上面列出的项目之外,还有很多相当有影响的错误修复,您可能希望了解。如果是这样,请参阅 更改日志 以获取完整列表。

我们希望您喜欢此版本,并期待 您的反馈