layout()¶
In the layout() method you can adjust self.folders
and self.cpp
.
self.folders¶
self.folders.source (Defaulted to
""
): Specifies a subfolder where the sources are. Theself.source_folder
attribute inside thesource(self)
andbuild(self)
methods will be set with this subfolder. The current working directory in thesource(self)
method will include this subfolder. The export_sources and exports sources will also be copied to the root source directory. It is used in the cache when running conan create (relative to the cache source folder) as well as in a local folder when running conan build (relative to the local current folder).self.folders.build (Defaulted to
""
): Specifies a subfolder where the files from the build are. Theself.build_folder
attribute and the current working directory inside thebuild(self)
method will be set with this subfolder. It is used in the cache when running conan create (relative to the cache source folder) as well as in a local folder when running conan build (relative to the local current folder).self.folders.generators (Defaulted to
""
): Specifies a subfolder in which to write the files from the generators and the toolchains. In the cache, when running conan create, this subfolder will be relative to the root build folder and when running the conan install command it will be relative to the current working directory.self.folders.root (Defaulted to
None
): Specifies a parent directory where the sources, generators, etc., are located specifically when theconanfile.py
is located in a separated subdirectory. Check this example on how to use self.folders.root.self.folders.subproject (Defaulted to
None
): Specifies a subfolder where theconanfile.py
is relative to the project root. This is particularly useful for layouts with multiple subprojectsself.folders.build_folder_vars (Defaulted to
None
): Use settings, options and/orself.name
andself.version
to produce a different build folder and different CMake presets names.
self.cpp¶
The layout()
method allows to declare cpp_info
objects not only for the final
package (like the classic approach with the self.cpp_info
in the
package_info(self)
method) but for the self.source_folder
and
self.build_folder
.
The fields of the cpp_info
objects at self.cpp.build
and self.cpp.source
are the
same described here. Components are also supported.
Properties to declare all the information needed by the consumers of a package: include directories, library names, library paths… Used both for editable packages and regular packages in the cache.
There are three objects available in the layout()
method:
self.cpp.package: For a regular package being used from the Conan cache. Describes the contents of the final package. Exactly the same as in the
package_info()
self.cpp_info
, but in thelayout()
method.self.cpp.source: For “editable” packages, to describe the artifacts under
self.source_folder
. These can cover:self.cpp.source.includedirs
: To specify where the headers are at development time, like the typicalsrc
folder, before being packaged in theinclude
package folder.self.cpp.source.libdirs
andself.cpp.source.libs
could describe the case where libraries are committed to source control (hopefully exceptional case), so they are not part of the build results, but part of the source.
self.cpp.build: For “editable” packages, to describe the artifacts under
self.build_folder
.self.cpp.build.libdirs
will express the location of the built libraries before being packaged. They can often be found in a folder likex64/Release
, orrelease64
or similar.self.cpp.build.includedirs
can define the location of headers that are generated at build time, like headers stubs generated by some tools.
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"]
See also
Read more about the usage of the
layout()
in this tutorial and Conan package layouthere.
Environment variables and configuration¶
There are some packages that might define some environment variables in their
package_info()
method via self.buildenv_info
, self.runenv_info
. Other
packages can also use self.conf_info
to pass configuration to their consumers.
This is not an issue as long as the value of those environment variables or configuration
do not require using the self.package_folder
. If they do, then their values will
not be correct for the “source” and “build” layouts. Something like this will be broken
when used in editable
mode:
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"))
When the package is in editable mode, for example, self.package_folder
is None
, as
obviously there is no package yet.
The solution is to define it in the layout()
method, in the same way the cpp_info
can
be defined there:
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("MYCONF", "my_conf_folder")
The layouts
object contains source
, build
and package
scopes, and each one contains
one instance of buildenv_info
, runenv_info
and conf_info
.