Conan 1.20: Reuse CMake macros, system libraries support, Compatible packages and new recipe methods!
New 1.20 release with useful features and improvements. Here you have the main highlights of this one!
Reuse CMake macros from your dependencies
Following the line of previous releases, we continue to pursue a transparent integration with build systems and in this case, we have
cpp_info model to include build system files or build modules in the case of CMake.
This new feature allows reusing the CMake macros on the consumer side in a transparent way. This comes in handy when libraries provide some kind of helper as a function or macro to consumers to create or link targets or to use a built-in tool.
We did some tests using the pybind11 library. This library provides a CMake macro that helps a consumer to create and link its targets: pybin11_add_module().
The recommended way to use the library can be found in the (library’s documentation)[https://pybind11.readthedocs.io/en/stable/compiling.html#building-with-cmake] as the following:
cmake_minimum_required(VERSION 2.8.12) project(example) add_subdirectory(pybind11) pybind11_add_module(example example.cpp)
Using build modules, the files needed to reuse that macro can be now included in the
cpp_info model like this:
... def package_info(self): base_path = os.path.join("share", "cmake", "pybind11") self.cpp_info.builddirs = [base_path] self.cpp_info.build_modules = [ os.path.join(base_path, "pybind11Tools.cmake"), os.path.join(base_path, "FindPythonLibsNew.cmake") ] ...
Those build modules will be included in the find and config files generated by the
generators so they can be used transparently like this:
cmake_minimum_required(VERSION 2.8.12) project(example) find_package(pybind11 REQUIRED) pybind11_add_module(example example.cpp)
The complete diff of the changes required in the
pybind11 recipe as well as the consumer’s CMakeLists.txt can be found here.
Remember to check the documentation for full details about this feature.
Support for system libraries
Another useful improvement coming to the
cpp_info model is the system libraries. Commonly, libraries
require consumers to link to system libraries like
This was normally done appending those system libs to the
cpp_info.libs and therefore, mixing package libraries with the
Some generators were smart enough to detect package libraries and system libraries, but they did not apply any special treatment to the latest.
With the usage of
cpp_info.system_libs generators have now the ability to improve the target generation, linking them as
INTERFACE_LINK_LIBRARIES in all the CMake generators.
You can read more about system libraries in the documentation.
In our investigation to support new compilers, we realized while integrating the Intel C++ compiler that the compatibility with packages built with a base compiler was not possible due to the package ID model restriction in Conan.
Until this release, the only compatibility possible was to create the same package (unique package ID) with the same settings input. This means, that if you wanted to model the compatibility of a package for GCC 4.7, 4.8 and 4.9, the only possible way was to define a unique ID for all of them with a fixed version value (see example here). However, that is not the case when mixing packages for the Intel C++ compiler and Visual Studio and GCC.
This new feature allows package creators to define compatible packages with a completely different package ID. A list of compatible packages
can be defined in the
package_id() method, for example, you can define GCC 4.9 and 4.7 as compatible packages for consumers that are using
GCC 4.9 as input in their profiles. The difference here is that now, if you apply a profile for GCC 4.7 you will generate a package for 4.7,
if you apply a profile of 4.8 you will get a package ID for 4.8, but if you don’t generate a package for 4.9 and you require this package as
a consumer, you will get a binary for 4.8 or 4.7 if available:
... def package_id(self): if self.settings.compiler == "gcc" and self.settings.compiler.version == "4.9": for version in ("4.8", "4.7"): compatible_pkg = CompatiblePackage(self) compatible_pkg.settings.compiler.version = version self.compatible_packages.append(compatible_pkg) ...
When a package is not found but a compatible package exists, Conan will pick the available package and notify it with the following message:
$ conan install lib/0.1@us/ch ... Main binary package '2ef6f6c768dd0f332dc252b72c30dee116632302' missing. Using compatible package '1151fe341e6b310f7645a76b4d3d524342835acc' ... lib/0.1@us/ch:1151fe341e6b310f7645a76b4d3d524342835acc - Cache
Note that this implies that the packages are compatible at all effects, as Conan will treat them as fully interchangeable.
This is has been introduced as a experimental feature and the interface might change in future releases but you can take a look at the documentation and the examples to learn more about it.
Dynamically set the name or the version of your packages
Now you can dynamically define the name and the version of your recipes with
set_version(). For example, if you want to extract the version from the CMakeLists.txt:
class HelloConan(ConanFile): name = "Hello" def set_version(self): content = load("CMakeLists.txt") version = re.search(b"set\(MY_LIBRARY_VERSION (.*)\)", content).group(1) self.version = version.strip()
The set of
self.version is only allowed inside those methods and the information will be stored in the recipe metadata, meaning that these methods will be only used when the recipe is exported to the cache.
We had some optimizations pending for the SCM feature that are now solved in this release.
Now, when a package is created with not committed changes, the
auto fields in the recipe are not replaced automatically. This marks the
packages as dirty and prevents the upload of the recipe to a remote without uncommitted changes but allows developers to continue testing
the package creation with those changes.
However, you can still force Conan to replace the
auto fields in export, create and export-pkg commands with the
--ignore-dirty flag or
force the upload of dirty packages with
conan upload --force.
See the complete documentation of this feature.
Clang 10 and GCC 7.4 support
Conan 1.20 adds support for Clang 10 and includes the specific 7.4 version for GCC in the default settings.yml file.
Remember that the minor version values in the
gcc compiler are claimed to be compatible and that Conan will use by default just GCC 7 as
the version value in the profile unless it is explicitly indicated in the profile.
Generating Artifactory build-info from lockfiles
With our focus on improving the continuous integration flows for Conan packages, we have released a new approach to generate build information for packages using the Build Info JSON format for Artifactory. Instead of using the Conan trace file to gather the information, this is now done using a lockfile.
This new experimental feature
is available through the
conan_build_info command and we trust it will help to look into and develop how to achieve an efficient, robust
and complete CI flow for C/C++ projects using Conan.
Finally, check the full list of features and fixes in the changelog and do not hesitate to report any bug or share your feedback opening a new issue in our issue tracker.