Conan 1.46:新增 XcodeToolchain 和 XcodeBuild 工具,改进 conf 系统,新增 Git 辅助工具。
我们很高兴地宣布 Conan 1.46 已经发布,并带来了一些重要的新功能和错误修复。我们通过添加新的 XcodeToolchain 生成器和 XcodeBuild 构建辅助工具改进了 Xcode 支持,这些工具补充了 Conan 1.42 中引入的 XcodeDeps 生成器。此外,Conan 配置系统 已经得到了显著改进,允许更强大的配置文件和配方中 Conan “conf” 的操作,并添加了 jinja2 模板语法支持。此外,我们还添加了新的 Git 辅助工具,以便在 export()
方法中直接使用以捕获 Git URL 和提交,并在 source()
方法中克隆和检出 Git 仓库。
新的 XcodeBuild 和 XcodeToolchain 工具
现在,您可以使用 XcodeToolchain 和 XcodeBuild 新辅助工具以及 XcodeDeps 在 Conan 配方中构建您的 Xcode 项目。让我们看看如何创建一个使用 Xcode 构建系统的包。假设您在 Xcode 中生成了一个简单的“hello world”库项目,您希望使用 Conan 打包它,并且它具有以下结构
├── HelloLibrary.xcodeproj
└── src
├── hello.cpp
└── hello.hpp
您可以使用类似于以下使用 XcodeBuild 构建库和 XcodeToolchain 将信息从 Conan 设置传递到 Xcode 构建系统的 conanfile.py
轻松地为该库创建 Conan 包
import os
from conan import ConanFile
from conan.tools.apple import XcodeBuild
from conan.tools.files import copy
class HelloLib(ConanFile):
name = "hello"
version = "1.0"
settings = "os", "compiler", "build_type", "arch"
generators = "XcodeToolchain"
exports_sources = "HelloLibrary.xcodeproj/*", "src/*"
def build(self):
xcode = XcodeBuild(self)
xcode.build("HelloLibrary.xcodeproj")
def package(self):
copy(self, "*/libhello.a", src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"),
keep_path=False)
copy(self, "src/hello.hpp", src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"),
keep_path=False)
def package_info(self):
self.cpp_info.libs = ["hello"]
在创建包之前,您必须将 Conan 生成的 .xcconfig 文件添加到 Xcode 项目中。让我们为 Release 和 Debug 配置生成它们
$ conan install . -s build_type=Release
$ conan install . -s build_type=Debug
将生成的 .xcconfig 文件添加到 Xcode 项目中,并在 Info/Configurations 部分中,为这两个配置选择 conan_config
现在,您可以为 Debug 和 Release 配置创建库
$ conan create . -s build_type=Debug
$ conan create . -s build_type=Release
当 Conan 执行 build()
方法时,XcodeBuild 辅助工具会调用 Xcode 构建系统来构建库。请查看文档以获取 XcodeToolchain、XcodeBuild 和 XcodeDeps 的完整参考。
改进的“conf”系统
Conan 配置系统中有一些改进
-
支持
global.conf
配置文件中的 jinja2 模板。例如,这对于将并行构建作业数设置为系统配置中定义的值很有用... # Using all the cores automatically tools.build:jobs={{os.cpu_count()}} ...
Python os
和 system
模块在模板上下文中可用。
- 支持配置中的不同数据类型。现在,您可以在设置配置值时使用 Python 数据类型。Conan 将使用 Python 内置的
eval()
函数解释这些值。您可以使用字符串、布尔值、整数、列表和字典。例如
# String
tools.microsoft.msbuild:verbosity=Diagnostic
# Boolean
tools.system.package_manager:sudo=True
# Integer
tools.microsoft.msbuild:max_cpu_count=2
# List of values
user.myconf.build:listvalue=["value1", "value2"]
# Dictionary
tools.microsoft.msbuildtoolchain:compile_options={"ExceptionHandling": "Async"}
- 配置文件中配置值的新运算符。您可以使用它们来追加 (
=+
)、追加 (+=
) 或重置 (=!
) 配置文件[conf]
部分中的配置值。
[settings]
...
[conf]
# Define the value => ["value1"]
user.myconf.build:listvalue=["value1"]
# Append the value ["value2"] => ["value1", "value2"]
user.myconf.build:listvalue+=["value2"]
# Prepend the value ["value0"] => ["value0", "value1", "value2"]
user.myconf.build:listvalue=+["value0"]
# Unset the value
user.myconf.build:listvalue=!
conf_info
对象中可用的新方法 用于在 配方 中操作配置值。您可以使用不同的方法获取、定义或操作配置值
import os
from conans import ConanFile
class Pkg(ConanFile):
name = "pkg"
def package_info(self):
# Setting values
self.conf_info.define("tools.microsoft.msbuild:verbosity", "Diagnostic")
# Getting values
self.conf_info.get("tools.microsoft.msbuild:verbosity") # == "Diagnostic"
# Modifying configuration list-like values
self.conf_info.append("user.myconf.build:listvalue", "value1")
有关可用方法的完整参考,请 查看 Conan 文档。
新的 conan.tools.scm.Git 工具
Conan 中有一个 新的工具可用,用于在 conan.tools.scm 模块
中管理 Git 仓库。使用此工具,配方可以添加与 scm 功能 提供的功能相同的功能,但更灵活和明确(请注意,scm 功能将在 Conan 2.0 中删除)。
让我们看看如何使用新辅助工具的示例。我们可以采用之前用于定义 Xcode 包的配方,该配方具有以下结构
├── conanfile.py
├── HelloLibrary.xcodeproj
└── src
├── hello.cpp
└── hello.hpp
我们将更改配方以从 Git 仓库获取源代码。新配方可能如下所示
import os
from conan import ConanFile
from conan.tools.apple import XcodeBuild
from conan.tools.files import copy
from conan.tools.scm import Git
from conan.tools.files import update_conandata
class HelloLib(ConanFile):
...
def layout(self):
self.folders.source = "."
def export(self):
git = Git(self, self.recipe_folder)
scm_url, scm_commit = git.get_url_and_commit()
# we store the current URL and commit in conandata.yml
update_conandata(self, {"sources": {"commit": scm_commit, "url": scm_url}})
def source(self):
# we recover the saved URL and commit from conandata.yml
git = Git(self)
sources = self.conan_data["sources"]
# get the sources from the URL and commit
git.clone(url=sources["url"], target=".")
git.checkout(commit=sources["commit"])
def build(self):
xcode = XcodeBuild(self)
xcode.build("HelloLibrary.xcodeproj")
...
最重要的部分定义在 conanfile 的 export()
和 source()
方法中
-
在
exports()
方法中,我们使用get_url_and_commit()
获取 Git 仓库的当前 提交 和 URL。然后,update_conandata()
辅助工具用于将此信息与配方一起保存到缓存中的conandata.yml
文件中。 -
在
source()
方法中,我们检索存储在conandata.yml
文件中的信息以克隆仓库 URL 并检出 提交。
如您所见,这种在 Conan 配方中与 Git 仓库交互的方式非常灵活和明确。如果您想查看 Git 工具的所有可用方法,请 查看 Conan 文档。
除了上面列出的内容外,还有一些小的错误修复,您可能希望阅读。如果是这样,请参阅 更改日志 以获取完整列表。
我们希望您喜欢此版本,并期待 您的反馈。