工作区文件¶
警告
此功能是新的孵化功能的一部分。这意味着它正在开发中,并正在寻求用户测试和反馈。有关更多信息,请参阅 孵化部分。
工作区由 conanws.yml
和/或 conanws.py
文件定义,这些文件将定义“根”工作区文件夹。
conanws.yml¶
工作区最基本实现是 conanws.yml
文件。它定义了工作区的 packages
(可编辑包)。例如,一个定义了 2 个 packages
的工作区 conanws.yml
可以是
packages:
- path: dep1
ref: dep1/0.1
- path: dep2
ref: dep2/0.1
此外,它也可以没有 ref
字段,让 Conan 从各自的 path/conanfile.py
中读取名称/版本。
packages:
- path: dep1
- path: dep2
conanws.py¶
一个 conanws.yml
可以通过更强大的 conanws.py
进行扩展,它遵循与 ConanFile
与其 conandata.yml
相同的关系。如果我们想动态定义 packages
,例如基于文件夹中是否存在某些 name.txt
和 version.txt
文件,则可以在 conanws.py
中这样定义包:
import os
from conan import Workspace
class MyWorkspace(Workspace):
def packages(self):
result = []
for f in os.listdir(self.folder):
if os.path.isdir(os.path.join(self.folder, f)):
with open(os.path.join(self.folder, f, "name.txt")) as fname:
name = fname.read().strip()
with open(os.path.join(self.folder, f, "version.txt")) as fversion:
version = fversion.read().strip()
result.append({"path": f, "ref": f"{name}/{version}"})
return result
还可以通过 Workspace.load_conanfile()
辅助函数在 set_name()
和 set_version()
方法中重用 conanfile.py
的逻辑。
import os
from conan import Workspace
class MyWorkspace(Workspace):
def packages(self):
result = []
for f in os.listdir(self.folder):
if os.path.isdir(os.path.join(self.folder, f)):
conanfile = self.load_conanfile(f)
result.append({"path": f, "ref": f"{conanfile.name}/{conanfile.version}"})
return result
conanws.py 超级构建选项¶
用于超级构建工作区文件的 conanws.py
可以通过两种不同的方式管理选项:
它可以定义自己的
options
,使用标准的conanfile.py
语法,这样生成的用于超级项目的conan_toolchain.cmake
就会使用这些输入。它可以收集工作区包的选项,使用
workspace_packages_options
,并以任何用户自定义的方式对其进行处理。
超级项目选项
一个 conanws.py
必须在 ConanFile
类中定义超级构建的选项,并在 generate()
方法中使用这些选项,就像通常用 conanfile.py
文件一样,类似于
from conan import ConanFile, Workspace
class MyWs(ConanFile):
settings = "arch", "build_type"
options = {"myoption": [1, 2, 3]}
def generate(self):
self.output.info(f"Generating with my option {self.options.myoption}!!!!")
class Ws(Workspace):
def root_conanfile(self):
return MyWs
然后,可以通过常规语法,通过配置文件或命令行来提供选项。
$ conan workspace super-install -of=build -o "*:myoption=1"
> conanws.py base project Conanfile: Generating with my option 1!!!!
请注意,这可能与工作区包中定义的 options
有重叠,因为对于超级项目,这些选项将被忽略,只有超级项目本身的选项才会被考虑用于生成 conan_toolchain.cmake
。例如,conanws.py
可以定义一个 shared
选项,如果希望 conan_toolchain.cmake
在定义诸如 -o "*:shared=True"
之类的东西时正确定义 BUILD_SHARED_LIBS
或不定义,因为当工作区包折叠到依赖图中以模拟超级项目时,工作区包中具有 shared
选项的信息将被丢弃。
包选项
第二种选择是收集已折叠的工作区包的 options
。请记住,在最终的依赖图中,工作区包不再被表示,因为它们不再是独立的包,而是当前超级构建的一部分。访问其选项信息的方法是通过 workspace_packages_options
,并且可以在 generate()
方法中使用这些信息在超级构建项目级别执行任何所需的动作。
因此,假设一个包含 dep/0.1
包的工作区,该包包含标准的 shared
选项,定义了以下超级构建 ConanFile
from conan import ConanFile, Workspace
class MyWs(ConanFile):
def generate(self):
for pkg, options in self.workspace_packages_options.items():
for k, v in options.items():
self.output.info(f"Generating with opt {pkg}:{k}={v}!!!!")
class Ws(Workspace):
def root_conanfile(self):
return MyWs
然后,当定义了工作区包选项时,工作区 ConanFile
可以收集它们。
$ conan workspace super-install -of=build -o "*:shared=True"
> conanws.py base project Conanfile: Generating with opt dep/0.1:shared=True!!!!!!!!
注意
实际上,工作区创建者有责任定义如何处理选项,无论是通过定义自己的选项还是收集工作区包的选项。请注意,无法自动将工作区包选项映射到超级项目,因为选项是按包定义的。两个不同的包可能具有不同的 shared=True
和 shared=False
值。此外,通常情况下,对生成的工具链文件的影响是自定义的,并在每个包的 generate()
方法中实现。这种影响是编程性的(非声明性的),将所有这些影响聚合到单个工具链中将极其困难。
另请参阅
阅读 工作区教程 部分。