diff --git a/devtools/build_requires.rst b/devtools/build_requires.rst index af99d608f2a..e55cbbdfaef 100644 --- a/devtools/build_requires.rst +++ b/devtools/build_requires.rst @@ -39,9 +39,9 @@ Build requirements can be declared in profiles, like: Build requirements are specified by a ``pattern:``. If such pattern is not specified, it will be assumed to be ``*``, i.e. to apply to all packages. Packages can be declared in different lines or by a comma separated list. In this example, ``tool1``, ``tool2``, ``tool3`` and -``Tool4`` will be used for all packages in the dependency graph (while running :command:`conan install` or :command:`conan create`). +``tool4`` will be used for all packages in the dependency graph (while running :command:`conan install` or :command:`conan create`). -If a pattern like ``my_pkg*`` is specified, the declared build requirements will only be applied to packages matching that pattern. ``tool5`` +If a pattern like ``my_pkg*`` is specified, the declared build requirements will only be applied to packages matching that pattern: ``tool5`` will not be applied to Zlib for example, but it will be applied to ``my_pkg_zlib``. The special case of a **consumer** conanfile (without name or version) it is impossible to match with a pattern, so it is handled with the @@ -69,7 +69,7 @@ Build requirements can also be specified in a package recipe, with the ``build_r The above ``tool_a`` and ``tool_b`` will always be retrieved and used for building this recipe, while the ``tool_win`` one will only be used only in Windows. -If some build requirement defined inside ``build_requirements()`` has the same package name as the one defined in the ``build_requires`` +If any build requirement defined inside ``build_requirements()`` has the same package name as the one defined in the ``build_requires`` attribute, the one inside the ``build_requirements()`` method will prevail. As a rule of thumb, downstream defined values always override upstream dependency values. If some build requirement is defined in the diff --git a/reference/tools.rst b/reference/tools.rst index 81cefce5369..f44571a80a4 100644 --- a/reference/tools.rst +++ b/reference/tools.rst @@ -39,7 +39,7 @@ tools.vcvars_command() .. code-block:: python - def vcvars_command(settings, arch=None, compiler_version=None, force=False, vcvars_ver=None, + def vcvars_command(conanfile, arch=None, compiler_version=None, force=False, vcvars_ver=None, winsdk_version=None) Returns, for given settings, the command that should be called to load the Visual Studio environment variables for a certain Visual Studio @@ -53,7 +53,7 @@ the same subprocess. It will be typically used in the ``build()`` method, like t def build(self): if self.settings.build_os == "Windows": - vcvars = tools.vcvars_command(self.settings) + vcvars = tools.vcvars_command(self) build_command = ... self.run("%s && configure %s" % (vcvars, " ".join(args))) self.run("%s && %s %s" % (vcvars, build_command, " ".join(build_args))) @@ -67,7 +67,7 @@ If **arch** or **compiler_version** is specified, it will ignore the settings an for these parameters. Parameters: - - **settings** (Required): Conanfile settings. Use ``self.settings``. + - **conanfile** (Required): Conanfile object. Use ``self`` in a ``conanfile.py``. - **arch** (Optional, Defaulted to ``None``): Will use ``settings.arch``. - **compiler_version** (Optional, Defaulted to ``None``): Will use ``settings.compiler.version``. - **force** (Optional, Defaulted to ``False``): Will ignore if the environment is already set for a different Visual Studio version. @@ -810,19 +810,31 @@ tools.cross_building() .. code-block:: python - def cross_building(settings, self_os=None, self_arch=None, skip_x64_x86=False) + def cross_building(conanfile, self_os=None, self_arch=None, skip_x64_x86=False) + + +Evaluates operating system and architecture from the ``host`` machine and the ``build`` machine +to return a boolean ``True`` if it is a cross building scenario. Settings from ``host`` machine are +taken from the ``conanfile.settings``, while setting from the ``build`` context can provide from +different sources: -Reading the settings and the current host machine it returns ``True`` if we are cross building a Conan package: +* if ``conanfile.settings_build`` is available (Conan was called with a ``--profile:build``) it will + use settings in that profile (read more about :ref:`build_requires_context`). +* otherwise, the values for the ``build`` context will come from (in this order of precedence): + ``self_os`` and ``self_arch`` if they are given to the function, the values for ``os_build`` + and ``arch_build`` from ``conanfile.settings`` or auto-detected. + +This tool can be used to run special actions depending on its return value: .. code-block:: python from conans import tools - if tools.cross_building(self.settings): + if tools.cross_building(self): # Some special action Parameters: - - **settings** (Required): Conanfile settings. Use ``self.settings``. + - **conanfile** (Required): Conanfile object. Use ``self`` in a ``conanfile.py``. - **self_os** (Optional, Defaulted to ``None``): Current operating system where the build is being done. - **self_arch** (Optional, Defaulted to ``None``): Current architecture where the build is being done. - **skip_x64_x86** (Optional, Defaulted to ``False``): Do not consider building for ``x86`` host from ``x86_64`` build machine diff --git a/systems_cross_building/cross_building.rst b/systems_cross_building/cross_building.rst index a6534dd8b6d..eb8f10753f0 100644 --- a/systems_cross_building/cross_building.rst +++ b/systems_cross_building/cross_building.rst @@ -47,10 +47,10 @@ Let's illustrate these scenarios with some examples: platform Linux, and as we saw before, that Android NDK cross compiler will generate binaries for a ``target`` platform which is Android. -The values of the ``build``, ``host`` and ``target`` platforms are not absolute, and -they depend on the process we are talking about. The ``host`` when compiling a cross compiler turns +**The values of the** ``build`` **,** ``host`` **and** ``target`` **platforms are not absolute, and +they depend on the process we are talking about**: the ``host`` when compiling a cross compiler turns into the ``build`` when using that same cross compiler, or the ``target`` of the cross compiler is -the ``host`` platform of the binaries generated with it. +the ``host`` platform when we are using it to build binaries. .. seealso:: @@ -68,17 +68,17 @@ Conan package for Windows, you need to tell Conan where to find your toolchain/c There are two approaches: -- Install the toolchain in your computer and use a ``profile`` to declare the settings and +- Using a profile: install the toolchain in your computer and use a ``profile`` to declare the settings and point to the needed tools/libraries in the toolchain using the ``[env]`` section to declare, at least, the ``CC`` and ``CXX`` environment variables. -- Package the toolchain as a Conan package and include it as a ``build_requires``. +- Using build requires: package the toolchain as a Conan package and include it as a ``build_requires``. Using a profile +++++++++++++++ -Using a Conan profile we can declare not only the ``settings`` that will identify our binary, but also +Using a Conan profile we can declare not only the ``settings`` that will identify our binary (``host`` settings), but also all the environment variables needed to use a toolchain or cross compiler. The profile needs the following sections: @@ -90,7 +90,7 @@ sections: where the host system libraries and tools are. For example, in the following profile we declare the ``host`` platform to be Windows x86_64 with the -compiler, version and other settings be are using. And we add the **[env]** section with all the variables +compiler, version and other settings we are using. And we add the **[env]** section with all the variables needed to use an installed toolchain: .. code-block:: ini @@ -193,6 +193,48 @@ The above means that **Conan is able to compile the full graph in a single execu the build requires using the ``profile_build`` and then it will compile the libraries using the ``host_profile`` settings applying the environment of the former ones. +Starting with Conan v1.25 (if the user provides the ``--profile:build``) it is possible to get the relative context +where a recipe is running during a Conan invocation. The object instatiated from the recipe contains the following +attributes: + +* ``self.settings`` will always contain the settings corresponding to the binary to build/retrieve. It will contain + the settings from the profile ``profile_host`` when this recipe appears in the ``host`` context and the settings + from the profile ``profile:build`` if this object belongs to the ``build`` context. +* ``self.settings_build`` will always contain the settings provided in the profile ``profile_build``, even if the + recipe appears in the ``build`` context, the build requirements of the build requirements are expected to + run in the ``build`` machine too. +* ``self.settings_target``: for recipes in the ``host`` context this attribute will be equal to ``None``, for those + in the ``build`` context, if will depend on the level of anidation: + + + for recipes that are build requirements of packages in the ``host`` context, this attribute will contain + the settins from the profile ``profile_host``, while + + for recipes that are build requirements of other build requirements the ``self.settings_target`` + will contain the values of the ``profile_build``. + +With previous attributes, a draft for a recipe that packages a cross compiler could follow this pattern: + +.. code-block:: python + + class CrossCompiler(ConanFile): + name = "my_compiler" + + settings = "os", "arch", "compiler", "build_type" + options = {"target": "ANY"} + default_options = {"shared": False, "target": None} + + def configure(self): + settings_target = getattr(self, 'settings_target', None) + if settings_target is None: + # It is running in 'host', so Conan is compiling this package + if not self.options.target: + raise ConanInvalidConfiguration("A value for option 'target' has to be provided") + else: + # It is running in 'build' and it is being used as a BR, 'target' can be inferred from settings + if self.options.target: + raise ConanInvalidConfiguration("Value for the option 'target' will be computed from settings_target") + self.options.target = "" # Use 'self.settings_target' to get this value + + Conan older than v1.24 ...................... @@ -250,8 +292,8 @@ Conan can still compile it from sources but it won't be able to identify the bin if the build requirements has other Conan dependencies. -Settings ``*_build`` and ``*_target`` -+++++++++++++++++++++++++++++++++++++ +Host settings ``os_build``, ``arch_build``, ``os_target`` and ``arch_target`` ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .. warning:: @@ -265,7 +307,8 @@ Before Conan v1.24 the recommended way to deal with cross building was to use so for some Conan tools and build helpers, but they also need to be listed in the recipes themselves creating a dedicated set of recipes for *installers* and *tools* in general. This approach should be superseeded with the introduction in Conan 1.24 of the command line arguments ``--profile:host`` and ``--profile:build`` -that allow to declare two different profiles with all the information needed for the corresponding platforms. +that allow to declare two different profiles with all the information needed for the corresponding platforms +(see section above this one). The meaning of those settings is the following: @@ -279,27 +322,6 @@ The meaning of those settings is the following: The rest of settings, as we already know, identify the ``host`` platform. -Preparing recipes to be cross-compiled -++++++++++++++++++++++++++++++++++++++ - -If you use the build helpers :ref:`AutoToolsBuildEnvironment` or :ref:`CMake` -together with ``os_build`` and ``arch_build`` settings, Conan will adjust the configuration accordingly to the specified settings. - -If not, you can always check the regular settings ``os``, ``arch``,... (matching the ``host`` platform) and -inject the needed flags to your build system script. - -Also, you can use this tool to check if you are cross-building: - -- :ref:`tools.cross_building(self.settings)` (returns True or False) - - -.. note:: - - In the following releases, this build helpers and tools will take into account the values of the - command line arguments ``--profile:host`` and ``--profile:build`` to implement the proper - cross building behavior. - - ARM architecture reference --------------------------