Conan 1.37:ConanCenter 新默认 URL、新的 layout() 方法、新的 Bazel 集成、新的 build_policy=never、新的 --build-require 标记
Conan 1.37 带来了几个重要的新功能。首先,Conan 客户端附带的默认 remotes.txt 文件中添加了 Conan Center 的新 URL。此版本还包括一个名为 layout()
的主要新方法,用于 conanfile.py,以及一些用于与 Bazel 构建系统集成的新的类。此外,还新增了一个名为 never
的 build_policy
,以及一个名为 --build-require
的新标记,可与 conan install
和 conan 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 构建系统 添加了以下两个新的生成器,它们在本质上类似于 CMakeDeps
和 CMakeToolchain
生成器。
BazelDeps
BazelToolchain
我们还添加了一个名为 Bazel
的标准构建帮助器类,以使从 CLI 调用 Bazel 减少错误(类似于 CMake
和 MSBuild
构建帮助器)。
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 install
和 conan create
命令现在支持一个额外的标记:--build-require
。发现需要此标记是由于用于交叉构建的新 build
和 host
“上下文”导致的。它的用例并非最常见的工作流,因此我们将尝试在此澄清其用途。
在 Conan 中构建工具作为 build_requires
的最常见方法是在 conanfile
或 profile
中将其列出。在这些情况下,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
)。
除了上面列出的项目之外,还有很多相当有影响的错误修复,您可能希望了解。如果是这样,请参阅 更改日志 以获取完整列表。
我们希望您喜欢此版本,并期待 您的反馈。