配方定义布局
当配方不在本地缓存中时,可以在其package_info()
方法中定义自定义布局,如下所示:
from conans import ConanFile
class Pkg(ConanFile):
settings = "build_type"
def package_info(self):
if not self.in_local_cache:
d = "include_%s" % self.settings.build_type
self.cpp_info.includedirs = [d.lower()]
当使用build_type=Debug
conan设置时,会将include目录映射到examples/features/editable/cmake/say/include_debug
,如果build_type=Release
,则将include目录映射到examples/features/editable/cmake/say/include_release
。 同样,其他目录(libdir,bindirs等)也可以使用任何逻辑进行自定义,这些逻辑对于不同的OS,构建系统等是不同的。
from conans import ConanFile
class Pkg(ConanFile):
settings = "os", "compiler", "arch", "build_type"
def package_info(self):
if not self.in_local_cache:
if self.settings.compiler == "Visual Studio":
# NOTE: Use the real layout used in your VS projects, this is just an example
self.cpp_info.libdirs = ["%s_%s" % (self.settings.build_type, self.settings.arch)]
例如,这会将库目录定义为examples/features/editable/cmake/say/Release_x86_64
。 这只是一个示例,VS使用的实际布局将有所不同。
布局文件
无需更改配方文件以匹配本地布局,而是可以在单独的文件中定义布局。 如果您有大量具有相同结构的库,那么这特别有用,因此您可以编写一次并将其用于多个软件包。
布局文件是ini文件,但是在解析它们之前,Conan使用Jinja2模板引擎传递设置,选项和当前参考对象,因此可以向文件添加逻辑:
[build_folder]
build/{{settings.build_type}}
[source_folder]
src
[includedirs]
src
[libdirs]
build/{{settings.build_type}}/lib
您可以查看 Jinja2 文档,以了解有关其强大语法的更多信息。
该文件可以使用包参考来定制特定包的逻辑:
[say/0.1@user/channel:build_folder]
{% if settings.compiler == "Visual Studio" %}
build
{% else %}
build/{{settings.build_type}}
{% endif %}
[build_folder]
build/{{settings.arch}}/{{settings.build_type}}
[source_folder]
src
[includedirs]
src
[libdirs]
build/{{settings.build_type}}/lib
[bindirs]
build/{{settings.build_type}}/bin
这种布局将为say
和其他处于可编辑模式的软件包定义src
include目录。 另外,build_folder
仅对say/0.1@user/channel
软件包具有条件。 根据编译器,它将使用特定的路径。
在每种情况下,将受可编辑模式影响的目录包括includeirs
,libdirs
,bindirs
,resdirs
,srcdirs
和builddirs
,所有这些都在cpp_info字典中声明。 该词典中的其余值将不会被修改。 因此,仍将使用在package_info()
中定义的库中的cflags
,defines
,库名。
默认情况下,所有文件夹路径都相对于可编辑包的conanfile.py所在的目录(这是用于创建链接的路径)的相对路径,尽管它们也允许绝对路径。
指定布局文件
布局文件在conan editable add
命令中指定,作为额外的参数:
$ cd examples/features/editable/cmake/say
$ conan editable add . say/0.1@user/channel --layout=layout_vs
首先将相对于当前目录查找该layout_vs
文件(路径也可以是绝对路径)。 如果找到,将使用它。 可以将这些布局添加到源存储库中,因此在克隆后总是很容易找到它们。
如果找不到相对于当前目录的指定布局,则将在.conan/layouts
文件夹的Conan缓存中查找该布局。 具有一个可以与团队共享并使用conan config install
安装的布局的单一定义,这非常方便。
如果未指定任何参数,conan editable add
命令将尝试使用本地缓存中的.conan/layouts/default布局。
您可以通过将不同的参数传递给conan editable add
的来切换布局文件。
评估顺序及优先级
了解有关布局定义的评估顺序和优先级非常重要:
- 将始终执行的第一件事是配方package_info()。这将定义标志,定义以及布局文件夹的一些值:includedirs,libdirs等。
- 如果定义了布局文件,无论是显式定义还是使用隐式
.conan/layouts/default
定义,conan都会根据其程序包引用查找匹配项。 - 如果找到匹配项,则是由于
[includedirs]
之类的全局定义,还是由于[pkg/version@user/channel:includedirs]
之类的匹配项,因此布局文件夹(includedirs,libdirs,resdirs,builddirs,bindirs)将是无效并由文件中定义的替换。 - 如果找到特定的匹配项,例如
[pkg/version@user/channel:includedirs]
,则应该也定义了其特定的[pkg/version@user/channel:libdirs]
等。找到匹配项后将不会应用。 - 如果找不到匹配项,则将遵循
package_info()
中定义的布局文件夹的原始值。 - 要使用的布局文件是在
conan editable add
时定义的。如果在**conan editable add**
之后添加.conan/layouts/default
文件,则将完全不使用该文件。