Contents
Last week I shared the general setup of my development environment. Today I will go a bit into Conan and how I use it.
I have written about my current project Fix, and what it is about. For the project I will need a few libraries. In order to not have to install them manually, I use Conan. These are the libraries I currently use:
- My unit tests are written using Catch. Up to now I had used Boost.Test, CppUnit, and Google Test for a two hour Coding Dojo.
- I use mock objects in my unit tests. I could probably write them myself (currently it’s only one), but I went for a mocking library called Trompeloeil.
- For the web server and the application framework I went for Poco. Poco also has some file system functionality which I use in the persistence layer for now.
- The JSON based REST API is implemented using “JSON for modern C++”, which is a really convenient library.
These four libraries are all I use for now. Catch, Trompeloeil and the JSON library are header only. They would be fairly easy to install on any system I work on, but I still want to use Conan, just for the fun of it.
Using Conan
Using Conan is pretty straight forward. If you want to use a library (or package), there has to be a recipe for it on the server. A server can be either the public one on conan.io or a private server you can set up for yourself. I use the public server, since the recipes for most libraries are already there.
Specifying packages
The simplest way to specify which packages a project depends on is to have a conanfile.txt
with a [requires]
section. For Fix it looks like follows:
[requires] Poco/1.7.3@lasote/stable catch/1.5.0@TyRoXx/stable nlJson/2.0.2@arnemertz/stable trompeloeil/v17@rollbear/stable [generators] cmake
You see how the different packages are specified: a name, a version number of the package, the name of the package maintainer and a specifier if the package is in a stable, testing or other phase. The package version often, but not always corresponds to the library version it stands for.
The [generators]
section simply tells Conan to write files for CMake so it knows where to find the libraries and so on.
Building the packages
When we call conan install path/to/conan/file
withe the above conanfile.txt
, Conan will try to get or build the packages. There may or may not be already a binary package for your settings available on the server. In my case, the default settings of my environment are:
arch=x86_64 build_type=Release compiler=clang compiler.libcxx=libstdc++11 compiler.version=3.8 os=Linux
The only thing that changes from case to case currently is the build_type
, which I mostly set to Debug
. For that case I have to add -s build_type=Debug
to the parameters of conan install
.
The packages that are available on conan.io often have binaries compiled with GCC, but not with Clang. That is not a problem, because in that case conan install
simply uses the recipe to download the sources of the package and build it for the settings you use.
The downloaded or compiled binaries are then stored in a cache on your machine, so the compilation for a given set of settings will be done only once. In my case I have two binaries for each package in the Conan cache, because I alter between Debug and Release builds.
Writing your own recipe
You might have noticed that I am the maintainer of the package for the JSON library. The reason is simple: there was no package for that library available on the server. Since I wanted to get the library via Conan regardless, I had to write my own recipe and publish it to conan.io.
The JSON library is header only and therefore fairly simple to build. The recipe only needs to specify where to download the headers from, you can find it on GitHub. Even for more complex packages, it is very simple to get started with your own recipes. There is a good documentation for the process in the Conan docs.
I want to keep my recipe up to date and adopt new versions of the library as soon as possible. Therefore I want to be notified whenever there is a new release of the JSON library. It is available on GitHub, so I tried GitHub notifications first, but I did not find the granularity to get notifications only on new releases, which made the feature rather noisy. Currently I’m trying Sibbell – we’ll see how that turns out.
CMake integration
The integration of Conan and CMake is seamless. If you have run the conan install
with the settings you want to use, all that is left to be done is integrating the generated conanbuildinfo.cmake
file and a setup command into your CMakeLists.txt
.
cmake_minimum_required(VERSION 2.8.12) project( fix ) include(build/conanbuildinfo.cmake) conan_basic_setup() ...
Now, the only thing left is to link the libraries provided by Conan, which are listed in a handy variable:
target_link_libraries( ${PROJ_NAME} ${CONAN_LIBS} )
CMake will take care of include directories and everything else. Simply include the headers and use the library.
#include "Poco/Util/ServerApplication.h" class FixServer : public Poco::Util::ServerApplication { //... };
Conclusion
It is extremely simple to get started using Conan, and it brings all the benefits we know from package managers in other languages.
Permalink