新的 1.20 版本包含了许多有用的功能和改进。以下是该版本的主要亮点!

重用依赖项中的 CMake 宏

遵循先前版本的路线,我们继续追求与构建系统的透明集成,在本例中,我们改进了 cpp_info 模型,以在 CMake 的情况下包含构建系统文件或构建模块。

此新功能允许以透明的方式在使用者端重用 CMake 宏。当库以函数或宏的形式向使用者提供某种帮助程序以创建或链接目标或使用内置工具时,这将非常有用。

我们使用 pybind11 库 进行了一些测试。此库提供了一个 CMake 宏,可帮助使用者创建和链接其目标:pybin11_add_module()

推荐的使用库方法可以在(库文档)[https://pybind11.readthedocs.io/en/stable/compiling.html#building-with-cmake] 中找到,如下所示

cmake_minimum_required(VERSION 2.8.12)
project(example)

add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)

使用构建模块,现在可以像这样将重用该宏所需的包含在 cpp_info 模型中

conan-pybind11/conanfile.py

...
    def package_info(self):
        base_path = os.path.join("share", "cmake", "pybind11")
        self.cpp_info.builddirs = [base_path]
        self.cpp_info.build_modules = [
            os.path.join(base_path, "pybind11Tools.cmake"),
            os.path.join(base_path, "FindPythonLibsNew.cmake")
        ]
...

这些构建模块将包含在 cmake_find_packagecmake_find_package_multi 生成器生成的查找和配置文件中,因此可以像这样透明地使用它们

cmake_minimum_required(VERSION 2.8.12)
project(example)

find_package(pybind11 REQUIRED)
pybind11_add_module(example example.cpp)

pybind11 配方以及使用者 CMakeLists.txt 中所需更改的完整差异可以在 此处 找到。

请记住检查 文档 以获取有关此功能的完整详细信息。

支持系统库

cpp_info 模型进行的另一个有用的改进是系统库。通常,库要求使用者链接到系统库,例如 pthreadmWs2_32

这通常通过将这些系统库附加到 cpp_info.libs 来完成,因此将包库与系统库混合在一起。

一些生成器能够智能地检测包库和系统库,但它们没有对后者进行任何特殊处理。

通过使用 cpp_info.system_libs,生成器现在能够改进目标生成,并将它们作为 INTERFACE_LINK_LIBRARIES 链接到所有 CMake 生成器中。

您可以在 文档 中阅读有关系统库的更多信息。

兼容包

在我们调查支持新编译器时,我们意识到在集成 Intel C++ 编译器时,由于 Conan 中的包 ID 模型限制,无法与使用基本编译器构建的包兼容。

在此版本之前,唯一可能的兼容性是使用相同的设置输入创建相同的包(唯一的包 ID)。这意味着,如果您想为 GCC 4.7、4.8 和 4.9 建模包的兼容性,唯一可能的方法是为所有这些包定义一个唯一的 ID,并使用一个固定的版本值(请参阅 此处 的示例)。但是,在混合 Intel C++ 编译器和 Visual Studio 以及 GCC 的包时,情况并非如此。

此新功能允许包创建者使用完全不同的包 ID 定义兼容包。兼容包列表可以在 package_id() 方法中定义,例如,您可以将 GCC 4.9 和 4.7 定义为使用 GCC 4.9 作为输入的使用者的兼容包。这里的区别在于,现在,如果您应用 GCC 4.7 的配置文件,您将生成 4.7 的包,如果您应用 4.8 的配置文件,您将获得 4.8 的包 ID,但是如果您没有生成 4.9 的包并且您作为使用者需要此包,您将获得 4.8 或 4.7 的二进制文件(如果可用)。

...
    def package_id(self):
        if self.settings.compiler == "gcc" and self.settings.compiler.version == "4.9":
            for version in ("4.8", "4.7"):
                compatible_pkg = CompatiblePackage(self)
                compatible_pkg.settings.compiler.version = version
                self.compatible_packages.append(compatible_pkg)
...

当找不到包但存在兼容包时,Conan 将选择可用的包并显示以下消息

$ conan install lib/0.1@us/ch
...
Main binary package '2ef6f6c768dd0f332dc252b72c30dee116632302' missing.
Using compatible package '1151fe341e6b310f7645a76b4d3d524342835acc'
...
    lib/0.1@us/ch:1151fe341e6b310f7645a76b4d3d524342835acc - Cache

请注意,这意味着这些包在所有方面都是兼容的,因为 Conan 将把它们视为完全可互换的。

此功能已作为实验性功能引入,并且接口可能会在将来的版本中更改,但您可以查看 文档 和示例以了解更多信息。

动态设置包的名称或版本

现在,您可以使用 set_name()set_version() 动态定义配方 的名称和版本。例如,如果您想从 CMakeLists.txt 中提取版本

class HelloConan(ConanFile):
        name = "Hello"

        def set_version(self):
            content = load("CMakeLists.txt")
            version = re.search(b"set\(MY_LIBRARY_VERSION (.*)\)", content).group(1)
            self.version = version.strip()

仅在这些方法内部允许设置 self.nameself.version,并且信息将存储在配方元数据中,这意味着这些方法仅在将配方导出到缓存时使用。

SCM 改进

我们有一些针对 SCM 功能 的优化正在等待,现在已在此版本中解决。

现在,当使用未提交的更改创建包时,配方中的 auto 字段不会自动替换。这将包标记为,并防止将配方上传到远程服务器而没有未提交的更改,但允许开发人员继续使用这些更改测试包创建。

但是,您仍然可以使用 --ignore-dirty 标志强制 Conan 在导出、创建和导出-pkg 命令中替换 auto 字段,或使用 conan upload --force 强制上传包。

请参阅此功能的 完整文档

Clang 10 和 GCC 7.4 支持

Conan 1.20 添加了对 Clang 10 的支持,并在默认的 settings.yml 文件中包含了 GCC 的特定 7.4 版本。

请记住,gcc 编译器中的次要版本值被认为是兼容的,并且 Conan 默认情况下只使用 GCC 7 作为配置文件中的版本值,除非在配置文件中明确指定。

从锁定文件生成 Artifactory 构建信息

为了改进 Conan 包的持续集成流程,我们发布了一种新方法来使用 构建信息 JSON 格式 为 Artifactory 生成包的构建信息。此方法不再使用 Conan 跟踪文件来收集信息,而是使用 锁定文件

新的实验性功能 可通过 conan_build_info 命令使用,我们相信它将有助于研究和开发如何为使用 Conan 的 C/C++ 项目实现高效、稳健和完整的 CI 流程。



最后,请查看 更改日志 中的功能和修复的完整列表,如有任何错误或反馈,请随时在我们的 问题跟踪器 中提交新问题。