Skip to content

Commit 40fb238

Browse files
authored
Docs about 'profile:host' and 'profile:build' (conan-io#1629)
* about cross building * section about build requires * fix nesting * initial work on devtools * fix indent * talk about dev tools * build requirements * change example about conan version * update commands reference * note in profiles * remove TODOs * review * add a couple of graphs to the build requirements section * examples are not <= 1.24 * warning to important * add zlib to the host context
1 parent ac1bf8a commit 40fb238

20 files changed

+1076
-742
lines changed

devtools.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ With conan it is possible to package and deploy applications.
77
It is also possible that these applications are also dev-tools, like compilers (e.g. MinGW), or build systems (e.g. CMake).
88

99
This section describes how to package and run executables, and also how to package dev-tools.
10-
Also, how to apply applications like dev-tools or even libraries (like testing frameworks) to other packages to build them from sources:``build_requires``
10+
Also, how to apply applications like dev-tools or even libraries (like testing frameworks) to other packages to build them from sources: :ref:`build_requires`
1111

1212
.. toctree::
1313
:maxdepth: 2

devtools/build_requires.rst

+87-19
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Build requirements
44
==================
55

66
There are some requirements that don't feel natural to add to a package recipe. For example, imagine that you had a ``cmake/3.4`` package in
7-
Conan. Would you add it as a requirement to the ``ZLib`` package, so it will install cmake first in order to build ``Zlib``?
7+
Conan. Would you add it as a requirement to the ``zlib`` package, so it will install cmake first in order to build ``zlib``?
88

99
In short:
1010

@@ -20,12 +20,13 @@ In short:
2020

2121
To address these needs Conan implements ``build_requires``.
2222

23+
2324
Declaring build requirements
2425
----------------------------
2526

2627
Build requirements can be declared in profiles, like:
2728

28-
.. code-block:: text
29+
.. code-block:: ini
2930
:caption: my_profile
3031
3132
[build_requires]
@@ -74,6 +75,57 @@ attribute, the one inside the ``build_requirements()`` method will prevail.
7475
As a rule of thumb, downstream defined values always override upstream dependency values. If some build requirement is defined in the
7576
profile, it will overwrite the build requirements defined in package recipes that have the same package name.
7677

78+
79+
.. _build_requires_context:
80+
81+
Build and Host contexts
82+
-----------------------
83+
84+
Conan v1.24 differentiates between the ``build`` context and the ``host`` context in the dependency graph (read more about
85+
the meaning of ``host`` and ``build`` platforms in the :ref:`cross building <cross_building>` section) **when the user
86+
supplies two profiles** to the command line using the ``--profile:build`` and ``--profile:host`` arguments:
87+
88+
* The **host context** is populated with the root package (the one specified in the :command:`conan install` or :command:`conan create` command),
89+
all its requirements and the build requirements forced to be in the host context.
90+
* The **build context** contains the rest of build requirements and all of them in the profiles. This category typically
91+
includes all the :ref:`dev tools <create_installer_packages>` like CMake, compilers, linkers,...
92+
93+
94+
Build requirements declared in the recipes can be forced to stay in the host context, this is needed for testing libraries that will
95+
be linked to the generated library or other executable we want to deploy to the ``host`` platform, for example:
96+
97+
.. code-block:: python
98+
99+
class MyPkg(ConanFile):
100+
build_requires = "nasm/2.14" # 'build' context (nasm.exe will be available)
101+
102+
def build_requirements(self):
103+
self.build_requires("protobuf/3.6.1") # 'build' context (protoc.exe will be available)
104+
self.build_requires("gtest/0.1", force_host_context=True) # 'host' context (our library will link with it)
105+
106+
107+
.. image:: ../images/xbuild/conan-gtest_nasm.png
108+
:width: 500 px
109+
:align: center
110+
111+
112+
Take into account that the same package (executable or library) can appear two times in the graph, in the ``host`` and
113+
in the ``build`` context, with different package IDs. Conan will propagate the proper information to the consumers:
114+
115+
* Build requirements in the ``host`` context will propagate like any other requirement, all the ``cpp_info`` will be
116+
available in the ``deps_cpp_info["xxx"]`` object (``env_info`` and ``user_info`` won't be propagated).
117+
* Build requirements in the ``build`` context will propagate all the ``env_info`` and Conan will also populate the
118+
environment variables ``DYLD_LIBRARY_PATH``, ``LD_LIBRARY_PATH`` and ``PATH`` with the corresponding information from
119+
the ``cpp_info`` object. All these information will be available in the ``deps_cpp_info`` object.
120+
121+
122+
.. important::
123+
124+
If no ``--profile:build`` is provided, all build requirements will belong to the one and only context and they will share
125+
their dependencies with the libraries we are building. In this scenario all the build requirements propagate ``user_info``,
126+
``cpp_info`` and ``env_info`` to the consumer's ``deps_user_info``, ``deps_cpp_info`` and ``deps_env_info``.
127+
128+
77129
Properties of build requirements
78130
--------------------------------
79131

@@ -83,10 +135,8 @@ The behavior of ``build_requires`` is the same irrespective if they are defined
83135
they will not even be checked for existence.
84136
- Options and environment variables declared in the profile as well as in the command line will affect the build requirements for packages.
85137
In that way, you can define, for example, for the ``cmake/3.16.3`` package which CMake version will be installed.
86-
- Build requirements will be activated for matching packages via the ``deps_cpp_info`` and ``deps_env_info`` members. So, include
87-
directories, library names, compile flags (CFLAGS, CXXFLAGS, LINKFLAGS), sysroot, etc. will be applied from the build requirement's
88-
package ``self.cpp_info`` values. The same for ``self.env_info``: variables such as ``PATH``, ``PYTHONPATH``, and any other environment
89-
variables will be applied to the matching patterns and activated as environment variables.
138+
- Build requirements will be activated for matching packages, see the section above about :ref:`build requires context <build_requires_context>`
139+
to know the information that this package will propagate to its consumers.
90140
- Build requirements can also be transitive. They can declare their own requirements, both normal requirements and their own build
91141
requirements. Normal logic for dependency graph resolution applies, such as conflict resolution and dependency overriding.
92142
- Each matching pattern will produce a different dependency graph of build requirements. These graphs are cached so that they are only
@@ -97,21 +147,29 @@ The behavior of ``build_requires`` is the same irrespective if they are defined
97147
- Can also use version-ranges, like ``Tool/[>0.3]@user/channel``.
98148
- Build requirements are not listed in :command:`conan info` nor are represented in the graph (with :command:`conan info --graph`).
99149

100-
Testing libraries
101-
-----------------
102150

103-
One example of a build requirement could be a testing framework, which is implemented as a library. Let's call it ``mytest_framework``, an
104-
existing Conan package.
151+
Example: testing framework and build tool
152+
-----------------------------------------
153+
154+
One example of build requirement is a testing framework implemented as a library, another good example is a build tool used
155+
in the compile process. Let's call them ``mytest_framework`` and ``cmake_turbo``, and imagine we already have a package available
156+
for both of them.
105157

106158
Build requirements can be checked for existence (whether they've been applied) in the recipes, which can be useful for conditional logic in
107159
the recipes. In this example, we could have one recipe with the following ``build()`` method:
108160

109161
.. code-block:: python
110162
163+
def build_requirements(self):
164+
if self.options.enable_testing:
165+
self.build_requires("mytest_framework/0.1@user/channel", force_host_context=True)
166+
111167
def build(self):
112-
cmake = CMake(self)
113-
enable_testing = "mytest_framework" in self.deps_cpp_info.deps
114-
cmake.configure(defs={"ENABLE_TESTING": enable_testing})
168+
# Use our own 'cmake_turbo' if it is available
169+
use_cmake_turbo = "cmake_turbo" in self.deps_env_info.deps
170+
cmake_executable = "cmake_turbo" if use_cmake_turbo else None
171+
cmake = CMake(self, cmake_program=cmake_executable)
172+
cmake.configure(defs={"ENABLE_TESTING": self.options.enable_testing})
115173
cmake.build()
116174
if enable_testing:
117175
cmake.test()
@@ -135,22 +193,32 @@ And the package *CMakeLists.txt*:
135193
COMMAND example)
136194
endif()
137195
138-
This package recipe will not retrieve the ``mytest_framework`` nor build the tests, for normal installation:
196+
This package recipe won't retrieve the ``cmake_turbo`` package for normal installation:
139197

140198
.. code-block:: bash
141199
142200
$ conan install .
143201
144202
But if the following profile is defined:
145203

146-
.. code-block:: text
147-
:caption: mytest_profile
204+
.. code-block:: ini
205+
:caption: use_cmake_turbo_profile
148206
149207
[build_requires]
150-
mytest_framework/0.1@user/channel
208+
cmake_turbo/0.1@user/channel
209+
210+
then the install command will retrieve the ``cmake_turbo`` and use it:
211+
212+
.. code-block:: bash
213+
214+
$ conan install . --profile=use_cmake_turbo_profile
215+
151216
152-
then the install command will retrieve the ``mytest_framework``, build and run the tests:
217+
Although the previous line would work it is preferred to use the feature from Conan v1.24 and provide
218+
two profiles to the command line, that way the build requirements in the ``build`` context won't
219+
interfer with the ``host`` graph if they share common requirements (see :ref:`section about dev tools <create_installer_packages>`).
220+
It can also be needed if cross compiling (see :ref:`section about cross compiling <cross_building_build_requires>`).
153221

154222
.. code-block:: bash
155223
156-
$ conan install . --profile=mytest_profile
224+
$ conan install . --profile:host=use_cmake_turbo_profile --profile:build=build_machine

0 commit comments

Comments
 (0)