-
Notifications
You must be signed in to change notification settings - Fork 364
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[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]>
- Loading branch information
1 parent
3f537ec
commit 900bc27
Showing
32 changed files
with
1,640 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,155 +1,56 @@ | ||
.. spelling:: | ||
|
||
ing | ||
ver | ||
|
||
.. _conan_conanfile_methods: | ||
.. _reference_conanfile_methods: | ||
|
||
Methods | ||
======= | ||
|
||
|
||
requirements() | ||
-------------- | ||
|
||
Requirement traits | ||
^^^^^^^^^^^^^^^^^^ | ||
|
||
Traits are properties of a requires clause. They determine how various parts of a | ||
dependency are treated and propagated by Conan. Values for traits are usually computed by | ||
Conan based on dependency's :ref:`reference_conanfile_attributes_package_type`, but can | ||
also be specified manually. | ||
|
||
A good introduction to traits is provided in the `Advanced Dependencies Model in Conan 2.0 | ||
<https://youtu.be/kKGglzm5ous>`_ presentation. | ||
|
||
In the example below ``headers`` and ``libs`` are traits. | ||
|
||
.. code-block:: python | ||
self.requires("math/1.0", headers=True, libs=True) | ||
headers | ||
~~~~~~~ | ||
|
||
Indicates that there are headers that are going to be ``#included`` from this package at | ||
compile time. The dependency will be in the host context. | ||
|
||
libs | ||
~~~~ | ||
|
||
The dependency contains some library or artifact that will be used at link time of the | ||
consumer. This trait will typically be ``True`` for direct shared and static libraries, | ||
but could be false for indirect static libraries that are consumed via a shared library. | ||
The dependency will be in the host context. | ||
|
||
build | ||
~~~~~ | ||
|
||
This dependency is a build tool, an application or executable, like cmake, that is used | ||
exclusively at build time. It is not linked/embedded into binaries, and will be in the | ||
build context. | ||
|
||
run | ||
~~~ | ||
|
||
This dependency contains some executables, either apps or shared libraries that need to be | ||
available to execute (typically in the path, or other system env-vars). This trait can be | ||
``True`` for ``build=False``, in that case, the package will contain some executables that | ||
can run in the host system when installing it, typically like an end-user application. | ||
This trait can be ``True`` for ``build=True``, the package will contain executables that | ||
will run in the build context, typically while being used to build other packages. | ||
|
||
visible | ||
~~~~~~~ | ||
|
||
This ``require`` will be propagated downstream, even if it doesn't propagate ``headers``, | ||
``libs`` or ``run`` traits. Requirements that propagate downstream can cause version | ||
conflicts. This is typically ``True``, because in most cases, having 2 different versions of | ||
the same library in the same dependency graph is at least complicated, if not directly | ||
violating ODR or causing linking errors. It can be set to ``False`` in advanced scenarios, | ||
when we want to use different versions of the same package during the build. | ||
|
||
transitive_headers | ||
~~~~~~~~~~~~~~~~~~ | ||
|
||
If ``True`` the headers of the dependency will be visible downstream. | ||
|
||
transitive_libs | ||
~~~~~~~~~~~~~~~ | ||
|
||
If ``True`` the libraries to link with of the dependency will be visible downstream. | ||
|
||
test | ||
~~~~ | ||
|
||
This requirement is a test library or framework, like Catch2 or gtest. It is mostly a | ||
library that needs to be included and linked, but that will not be propagated downstream. | ||
|
||
package_id_mode | ||
~~~~~~~~~~~~~~~ | ||
|
||
If the recipe wants to specify how the dependency version affects the current package | ||
``package_id``, can be directly specified here. | ||
|
||
While it could be also done in the ``package_id()`` method, it seems simpler to be able to | ||
specify it in the ``requires`` while avoiding some ambiguities. | ||
|
||
.. code-block:: python | ||
# We set the package_id_mode so it is part of the package_id | ||
self.tool_requires("tool/1.1.1", package_id_mode="minor_mode") | ||
Which would be equivalent to: | ||
|
||
.. code-block:: python | ||
def package_id(self): | ||
self.info.requires["tool"].minor_mode() | ||
force | ||
~~~~~ | ||
|
||
This ``requires`` will force its version in the dependency graph upstream, overriding | ||
other existing versions even of transitive dependencies, and also solving potential | ||
existing conflicts. | ||
|
||
override | ||
~~~~~~~~ | ||
|
||
The same as the ``force`` trait, but not adding a ``direct`` dependency. If there is no | ||
transitive dependency to override, this ``require`` will be discarded. This trait only | ||
exists at the time of defining a ``requires``, but it will not exist as an actual | ||
``requires`` once the graph is fully evaluated | ||
|
||
direct | ||
~~~~~~ | ||
|
||
If the dependency is a direct one, that is, it has explicitly been declared by the current | ||
recipe, or if it is a transitive one. | ||
|
||
|
||
validate_build() | ||
---------------- | ||
|
||
The ``validate_build()`` method is used to verify if a configuration is valid for building a package. It is different | ||
from the ``validate()`` method that checks if the binary package is "impossible" or invalid for a given configuration. | ||
|
||
The ``validate_build()`` method has to use always the ``self.settings`` and ``self.options``: | ||
|
||
.. code-block:: python | ||
from conan import ConanFile | ||
from conan.errors import ConanInvalidConfiguration | ||
class myConan(ConanFile): | ||
name = "foo" | ||
version = "1.0" | ||
settings = "os", "arch", "compiler" | ||
def package_id(self): | ||
# For this package, it doesn't matter the compiler used for the binary package | ||
del self.info.settings.compiler | ||
def validate_build(self): | ||
# But we know this cannot be build with "gcc" | ||
if self.settings.compiler == "gcc": | ||
raise ConanInvalidConfiguration("This doesn't build in GCC") | ||
.. toctree:: | ||
:maxdepth: 1 | ||
:hidden: | ||
|
||
methods/build | ||
methods/build_id | ||
methods/build_requirements | ||
methods/compatibility | ||
methods/configure | ||
methods/config_options | ||
methods/export | ||
methods/export_sources | ||
methods/generate | ||
methods/init | ||
methods/layout | ||
methods/package | ||
methods/package_id | ||
methods/package_info | ||
methods/requirements | ||
methods/set_name | ||
methods/set_version | ||
methods/source | ||
methods/system_requirements | ||
methods/test | ||
methods/validate | ||
methods/validate_build | ||
|
||
|
||
- :doc:`build() <methods/build>`: Contains the build instructions to build a package from source | ||
- :doc:`build_id() <methods/build_id>`: Allows reusing the same build to create different package binaries | ||
- :doc:`build_requirements() <methods/build_requirements>`: Defines ``tool_requires`` and ``test_requires`` | ||
- :doc:`compatibility() <methods/compatibility>`: Defines binary compatibility at the recipe level | ||
- :doc:`configure() <methods/configure>`: Allows configuring settings and options while computing dependencies | ||
- :doc:`config_options() <methods/config_options>`: Configure options while computing dependency graph | ||
- :doc:`export() <methods/export>`: Copies files that are part of the recipe | ||
- :doc:`export_sources() <methods/export_sources>`: Copies files that are part of the recipe sources | ||
- :doc:`generate() <methods/generate>`: Generates the files that are necessary for building the package | ||
- :doc:`init() <methods/init>`: Special initialization of recipe when extending from ``python_requires`` | ||
- :doc:`layout() <methods/layout>`: Defines the relative project layout, source folders, build folders, etc. | ||
- :doc:`package() <methods/package>`: Copies files from build folder to the package folder. | ||
- :doc:`package_id() <methods/package_id>`: Defines special logic for computing the binary ``package_id`` identifier | ||
- :doc:`package_info() <methods/package_info>`: Provide information for consumers of this package about libraries, folders, etc. | ||
- :doc:`requirements() <methods/requirements>`: Define the dependencies of the package | ||
- :doc:`set_name() <methods/set_name>`: Dynamically define the name of a package | ||
- :doc:`set_version() <methods/set_version>`: Dynamically define the version of a package. | ||
- :doc:`source() <methods/source>`: Define the dependencies of the package | ||
- :doc:`system_requirements() <methods/system_requirements>`: Call system package managers like Apt to install system packages | ||
- :doc:`test() <methods/test>`: Run some simple package test (exclusive of ``test_package``) | ||
- :doc:`validate() <methods/validate>`: Define if the current package is invalid (cannot work) with the current configuration. | ||
- :doc:`validate_build() <methods/validate_build>`: Define if the current package cannot be created with the current configuration. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
.. _reference_conanfile_methods_build: | ||
|
||
build() | ||
======= | ||
|
||
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: | ||
|
||
|
||
.. code-block:: python | ||
from conan.tools.cmake import CMake | ||
class Pkg(ConanFile): | ||
def build(self): | ||
# Either using some of the Conan built-in helpers | ||
cmake = CMake(self) | ||
cmake.configure() # equivalent to self.run("cmake . <other args>") | ||
cmake.build() # equivalent to self.run("cmake --build . <other args>") | ||
cmake.test() # equivalent to self.run("cmake --target=RUN_TESTS") | ||
# Or it could run your own build system or scripts | ||
self.run("mybuildsystem . --configure") | ||
self.run("mybuildsystem . --build") | ||
For more information about the existing built-in build system integrations, visit :ref:`conan_tools`. | ||
|
||
The ``build()`` method should be as simple as possible, just wrapping the command line invocations | ||
that a developer would do in the simplest possible way. The ``generate()`` method is the one responsible | ||
for preparing the build, creating toolchain files, CMake presets, or any other files which are necessary | ||
so developers could easily call the build system by hand. This allows for much better integrations with IDEs and | ||
improves the developer experience. The result is that in practice the ``build()`` method should be relatively simple. | ||
|
||
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. | ||
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. | ||
|
||
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 | ||
``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``. | ||
|
||
|
||
|
||
.. note:: | ||
|
||
**Best practices** | ||
|
||
- 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. | ||
|
||
|
||
.. seealso:: | ||
|
||
Follow the :ref:`tutorial about building packages<tutorial_creating_build>` for more information about building from sources. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
.. _reference_conanfile_methods_build_id: | ||
|
||
build_id() | ||
========== | ||
|
||
The ``build_id()`` method allows to re-use the same build to create different binary packages in the cache, | ||
potentially saving build time as it can avoid some unnecessary re-builds. It is therefore an optimization method. | ||
|
||
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 | ||
can be changed, there are a couple of scenarios that this might be useful: | ||
|
||
- 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. | ||
- 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). | ||
|
||
In the first case, we could for example write: | ||
|
||
.. code-block:: python | ||
settings = "os", "compiler", "arch", "build_type" | ||
def build_id(self): | ||
self.info_build.settings.build_type = "Any" | ||
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 | ||
same ``build_id`` for any ``build_type``, then just one folder and one ``build()`` will be done, building both debug and release artifacts, | ||
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 | ||
executed if using different compilers or architectures. | ||
|
||
Other information like custom package options can also be changed: | ||
|
||
.. code-block:: python | ||
def build_id(self): | ||
self.info_build.options.myoption = 'MyValue' # any value possible | ||
self.info_build.options.fullsource = 'Always' | ||
If the ``build_id()`` method does not modify the ``info_build`` data, and it still produces a different id than | ||
the ``package_id``, then the standard behavior will be applied. Consider the following: | ||
|
||
.. code-block:: python | ||
settings = "os", "compiler", "arch", "build_type" | ||
def build_id(self): | ||
if self.settings.os == "Windows": | ||
self.info_build.settings.build_type = "Any" | ||
This will only produce a different ``build_id`` if the package is for Windows, thus running ``build()`` just | ||
once for all ``build_type`` values. The behavior | ||
in any other OS will be the standard one, as if the ``build_id()`` method was not defined, running | ||
one different ``build()`` for each ``build_type``. | ||
|
||
|
||
.. note:: | ||
|
||
**Best practices** | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
.. _reference_conanfile_methods_build_requirements: | ||
|
||
build_requirements() | ||
==================== | ||
|
||
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``: | ||
|
||
.. code-block:: python | ||
def build_requirements(self): | ||
self.tool_requires("cmake/3.23.5") | ||
self.test_requires("gtest/1.13.0") | ||
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. | ||
|
||
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. | ||
|
||
tool_requires | ||
------------- | ||
|
||
The ``tool_requires`` is equivalent to ``requires()`` with the following traits: | ||
|
||
- ``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. | ||
- ``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. | ||
- ``run=True``. This dependency has some executables or runtime that needs to be ran at build time. | ||
- ``headers=False`` A tool requirement does not have headers. | ||
- ``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). | ||
|
||
test_requires | ||
------------- | ||
|
||
The ``test_requires`` is equivalent to ``requires()`` with the following traits: | ||
|
||
- ``test=True``. This dependency is a "test" dependency, existing in the "host" context, but not aiming to be part of the final product. | ||
- ``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. | ||
|
||
|
||
It is possible to further modify individual traits of ``tool_requires()`` and ``test_requires()`` if necessary, for example: | ||
|
||
.. code-block:: python | ||
def build_requirements(self): | ||
self.tool_requires("cmake/3.23.5", options={"shared": False}) | ||
.. note:: | ||
|
||
**Best practices** | ||
|
||
- ``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. | ||
- 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. | ||
|
||
|
||
.. seealso:: | ||
|
||
- Follow the :ref:`tutorial about consuming Conan packages as tools<consuming_packages_tool_requires>`. | ||
- Read the :ref:`tutorial about creating tool_requires packages<tutorial_other_tool_requires_packages>`. |
Oops, something went wrong.