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_folderattribute 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_folderattribute 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.pyis 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.pyis relative to the project root. This is particularly useful for layouts with multiple subprojectsself.folders.build_folder_vars (Defaulted to
None): Use settings and options 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 typicalsrcfolder, before being packaged in theincludepackage folder.self.cpp.source.libdirsandself.cpp.source.libscould 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.libdirswill express the location of the built libraries before being packaged. They can often be found in a folder likex64/Release, orrelease64or similar.self.cpp.build.includedirscan 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 layout
here.
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.