layout()¶
在 layout() 方法中,您可以调整 self.folders 和 self.cpp。
self.folders¶
self.folders.source (默认值为
""):指定源文件所在的子文件夹。source(self)和build(self)方法中的self.source_folder属性将使用此子文件夹。source(self)方法中的当前工作目录将包含此子文件夹。 export_sources 和 exports 源代码也将被复制到根源目录。它在运行 conan create 时用于缓存(相对于缓存源文件夹),以及在运行 conan build 时用于本地文件夹(相对于本地当前文件夹)。self.folders.build (默认值为
""):指定构建文件所在的子文件夹。self.build_folder属性和build(self)方法中的当前工作目录将使用此子文件夹。它在运行 conan create 时用于缓存(相对于缓存源文件夹),以及在运行 conan build 时用于本地文件夹(相对于本地当前文件夹)。self.folders.generators (默认值为
""):指定用于写入生成器和工具链文件的子文件夹。在缓存中,运行 conan create 时,此子文件夹将相对于根构建文件夹,而在运行 conan install 命令时,它将相对于当前工作目录。self.folders.root (默认值为
None):指定源文件、生成器等所在的父目录,特别是当conanfile.py位于分离的子目录中时。请查看 此示例,了解如何使用 self.folders.root。self.folders.subproject (默认值为
None):指定conanfile.py相对于项目根目录的子文件夹。这对于 具有多个子项目的布局特别有用。self.folders.build_folder_vars (默认值为
None):使用设置、选项和/或self.name和self.version来生成不同的构建文件夹和不同的 CMake 预设名称。
self.cpp¶
The layout() 方法允许声明 cpp_info 对象,不仅用于最终包(如使用 self.cpp_info 在 package_info(self) 方法中的经典方法),还用于 self.source_folder 和 self.build_folder。
在 self.cpp.build 和 self.cpp.source 中的 cpp_info 对象中的字段与 此处 描述的相同。组件也受支持。
用于声明包的消费者所需的所有信息:包含目录、库名称、库路径… 用于 可编辑包 和缓存中的常规包。
在 layout() 方法中可用三个对象
self.cpp.package:用于从 Conan 缓存使用的常规包。描述最终包的内容。与
package_info()中的self.cpp_info完全相同,但位于layout()方法中。self.cpp.source:用于“可编辑”包,以描述
self.source_folder下的工件。这些可以涵盖self.cpp.source.includedirs:用于指定开发时头文件所在的位置,例如典型的src文件夹,在打包到include包文件夹之前。self.cpp.source.libdirs和self.cpp.source.libs可以描述库提交到源代码控制的情况(希望是例外情况),因此它们不是构建结果的一部分,而是源代码的一部分。
self.cpp.build:用于“可编辑”包,以描述
self.build_folder下的工件。self.cpp.build.libdirs将表达构建库的位置,然后再打包。它们通常可以在像x64/Release或release64或类似的文件夹中找到。self.cpp.build.includedirs可以定义在构建时生成的头文件所在的位置,例如一些工具生成的头文件存根。
def layout(self):
...
self.folders.source = "src"
self.folders.build = "build"
# In the local folder (when the package is in development, or "editable") the artifacts can be found:
self.cpp.source.includedirs = ["my_includes"]
self.cpp.build.libdirs = ["lib/x86_64"]
self.cpp.build.libs = ["foo"]
# In the Conan cache, we packaged everything at the default standard directories, the library to link
# is "foo"
self.cpp.package.libs = ["foo"]
环境变量和配置¶
有些包可能在其 package_info() 方法中通过 self.buildenv_info、self.runenv_info 定义一些环境变量。其他包也可以使用 self.conf_info 将配置传递给其消费者。
只要这些环境变量或配置的值不需要使用 self.package_folder,这都不是问题。如果需要,那么它们的值对于“源”和“构建”布局将不正确。例如,这将在使用 editable 模式时被破坏
import os
from conan import ConanFile
class SayConan(ConanFile):
...
def package_info(self):
# This is BROKEN if we put this package in editable mode
self.runenv_info.define_path("MYDATA_PATH",
os.path.join(self.package_folder, "my/data/path"))
当包处于可编辑模式时,例如,self.package_folder 为 None,因为显然还没有包。解决方案是在 layout() 方法中定义它,就像可以定义 cpp_info 一样
from conan import ConanFile
class SayConan(ConanFile):
...
def layout(self):
# The final path will be relative to the self.source_folder
self.layouts.source.buildenv_info.define_path("MYDATA_PATH", "my/source/data/path")
# The final path will be relative to the self.build_folder
self.layouts.build.buildenv_info.define_path("MYDATA_PATH2", "my/build/data/path")
# The final path will be relative to the self.build_folder
self.layouts.build.conf_info.define_path("user.myconf:my_path", "my_conf_folder")
# Both for user defined confs, or in the case of tool-requires, also built-in confs
self.layouts.build.conf_info.define_path("tools.android:ndk_path", "local/path/to/ndk")
The layouts 对象包含 source、build 和 package 范围,每个范围包含一个 buildenv_info、runenv_info 和 conf_info 实例。