Skip to content
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
5 changes: 5 additions & 0 deletions _themes/conan/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@
<div class="wy-nav-content">
<div class="rst-content">
{% include "breadcrumbs.html" %}
<div class="admonition important">
Conan users please fill
<a href="https://www.surveymonkey.com/r/ConanCommunity">this 2 min survey.</a>
Thanks!
</div>
<select id="search" name="state" multiple="true" onchange="window.location = reldir + this.value;" style="width:90%"></select>
<hr/>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
Expand Down
2 changes: 2 additions & 0 deletions conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ def copy_legacy_redirects(app, docname): # Sphinx expects two arguments
"creating_packages/package_dev_flow.html": "../developing_packages/package_dev_flow.html",
"conan1.0.html": "faq/conan1.0.html",
"mastering/python_requires.html": "../extending/python_requires.html",
"mastering/version_ranges.html": "../versioning/version_ranges.html",
"mastering/revisions.html": "../versioning/revisions.html",

"integrations/cmake.html": "build_system/cmake.html",
"integrations/makefile.html": "build_system/makefile.html",
Expand Down
7 changes: 2 additions & 5 deletions howtos/vs2017_cmake.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,13 @@ Using tasks with tasks.vs.json
Another alternative is using file `tasks <https://docs.microsoft.com/en-us/visualstudio/ide/customize-build-and-debug-tasks-in-visual-studio?view=vs-2017>`_
feature of Visual Studio 2017. This way you can install dependencies by running :command:`conan install` as task directly in the IDE.

All you need is to right click on your *conanfile.py*-> Configure Tasks (see the
All you need is to right click on your *conanfile.py* -> Configure Tasks (see the
`link above <https://docs.microsoft.com/en-us/visualstudio/ide/customize-build-and-debug-tasks-in-visual-studio?view=vs-2017>`_) and add the
following to your *tasks.vs.json*.

.. warning::

The file *tasks.vs.json* is added to your local *.vs* folder so it is not supposed to be added to your version control system. There is
also a feature
`request <https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/33814138-add-macro-buildroot-to-tasks-vs-json>`_
to improve this process.
The file *tasks.vs.json* is added to your local *.vs* folder so it is not supposed to be added to your version control system.

.. code-block:: text
:emphasize-lines: 7,9,16,18
Expand Down
Binary file added images/graph_conflicts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/graph_locked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/graph_not_deterministic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/graph_override.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/lockfile_ci_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/lockfile_ci_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Contents:
uploading_packages
developing_packages
devtools
versioning
mastering
systems_cross_building
extending
Expand Down
2 changes: 0 additions & 2 deletions mastering.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ This section provides an introduction to important productivity and useful featu

mastering/conanfile_py
mastering/conditional
mastering/version_ranges
mastering/policies
mastering/envvars
mastering/virtualenv
mastering/logging
mastering/sharing_settings_and_config
mastering/custom_cache
mastering/revisions
2 changes: 1 addition & 1 deletion reference/conanfile/attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ It tells Conan to workaround the limitation of 260 chars in Windows paths.
.. important::

Since Windows 10 (ver. 10.0.14393), it is possible to `enable long paths at the system level
<https://docs.microsoft.com/es-es/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation>`_.
<https://docs.microsoft.com/es-es/windows/win32/fileio/naming-a-file#maximum-path-length-limitation>`_.
Latest python 2.x and 3.x installers enable this by default. With the path limit removed both on the OS
and on Python, the ``short_paths`` functionality becomes unnecessary, and may be disabled explicitly
through the ``CONAN_USER_HOME_SHORT`` environment variable.
Expand Down
2 changes: 2 additions & 0 deletions reference/conanfile/methods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,8 @@ it is an example of a recipe for a library that doesn't support Windows operatin

This exception will be propagated and Conan application will finish with a :ref:`special return code <invalid_configuration_return_code>`.

.. _method_requirements:

requirements()
--------------

Expand Down
12 changes: 12 additions & 0 deletions versioning.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.. _versioning:

Versioning
----------

.. toctree::
:maxdepth: 2

versioning/introduction
versioning/version_ranges
versioning/revisions
versioning/lockfiles
153 changes: 153 additions & 0 deletions versioning/introduction.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
.. _versioning_introduction:

Introduction to versioning
==========================

Versioning approaches
---------------------

Fixed versions
++++++++++++++

This is the standard, direct way to specify dependencies versions, with their exact
version, for example in a *conanfile.py* recipe:

.. code-block:: python

requires = "zlib/1.2.11@conan/stable"

When doing a :command:`conan install`, it will try to fetch from the remotes exactly
that *1.2.11* version.

This method is nicely explicit and deterministic, and is probably the most used one.
As a possible disadvantage, it requires the consumers to explicitly modify the recipes
to use updated versions, which could be tedious or difficult to scale for large projects
with many dependencies, in which those dependencies are frequently modified, and
it is desired to move the whole project forward to those updated dependencies.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it is desired to move the whole project forward to those updated dependencies.
it is desired to move the whole project forward to those updated dependencies.
To mitigate that issue, especially while developing the packages, you can use fixed versions with `package revisions` (see below) to resolve automatically the latest revisions for a given fixed version.


Version ranges
++++++++++++++

A *conanfile* can specify a range of valid versions that could be consumed, using brackets:

.. code-block:: python

requires = "pkg/[>1.0 <1.8]@user/stable"

When a :command:`conan install` is executed, it will check in the local cache first and if
not in the remotes what ``pkg`` versions are available and will select the latest one
that satisfies the defined range.

By default, it is less deterministic, one ``conan install`` can resolve to ``pkg/1.1`` and
then ``pkg/1.2`` is published, and a new ``conan install`` (by users, or CI), will automatically
pick the newer 1.2 version, with different results. On the other hand it doesn't require
changes to consumer recipes to upgrade to use new versions of dependencies.

It is also true that the *semver* definition that comes from other programming languages
doesn't fit that well to C and C++ packages, because of different reasons, because of
open source libraries that don't closely follow the semver specification, but also because
of the ABI compatibility issues and compilation model that is so characteristic of C and C++ binaries.

Read more about it in :ref:`version_ranges` section.

Package alias
+++++++++++++

It is possible to define a "proxy" package that references another one, using the syntax:

.. code-block:: python

from conans import ConanFile

class AliasConanfile(ConanFile):
alias = "pkg/0.1@user/testing"

This package creation can be automatically created with the :ref:`conan_alias` command, that
can for example create a ``pkg/latest@user/testing`` alias that will be pointing to that
``pkg/0.1@user/testing``. Consumers can define ``requires = "pkg/latest@user/testing"`` and
when the graph is evaluated, it will be directly replaced by the ``pkg/0.1`` one. That is,
the ``pkg/latest`` package will not appear in the dependency graph at all.

This is also less deterministic, and puts the control on the package creator side, instead of
the consumer (version ranges are controlled by the consumer). Package creators can control
which real versions will their consumers be using. This is probably not the recommended way
for normal dependencies versions management.


Package revisions
+++++++++++++++++

Revisions are automatic internal versions to both recipes and binary packages.
When revisions are enabled, when a recipe changes and it is used to
create a package, a new recipe revision is generated, with the hash of the
contents of the recipe. The revisioned reference of the recipe is:

.. code-block:: text

pkg/version@user/channel#recipe_revision1
# after the change of the recipe
pkg/version@user/channel#recipe_revision2

A conanfile can reference a specific revision of its dependencies, but in
the general case that they are not specified, it will fetch the latest
revision available in the remote server:

.. code-block:: text

[requires]
# Use the latest revision of pkg1
pkg1/version@user/channel
# use the specific revision RREV1 of pkg2
pkg2/version@user/channel#RREV1

Each binary package will also be revisioned. The good practice is to build each
binary just once. But if for some reason, like a change in the environment, a new
build of exactly the same recipe with the same code (and the same recipe revision)
is fired again, a new package revision can be created. The package revision
is the hash of the contents of the package (headers, libraries...), so unless
deterministic builds are achieved, new package revisions will be generated.

In general revisions are not intended to be defined explictly in conanfiles,
altough they can for specific purposes like debugging.

Read more about :ref:`package_revisions`


Version and configuration conflicts
-----------------------------------

When two different branches of the same dependency graph require the same package,
this is known as "diamonds" in the graph. If the two branches of a diamond require
the same package but different versions, this is known as a conflict (a version conflict).

Lets say that we are building an executable in **PkgD/1.0**, that depends on **PkgB/1.0** and **PkgC/1.0**,
which contain static libraries. In turn, **PkgB/1.0** depends on **PkgA/1.0** and finally **PkgC/1.0** depends on
**PkgA/2.0**, which is also another static library.

The executable in **PkgD/1.0**, cannot link with 2 different versions of the same static library in **PkgC**, and the dependency resolution algorithm raises an error to let the
user decide which one.

.. image:: ../images/graph_conflicts.png

The same situation happens if the different packages require different configurations of the same upstream package, even if the same version is used. In the example above, both **PkgB** and **PkgC** can be requiring the same version **PkgA/1.0**, but one of them will try to use it as a static library and the other one will try to use it as shared library.
The dependency resolution algorithm will also raise an error.

Dependencies overriding
-----------------------
The downstream consumer packages always have higher priority, so the versions they request, will be overriden upstream as the dependency graph is built, re-defining the possible requires that the packages could have. For example, **PkgB/1.0** could define in its recipe a dependency to **PkgA/1.0**. But if a downstream consumer defines a requirement to **PkgA/2.0**, then that version will be used in the upstream graph:

.. image:: ../images/graph_override.png

This is what enables the users to have control. Even when a package recipe upstream defines an older version, the downstream consumers can force to use an updated version. Note that this is not a diamond structure in the graph, so it is not a conflict by default. This behavior can be also restricted defining the :ref:`env_vars_conan_error_on_override` environment variable to raise an error when these overrides happen, and then the user can go and explicitly modify the upstream **PkgB/1.0** recipe to match the version of PkgA and avoid the override.

In some scenarios, the downstream consumer **PkgD/1.0** might not want to force a dependency on PkgA. There are several possibilities, for example that PkgA is a conditional requirement that only happens in some operating systems. If PkgD defines a normal requirement to PkgA, then, it will be introducing that edge in the graph, forcing PkgA to be used always, in all operating systems. For this purpose the ``override`` qualifier can be defined in requirement, see :ref:`method_requirements`.


Versioning and binary compatibility
-----------------------------------

It is important to note and this point that versioning approaches and strategies should also be
consistent with the binary management.

By default conan assumes *semver* compatibility, so it will not require to build a new binary for a package when its dependencies change their minor or patch versions. This might not be enough for C or C++ libraries which versioning scheme doesn't strictly follow semver. It is strongly suggested to read more about this in :ref:`define_abi_compatibility`

Loading