Skip to content

Commit 900bc27

Browse files
memshardedSSE4AbrilRBSczoido
authored
[develop2] reference methods (#2953)
* [develop2] reference methods * Update reference/conanfile/methods/build.rst Co-authored-by: SSE4 <[email protected]> * Update reference/conanfile/methods/compatibility.rst Co-authored-by: SSE4 <[email protected]> * Update reference/conanfile/methods/compatibility.rst Co-authored-by: SSE4 <[email protected]> * Update reference/conanfile/methods/export_sources.rst Co-authored-by: SSE4 <[email protected]> * review * wip * wip * wip * Add grammar review * wip * wip * Update configure.rst * Update reference/conanfile/methods/source.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * Update reference/conanfile/methods/source.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * Update reference/conanfile/methods/source.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * Update reference/conanfile/methods/source.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * Update reference/conanfile/methods/system_requirements.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * Update reference/conanfile/methods/source.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * Update reference/conanfile/methods/system_requirements.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * Update reference/conanfile/methods/validate.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * Update reference/conanfile/methods/validate.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * Update reference/conanfile/methods/system_requirements.rst Co-authored-by: Rubén Rincón Blanco <[email protected]> * fix command * wip * added references to tutorial * cross referencing * fix ref --------- Co-authored-by: SSE4 <[email protected]> Co-authored-by: Rubén Rincón Blanco <[email protected]> Co-authored-by: Rubén Rincón Blanco <[email protected]> Co-authored-by: czoido <[email protected]>
1 parent 3f537ec commit 900bc27

32 files changed

+1640
-162
lines changed

reference/conanfile/methods.rst

+51-150
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,56 @@
1-
.. spelling::
2-
3-
ing
4-
ver
5-
6-
.. _conan_conanfile_methods:
1+
.. _reference_conanfile_methods:
72

83
Methods
94
=======
105

116

12-
requirements()
13-
--------------
14-
15-
Requirement traits
16-
^^^^^^^^^^^^^^^^^^
17-
18-
Traits are properties of a requires clause. They determine how various parts of a
19-
dependency are treated and propagated by Conan. Values for traits are usually computed by
20-
Conan based on dependency's :ref:`reference_conanfile_attributes_package_type`, but can
21-
also be specified manually.
22-
23-
A good introduction to traits is provided in the `Advanced Dependencies Model in Conan 2.0
24-
<https://youtu.be/kKGglzm5ous>`_ presentation.
25-
26-
In the example below ``headers`` and ``libs`` are traits.
27-
28-
.. code-block:: python
29-
30-
self.requires("math/1.0", headers=True, libs=True)
31-
32-
33-
headers
34-
~~~~~~~
35-
36-
Indicates that there are headers that are going to be ``#included`` from this package at
37-
compile time. The dependency will be in the host context.
38-
39-
libs
40-
~~~~
41-
42-
The dependency contains some library or artifact that will be used at link time of the
43-
consumer. This trait will typically be ``True`` for direct shared and static libraries,
44-
but could be false for indirect static libraries that are consumed via a shared library.
45-
The dependency will be in the host context.
46-
47-
build
48-
~~~~~
49-
50-
This dependency is a build tool, an application or executable, like cmake, that is used
51-
exclusively at build time. It is not linked/embedded into binaries, and will be in the
52-
build context.
53-
54-
run
55-
~~~
56-
57-
This dependency contains some executables, either apps or shared libraries that need to be
58-
available to execute (typically in the path, or other system env-vars). This trait can be
59-
``True`` for ``build=False``, in that case, the package will contain some executables that
60-
can run in the host system when installing it, typically like an end-user application.
61-
This trait can be ``True`` for ``build=True``, the package will contain executables that
62-
will run in the build context, typically while being used to build other packages.
63-
64-
visible
65-
~~~~~~~
66-
67-
This ``require`` will be propagated downstream, even if it doesn't propagate ``headers``,
68-
``libs`` or ``run`` traits. Requirements that propagate downstream can cause version
69-
conflicts. This is typically ``True``, because in most cases, having 2 different versions of
70-
the same library in the same dependency graph is at least complicated, if not directly
71-
violating ODR or causing linking errors. It can be set to ``False`` in advanced scenarios,
72-
when we want to use different versions of the same package during the build.
73-
74-
transitive_headers
75-
~~~~~~~~~~~~~~~~~~
76-
77-
If ``True`` the headers of the dependency will be visible downstream.
78-
79-
transitive_libs
80-
~~~~~~~~~~~~~~~
81-
82-
If ``True`` the libraries to link with of the dependency will be visible downstream.
83-
84-
test
85-
~~~~
86-
87-
This requirement is a test library or framework, like Catch2 or gtest. It is mostly a
88-
library that needs to be included and linked, but that will not be propagated downstream.
89-
90-
package_id_mode
91-
~~~~~~~~~~~~~~~
92-
93-
If the recipe wants to specify how the dependency version affects the current package
94-
``package_id``, can be directly specified here.
95-
96-
While it could be also done in the ``package_id()`` method, it seems simpler to be able to
97-
specify it in the ``requires`` while avoiding some ambiguities.
98-
99-
.. code-block:: python
100-
101-
# We set the package_id_mode so it is part of the package_id
102-
self.tool_requires("tool/1.1.1", package_id_mode="minor_mode")
103-
104-
Which would be equivalent to:
105-
106-
.. code-block:: python
107-
108-
def package_id(self):
109-
self.info.requires["tool"].minor_mode()
110-
111-
force
112-
~~~~~
113-
114-
This ``requires`` will force its version in the dependency graph upstream, overriding
115-
other existing versions even of transitive dependencies, and also solving potential
116-
existing conflicts.
117-
118-
override
119-
~~~~~~~~
120-
121-
The same as the ``force`` trait, but not adding a ``direct`` dependency. If there is no
122-
transitive dependency to override, this ``require`` will be discarded. This trait only
123-
exists at the time of defining a ``requires``, but it will not exist as an actual
124-
``requires`` once the graph is fully evaluated
125-
126-
direct
127-
~~~~~~
128-
129-
If the dependency is a direct one, that is, it has explicitly been declared by the current
130-
recipe, or if it is a transitive one.
131-
132-
133-
validate_build()
134-
----------------
135-
136-
The ``validate_build()`` method is used to verify if a configuration is valid for building a package. It is different
137-
from the ``validate()`` method that checks if the binary package is "impossible" or invalid for a given configuration.
138-
139-
The ``validate_build()`` method has to use always the ``self.settings`` and ``self.options``:
140-
141-
.. code-block:: python
142-
143-
from conan import ConanFile
144-
from conan.errors import ConanInvalidConfiguration
145-
class myConan(ConanFile):
146-
name = "foo"
147-
version = "1.0"
148-
settings = "os", "arch", "compiler"
149-
def package_id(self):
150-
# For this package, it doesn't matter the compiler used for the binary package
151-
del self.info.settings.compiler
152-
def validate_build(self):
153-
# But we know this cannot be build with "gcc"
154-
if self.settings.compiler == "gcc":
155-
raise ConanInvalidConfiguration("This doesn't build in GCC")
7+
.. toctree::
8+
:maxdepth: 1
9+
:hidden:
10+
11+
methods/build
12+
methods/build_id
13+
methods/build_requirements
14+
methods/compatibility
15+
methods/configure
16+
methods/config_options
17+
methods/export
18+
methods/export_sources
19+
methods/generate
20+
methods/init
21+
methods/layout
22+
methods/package
23+
methods/package_id
24+
methods/package_info
25+
methods/requirements
26+
methods/set_name
27+
methods/set_version
28+
methods/source
29+
methods/system_requirements
30+
methods/test
31+
methods/validate
32+
methods/validate_build
33+
34+
35+
- :doc:`build() <methods/build>`: Contains the build instructions to build a package from source
36+
- :doc:`build_id() <methods/build_id>`: Allows reusing the same build to create different package binaries
37+
- :doc:`build_requirements() <methods/build_requirements>`: Defines ``tool_requires`` and ``test_requires``
38+
- :doc:`compatibility() <methods/compatibility>`: Defines binary compatibility at the recipe level
39+
- :doc:`configure() <methods/configure>`: Allows configuring settings and options while computing dependencies
40+
- :doc:`config_options() <methods/config_options>`: Configure options while computing dependency graph
41+
- :doc:`export() <methods/export>`: Copies files that are part of the recipe
42+
- :doc:`export_sources() <methods/export_sources>`: Copies files that are part of the recipe sources
43+
- :doc:`generate() <methods/generate>`: Generates the files that are necessary for building the package
44+
- :doc:`init() <methods/init>`: Special initialization of recipe when extending from ``python_requires``
45+
- :doc:`layout() <methods/layout>`: Defines the relative project layout, source folders, build folders, etc.
46+
- :doc:`package() <methods/package>`: Copies files from build folder to the package folder.
47+
- :doc:`package_id() <methods/package_id>`: Defines special logic for computing the binary ``package_id`` identifier
48+
- :doc:`package_info() <methods/package_info>`: Provide information for consumers of this package about libraries, folders, etc.
49+
- :doc:`requirements() <methods/requirements>`: Define the dependencies of the package
50+
- :doc:`set_name() <methods/set_name>`: Dynamically define the name of a package
51+
- :doc:`set_version() <methods/set_version>`: Dynamically define the version of a package.
52+
- :doc:`source() <methods/source>`: Define the dependencies of the package
53+
- :doc:`system_requirements() <methods/system_requirements>`: Call system package managers like Apt to install system packages
54+
- :doc:`test() <methods/test>`: Run some simple package test (exclusive of ``test_package``)
55+
- :doc:`validate() <methods/validate>`: Define if the current package is invalid (cannot work) with the current configuration.
56+
- :doc:`validate_build() <methods/validate_build>`: Define if the current package cannot be created with the current configuration.

reference/conanfile/methods/build.rst

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
.. _reference_conanfile_methods_build:
2+
3+
build()
4+
=======
5+
6+
The ``build()`` method is used to define the build from source of the package. In practice this means calling some build system, which could be done explicitly or using any of the build helpers provided by Conan:
7+
8+
9+
.. code-block:: python
10+
11+
from conan.tools.cmake import CMake
12+
13+
class Pkg(ConanFile):
14+
15+
def build(self):
16+
# Either using some of the Conan built-in helpers
17+
cmake = CMake(self)
18+
cmake.configure() # equivalent to self.run("cmake . <other args>")
19+
cmake.build() # equivalent to self.run("cmake --build . <other args>")
20+
cmake.test() # equivalent to self.run("cmake --target=RUN_TESTS")
21+
22+
# Or it could run your own build system or scripts
23+
self.run("mybuildsystem . --configure")
24+
self.run("mybuildsystem . --build")
25+
26+
27+
For more information about the existing built-in build system integrations, visit :ref:`conan_tools`.
28+
29+
The ``build()`` method should be as simple as possible, just wrapping the command line invocations
30+
that a developer would do in the simplest possible way. The ``generate()`` method is the one responsible
31+
for preparing the build, creating toolchain files, CMake presets, or any other files which are necessary
32+
so developers could easily call the build system by hand. This allows for much better integrations with IDEs and
33+
improves the developer experience. The result is that in practice the ``build()`` method should be relatively simple.
34+
35+
The ``build()`` method is the right place to build and run unit tests, before packaging, and raising errors if those tests fail, interrupting the process, and not even packaging the final binaries.
36+
The built-in helpers will skip the unit tests if the ``tools.build:skip_test`` configuration is defined. For custom integrations, it is expected that the method checks this ``conf`` value in order to skip building and running tests, which can be useful for some CI scenarios.
37+
38+
The ``build()`` method runs once per unique configuration, so if there are some source operations like applying patches that are done conditionally to different configurations, they could be also applied in the
39+
``build()`` method, before the actual build. It is important to note that in this case the ``no_copy_source`` attribute cannot be set to ``True``.
40+
41+
42+
43+
.. note::
44+
45+
**Best practices**
46+
47+
- The ``build()`` method should be as simple as possible, the heavy lifting of preparing the build should happen in the ``generate()`` method in order to achieve a good developer experience that can easily build locally with just ``conan install .``, plus directly calling the build system or opening their IDE.
48+
49+
50+
.. seealso::
51+
52+
Follow the :ref:`tutorial about building packages<tutorial_creating_build>` for more information about building from sources.
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
.. _reference_conanfile_methods_build_id:
2+
3+
build_id()
4+
==========
5+
6+
The ``build_id()`` method allows to re-use the same build to create different binary packages in the cache,
7+
potentially saving build time as it can avoid some unnecessary re-builds. It is therefore an optimization method.
8+
9+
In the general case, there is one build folder for each binary package, with the exact same ``package_id`` of the package. However this behavior
10+
can be changed, there are a couple of scenarios that this might be useful:
11+
12+
- The package build scripts generate several different configurations at once (like both debug and release artifacts) in the same run, without the possibility of building each configuration separately.
13+
- The package build scripts generate one binary configuration, but different artifacts that can be packaged separately. For example if there are some test executables, you might want to create two packages: one just containing the library for general usage, and another one also containing the tests (for compliance, later reproducibility, debugging, etc).
14+
15+
In the first case, we could for example write:
16+
17+
.. code-block:: python
18+
19+
settings = "os", "compiler", "arch", "build_type"
20+
21+
def build_id(self):
22+
self.info_build.settings.build_type = "Any"
23+
24+
This recipe will generate a final different package with a different ``package_id`` for debug and release configurations. But as the ``build_id()`` will generate the
25+
same ``build_id`` for any ``build_type``, then just one folder and one ``build()`` will be done, building both debug and release artifacts,
26+
and then the ``package()`` method will be called for each configuration, and it should package the artifacts conditionally to the ``self.settings.build_type`` value. Different builds will still be
27+
executed if using different compilers or architectures.
28+
29+
Other information like custom package options can also be changed:
30+
31+
.. code-block:: python
32+
33+
def build_id(self):
34+
self.info_build.options.myoption = 'MyValue' # any value possible
35+
self.info_build.options.fullsource = 'Always'
36+
37+
If the ``build_id()`` method does not modify the ``info_build`` data, and it still produces a different id than
38+
the ``package_id``, then the standard behavior will be applied. Consider the following:
39+
40+
.. code-block:: python
41+
42+
settings = "os", "compiler", "arch", "build_type"
43+
44+
def build_id(self):
45+
if self.settings.os == "Windows":
46+
self.info_build.settings.build_type = "Any"
47+
48+
This will only produce a different ``build_id`` if the package is for Windows, thus running ``build()`` just
49+
once for all ``build_type`` values. The behavior
50+
in any other OS will be the standard one, as if the ``build_id()`` method was not defined, running
51+
one different ``build()`` for each ``build_type``.
52+
53+
54+
.. note::
55+
56+
**Best practices**
57+
58+
Conan strongly recommends to use one package binary with its own ``package_id`` for each different configuration. The goal of the ``build_id()`` method is to deal with legacy build scripts that cannot easily be changed to do the build of one configuration each time.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
.. _reference_conanfile_methods_build_requirements:
2+
3+
build_requirements()
4+
====================
5+
6+
The ``build_requirements()`` method is functionally equivalent to the ``requirements()`` one, it is executed just after it. It is not strictly necessary, in theory everything that is inside this method, could be done in the end of the ``requirements()`` one. Still, ``build_requirements()`` is good for having a dedicated place to define ``tool_requires`` and ``test_requires``:
7+
8+
.. code-block:: python
9+
10+
def build_requirements(self):
11+
self.tool_requires("cmake/3.23.5")
12+
self.test_requires("gtest/1.13.0")
13+
14+
15+
For simple cases the attribute syntax can be enough, like ``tool_requires = "cmake/3.23.5"`` and ``test_requires = "gtest/1.13.0"``. The method form can be necessary for conditional or parameterized requirements.
16+
17+
The ``tool_requires`` and ``test_requires`` methods are just a specialized instance of ``requires`` with some predefined trait values. See the :ref:`requires() reference<reference_conanfile_methods_requirements>` for more information about traits.
18+
19+
tool_requires
20+
-------------
21+
22+
The ``tool_requires`` is equivalent to ``requires()`` with the following traits:
23+
24+
- ``build=True``. This dependency is in the "build" context, being necessary at build time, but not at application runtime, and will receive the "build" profile and configuration.
25+
- ``visible=False``. The dependency to a tool requirement is not propagated downstream. For example, one package can call ``tool_requires("cmake/3.23.5")``, but that doesn't mean that the consumer packages also use ``cmake``, they could even use a different build system, or a different version, without causing conflicts.
26+
- ``run=True``. This dependency has some executables or runtime that needs to be ran at build time.
27+
- ``headers=False`` A tool requirement does not have headers.
28+
- ``libs=False``: A tool requirement does not have libraries to be linked by the consumer (if it had libraries they would be in the "build" context and could be incompatible with the "host" context of the consumer package).
29+
30+
test_requires
31+
-------------
32+
33+
The ``test_requires`` is equivalent to ``requires()`` with the following traits:
34+
35+
- ``test=True``. This dependency is a "test" dependency, existing in the "host" context, but not aiming to be part of the final product.
36+
- ``visible=False``. The dependency to a test requirement is not propagated downstream. For example, one package can call ``self.test_requires("gtest/1.13.0")``, but that doesn't mean that the consumer packages also use ``gtest``, they could even use a different test framework, or the same ``gtest`` with a different version, without causing conflicts.
37+
38+
39+
It is possible to further modify individual traits of ``tool_requires()`` and ``test_requires()`` if necessary, for example:
40+
41+
.. code-block:: python
42+
43+
def build_requirements(self):
44+
self.tool_requires("cmake/3.23.5", options={"shared": False})
45+
46+
47+
.. note::
48+
49+
**Best practices**
50+
51+
- ``tool_requires`` are exclusively for build time **tools**, not for libraries that would be included and linked into the consumer package. For libraries with some special characteristics, use a ``requires()`` with custom trait values.
52+
- The ``self.test_requires()`` and ``self.tool_requires()`` methods should exclusively be used in the ``build_requirements()`` method, with the only possible exception being the ``requirements()`` method. Using them in any other method is forbidden. To access information about dependencies when necessary in some methods, the :ref:`self.dependencies<conan_conanfile_model_dependencies>` attribute should be used.
53+
54+
55+
.. seealso::
56+
57+
- Follow the :ref:`tutorial about consuming Conan packages as tools<consuming_packages_tool_requires>`.
58+
- Read the :ref:`tutorial about creating tool_requires packages<tutorial_other_tool_requires_packages>`.

0 commit comments

Comments
 (0)