Skip to content

Commit

Permalink
Merge pull request conan-io#2141 from memsharded/feature/cmake_layout
Browse files Browse the repository at this point in the history
cmake_layout
  • Loading branch information
czoido authored Jun 30, 2021
2 parents b344db3 + 83c422a commit 173fa86
Showing 1 changed file with 78 additions and 0 deletions.
78 changes: 78 additions & 0 deletions reference/conanfile/tools/layout.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
conan.tools.layout
==================

.. warning::

This is an **experimental** feature subject to breaking changes in future releases.


Available since: `1.37.0 <https://github.com/conan-io/conan/releases>`_

LayoutPackager
Expand Down Expand Up @@ -36,3 +41,76 @@ Usage:
def package(self):
LayoutPackager(self).package()
Predefined layouts
------------------

There are some pre-defined common layouts, ready to be simply used in recipes.

For example, this would implement the standard CMake project layout:

.. code:: python
from conan.tools.layout import cmake_layout
def layout(self):
cmake_layout(self)
If you want to try it, use the ``conan new hello/0.1 -m v2_cmake`` template.

It is very important to note that this ``cmake_layout()`` is just calling the ``folders`` and ``cpp``
attributes described before:


.. code:: python
def cmake_layout(conanfile, generator=None):
gen = conanfile.conf["tools.cmake.cmaketoolchain:generator"] or generator
if gen:
multi = "Visual" in gen or "Xcode" in gen or "Multi-Config" in gen
elif conanfile.settings.compiler == "Visual Studio" or conanfile.settings.compiler == "msvc":
multi = True
else:
multi = False
conanfile.folders.source = "src"
if multi:
conanfile.folders.build = "build"
conanfile.folders.generators = "build/conan"
else:
build_type = str(conanfile.settings.build_type).lower()
conanfile.folders.build = "cmake-build-{}".format(build_type)
conanfile.folders.generators = os.path.join(conanfile.folders.build, "conan")
conanfile.cpp.source.includedirs = ["."]
if multi:
conanfile.cpp.build.libdirs = ["{}".format(conanfile.settings.build_type)]
else:
conanfile.cpp.build.libdirs = ["."]
First, it is important to notice that the layout depends on the CMake generator that will be used.
So if defined from ``[conf]``, that value will be used. If defined in recipe, then the recipe should
pass it as ``cmake_layout(self, cmake_generator)``.

The definitions of the folders is different if it is a multi-config generator (like Visual Studio or Xcode),
or a single-config generator (like Unix Makefiles). In the first case, the folder is the same irrespective
of the build type, and the build system will manage the different build types inside that folder. But
single-config generators like Unix Makefiles, must use a different folder for each different configuration
(as a different build_type Release/Debug).

Finally, the location where the libraries are created also depends. For multi-config, the respective libraries
will be located in a dedicated folder inside the build folder, while for single-config, the libraries will
be located directly in the build folder.

This helper defines a few things, for example that the source folder is called ``"src"``. This could be customized
without fully changing the layout:

def layout(self):
cmake_layout(self)
self.folders.source = "mysrcfolder"


Even if this pre-defined layout doesn't suit your specific projects layout, it is a good example how you could
implement your own logic (and probably put it in a common ``python_require`` if you are going to use it in multiple
packages).

0 comments on commit 173fa86

Please sign in to comment.