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

Document 'cpp_info.requires' #1864

Merged
merged 1 commit into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
16 changes: 16 additions & 0 deletions creating_packages/package_information.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@ Consumers can get this information via ``self.deps_cpp_info`` as usual and use i
# Get the include directories of the SSL component of openssl package
self.deps_cpp_info["openssl"].components["ssl"].include_paths


Recipes that require packages that declare components can also take advantage of this granularity, they can declare in the
``cpp_info.requires`` attribute the list of components from the requirements they want to link with:

.. code-block:: python

class Library(ConanFile):
name = 'library'
requires = "openssl/1.0.2u"

def package_info(self):
self.cpp_info.requires = ['openssl::ssl']

In the previous example, the 'library' package and transitively all its consumers will link only with the component ``ssl``
from the ``openssl`` package.

.. seealso::

Read :ref:`components reference <cpp_info_attributes_reference>` for more information.
10 changes: 7 additions & 3 deletions reference/conanfile/attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,10 @@ This object should be filled in ``package_info()`` method.
| self.cpp_info.components | | **[Experimental]** Dictionary with different components a package may have: libraries, executables... |
| | | **Warning**: Using components with other ``cpp_info`` non-default values or configs is not supported |
+--------------------------------------+---------------------------------------------------------------------------------------------------------+
| self.cpp_info.requires | | **[Experimental]** List of components to consume from requirements (it applies only to |
| | | generators that implements components feature). |
| | | **Warning**: If declared, only the components listed here will used by the linker and consumers. |
+--------------------------------------+---------------------------------------------------------------------------------------------------------+

The paths of the directories in the directory variables indicated above are relative to the
:ref:`self.package_folder<folders_attributes_reference>` directory.
Expand Down Expand Up @@ -972,16 +976,16 @@ them and to components of other packages (the following case is not a real examp
self.cpp_info.components["ssl"].requires = ["crypto",
"boost::headers"] # Depends on headers component in boost package

The interface of the ``Component`` object is the same as the one used by the ``cpp_info`` object (except for the ``requires`` attribute) and
The interface of the ``Component`` object is the same as the one used by the ``cpp_info`` object and
has **the same default directories**.

.. warning::

Using components and global ``cpp_info`` non-default values or release/debug configurations at the same time is not allowed (except for
``self.cpp_info.name`` and ``self.cpp_info.names``).

Dependencies among different components can be defined using the ``requires`` attribute and the name of the component. The dependency graph
for components will be calculated and values will be aggregated in the correct order for each field.
Dependencies among components and to components of other requirements can be defined using the ``requires`` attribute and the name
of the component. The dependency graph for components will be calculated and values will be aggregated in the correct order for each field.

.. seealso::

Expand Down
56 changes: 31 additions & 25 deletions reference/conanfile/methods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,20 +224,21 @@ The :ref:`cpp_info_attributes_reference` attribute has the following properties
self.cpp_info.sharedlinkflags = [] # linker flags
self.cpp_info.exelinkflags = [] # linker flags
self.cpp_info.components # Dictionary with the different components a package may have
self.cpp_info.requires = None # List of components from requirements

- **name**: Alternative name for the package to be used by generators.
- **includedirs**: List of relative paths (starting from the package root) of directories where headers can be found. By default it is
initialized to ``['include']``, and it is rarely changed.
- **libs**: Ordered list of libs the client should link against. Empty by default, it is common that different configurations produce
different library names. For example:

.. code-block:: python
.. code-block:: python

def package_info(self):
if not self.settings.os == "Windows":
self.cpp_info.libs = ["libzmq-static.a"] if self.options.static else ["libzmq.so"]
else:
...
def package_info(self):
if not self.settings.os == "Windows":
self.cpp_info.libs = ["libzmq-static.a"] if self.options.static else ["libzmq.so"]
else:
...

- **libdirs**: List of relative paths (starting from the package root) of directories in which to find library object binaries (\*.lib,
\*.a, \*.so, \*.dylib). By default it is initialized to ``['lib']``, and it is rarely changed.
Expand All @@ -258,32 +259,37 @@ The :ref:`cpp_info_attributes_reference` attribute has the following properties
- **cflags**, **cxxflags**, **sharedlinkflags**, **exelinkflags**: List of flags that the consumer should activate for proper behavior.
Usage of C++11 could be configured here, for example, although it is true that the consumer may want to do some flag processing to check
if different dependencies are setting incompatible flags (c++11 after c++14).
- **name**: Alternative name for the package so generators can take into account in order to generate targets or file names.
- **components**: **[Experimental]** Dictionary with names as keys and a component object as value to model the different components a
package may have: libraries, executables... Read more about this feature at :ref:`package_information_components`.

.. code-block:: python
.. code-block:: python

if self.options.static:
if self.settings.compiler == "Visual Studio":
self.cpp_info.libs.append("ws2_32")
self.cpp_info.defines = ["ZMQ_STATIC"]
if self.options.static:
if self.settings.compiler == "Visual Studio":
self.cpp_info.libs.append("ws2_32")
self.cpp_info.defines = ["ZMQ_STATIC"]

if not self.settings.os == "Windows":
self.cpp_info.cxxflags = ["-pthread"]
if not self.settings.os == "Windows":
self.cpp_info.cxxflags = ["-pthread"]

Note that due to the way that some build systems, like CMake, manage forward and back slashes, it might
be more robust passing flags for Visual Studio compiler with dash instead. Using ``"/NODEFAULTLIB:MSVCRT"``,
for example, might fail when using CMake targets mode, so the following is preferred and works both
in the global and targets mode of CMake:
Note that due to the way that some build systems, like CMake, manage forward and back slashes, it might
be more robust passing flags for Visual Studio compiler with dash instead. Using ``"/NODEFAULTLIB:MSVCRT"``,
for example, might fail when using CMake targets mode, so the following is preferred and works both
in the global and targets mode of CMake:

.. code-block:: python
.. code-block:: python

def package_info(self):
self.cpp_info.exelinkflags = ["-NODEFAULTLIB:MSVCRT",
"-DEFAULTLIB:LIBCMT"]

def package_info(self):
self.cpp_info.exelinkflags = ["-NODEFAULTLIB:MSVCRT",
"-DEFAULTLIB:LIBCMT"]
- **name**: Alternative name for the package so generators can take into account in order to generate targets or file names.
- **components**: **[Experimental]** Dictionary with names as keys and a component object as value to model the different components a
package may have: libraries, executables... Read more about this feature at :ref:`package_information_components`.
- **requires**: **[Experimental]** List of components from the requirements this package (and its consumers) should link with. It will
be used by generators that add support for components features (:ref:`package_information_components`).


If your recipe has requirements, you can access to your requirements ``cpp_info`` as well using the ``deps_cpp_info`` object.
If your recipe has requirements, you can access to the information stored in the ``cpp_info`` of your requirements
using the ``deps_cpp_info`` object:

.. code-block:: python

Expand Down