Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review some of the wording #1

Merged
merged 3 commits into from
Feb 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions reference/conanfile/methods/build.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
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 explictly or using any of the build helpers provided by Conan:
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
Expand All @@ -27,22 +27,21 @@ The ``build()`` method is used to define the build from source of the package. I
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 responsible
for preparing the build, creating toolchain file, CMake presets, or whatever other files are necessary
so developers can easily call the build system by hand easily. This way the integration with IDEs and
the developer experience is much better. The result is that the ``build()`` method should be relatively
simple in practice.
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 ``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 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 different 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 that in this case the ``no_copy_source`` attribute cannot be set to ``True``.
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()`` 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.
- 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.
12 changes: 6 additions & 6 deletions reference/conanfile/methods/build_id.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ 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 an optimization method.
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 generates 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 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 write for example:
In the first case, we could for example write:

.. code-block:: python

Expand All @@ -34,7 +34,7 @@ Other information like custom package options can also be changed:
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 produce a different one than
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
Expand All @@ -45,7 +45,7 @@ the ``package_id``, then the standard behavior will be applied. Consider the fol
if self.settings.os == "Windows":
self.info_build.settings.build_type = "Any"

This will only produce a ``build_id`` different if the package is for Windows, running ``build()`` just
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``.
Expand All @@ -55,4 +55,4 @@ one different ``build()`` for each ``build_type``.

**Best practices**

Conan strong recommendation is to use one package binary with its own ``package_id`` for each different configuration. The ``build_id()`` goal is to deal with legacy build scripts that cannot easily be changed to do the build of one configuration each time.
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.
12 changes: 6 additions & 6 deletions reference/conanfile/methods/build_requirements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
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, the ``build_requirements()`` is good for having a dedicated place to define ``tool_requires`` and ``test_requires``:
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

Expand All @@ -14,15 +14,15 @@ The ``build_requirements()`` method is functionally equivalent to the ``requirem

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`` are just a specialized instance of ``requires`` with some predefined trait values. See the :ref:`requires() reference<reference_conanfile_methods_requirements>` for more information.
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 ``tool_requires("cmake/3.23.5")``, but that doesn't mean that consumer packages also use ``cmake``, they could even use a different build system, or a different version, without causing conflicts.
- ``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).
Expand All @@ -33,7 +33,7 @@ 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 ``self.test_requires("gtest/1.13.0")``, but that doesn't mean that consumer packages also use ``gtest``, they could even use a different test framework, or the same ``gtest`` with a different version, without causing conflicts.
- ``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:
Expand All @@ -48,5 +48,5 @@ It is possible to further modify individual traits of ``tool_requires()`` and ``

**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, using a ``requires()`` with custom trait values.
- The ``self.test_requires()`` and ``self.tool_requires`` should exclusively be used in this ``build_requirements()`` method, with the only possible exception of the ``requirements()`` method. Using them in any other method is forbidden. To access dependencies information when necessary in some methods, the ``self.dependencies`` should be used.
- ``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.
8 changes: 4 additions & 4 deletions reference/conanfile/methods/compatibility.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ level. In general, the global compatibility plugin should be good for most cases
require the recipe method for exceptional cases.

This method can be used in a *conanfile.py* to define packages that are compatible between
each other. If there are no binaries available for the requested settings and options
this mechanism will retrieve the compatible package's binaries if they exist. The method
each other. If there are no binaries available for the requested settings and options,
this mechanism will retrieve the compatible package's binaries if they exist. This method
should return a list of compatible configurations.

For example, if we want that binaries
built with gcc versions 4.8, 4.7 and 4.6 are considered compatible with the ones compiled
with 4.9 we could declare the ``compatibility()`` like this:
built with gcc versions 4.8, 4.7 and 4.6 to be considered compatible with the ones compiled
with 4.9 we could declare a ``compatibility()`` method like this:

.. code-block:: python

Expand Down
4 changes: 2 additions & 2 deletions reference/conanfile/methods/config_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ config_options()

The ``config_options()`` method
is used to configure or constraint the available options in a package, **before** they are given a value. A typical use case is to remove an option in a given platform. For example,
the ``fPIC`` flag doesn't exist in Windows, so it should be done:
the ``fPIC`` flag doesn't exist in Windows, so it should be removed in this method like so:

.. code-block:: python

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

The ``config_options()`` executes before ``configure()`` method, and before the actual assignment of ``options`` values, but settings are already defined.
The ``config_options()`` method executes before the ``configure()`` method, and before the actual assignment of the ``options`` values, but after settings are already defined.
14 changes: 7 additions & 7 deletions reference/conanfile/methods/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
configure()
===========

The ``configure()`` method should be used for configuration of settings and options in the recipe
The ``configure()`` method should be used for the configuration of settings and options in the recipe
for later use in the different methods like ``generate()``, ``build()`` or ``package()``. This
method executes while building the dependency graph and expanding the packages dependencies, that means
method executes while building the dependency graph and expanding the packages dependencies, which means
that when this method executes the dependencies are still not there, they do not exist, and it is not
possible to access ``self.dependencies``.

For example, for a C (not C++) library, the ``compiler.libcxx`` and ``compiler.cppstd`` shouldn't
For example, for a C (not C++) library, the ``compiler.libcxx`` and ``compiler.cppstd`` settings shouldn't
even exist during the ``build()``. It is not only that they are not part of the ``package_id``, but
they shouldn't be used in the build process at all. They will be defined in the profile, because
other packages in the graph can be C++ packages and need them, but it is the responsibility of this
Expand Down Expand Up @@ -40,10 +40,10 @@ so it should be removed:

def configure(self):
if self.options.shared:
del self.options.fPIC
self.options.rm_safe("fPIC")
AbrilRBS marked this conversation as resolved.
Show resolved Hide resolved


Recipes can suggest dependencies option values as ``default_options = {"*:shared": True}``, but
Recipes can suggest values for their dependencies options as ``default_options = {"*:shared": True}``, but
it is not possible to do that conditionally. For this purpose, it is also possible to use the
``configure()`` method:

Expand All @@ -58,5 +58,5 @@ it is not possible to do that conditionally. For this purpose, it is also possib

**Best practices**

- Recall it is **not** possible to define ``settings`` or ``conf`` values in recipes, they are read only.
- The definition of ``options`` values is only a "suggestion", but not always defining the value, depending on the graph computation, priorities, etc., the final value of ``options`` can be different.
- Recall that it is **not** possible to define ``settings`` or ``conf`` values in recipes, they are read only.
- The definition of ``options`` values is only a "suggestion", depending on the graph computation, priorities, etc., the final value of ``options`` can be different than the one set by the recipe.
12 changes: 6 additions & 6 deletions reference/conanfile/methods/export.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export()
========

Equivalent to the ``exports`` attribute, but in method form. This method will be called at ``export`` time,
which happens in ``conan export`` and ``conan create`` commands, and it is intended to allow copying files from the
user folder to the Conan cache folders, those files becoming part of the recipe. These sources will
which happens in the ``conan export`` and ``conan create`` commands, and it is intended to allow copying files from the
user folder to the Conan cache folders, thus making files becoming part of the recipe. These sources will
be uploaded to the servers together with the recipe, but are typically not downloaded unless the package is
being built from source.

Expand All @@ -25,13 +25,13 @@ as the destination folder for using ``copy()`` or your custom copy.
copy(self, "LICENSE.md", self.recipe_folder, self.export_folder)


There are 2 files that are always exported to the cache, without being explicitly defined in the recipe: the ``conanfile.py`` recipe, and the ``conandata.yml`` file if it exists. The ``conandata.yml`` file is automatically loaded whenever the ``conanfile.py`` is loaded, becoming the ``self.conan_data`` attribute, so it is intrinsic part of the recipe, so it is part of the "exported" recipe files, not of the "exported" source files.
There are 2 files that are always exported to the cache, without being explicitly defined in the recipe: the ``conanfile.py`` recipe, and the ``conandata.yml`` file if it exists. The ``conandata.yml`` file is automatically loaded whenever the ``conanfile.py`` is loaded, becoming the ``self.conan_data`` attribute, so it is a intrinsic part of the recipe, so it is part of the "exported" recipe files, not of the "exported" source files.


.. note::

**Best practices**

- The recipe files must be configuration independent. Those files are common for all configurations, then, it is not possible to do conditional ``export()`` to different settings, options, or platforms. Do not try to do any kind of conditional export. If necessary export all the files necessary for all configurations at once.
- The exported files must be small. Exporting with the recipe big files will make much slower the resolution of dependencies.
- Only files that are necessary for the evaluation of the ``conanfile.py`` recipe must be exported with this method. Files necessary for building from sources should be exported with ``exports_sources`` attribute or ``export_source()`` method.
- The recipe files must be configuration independent. Those files are common for all configurations, thus it is not possible to do conditional ``export()`` to different settings, options, or platforms. Do not try to do any kind of conditional export. If necessary export all the files necessary for all configurations at once.
- The exported files must be small. Exporting big files with the recipe will make the resolution of dependencies much slower the resolution.
- Only files that are necessary for the evaluation of the ``conanfile.py`` recipe must be exported with this method. Files necessary for building from sources should be exported with the ``exports_sources`` attribute or the :ref:`export_source()<reference_conanfile_methods_export_sources>` method.
Loading