Developing with Conan

Conan is a C++ package manager which simplifies setting up development environment quite a lot.

To set up everything from scratch (assuming that generic tools like python3, C++ compiler and CMake are already installed):

Setting up Conan

From Conan installation instructions:

# Install Conan
$ pip3 install --user conan

# Auto-detect system settings
$ conan profile new default --detect
# If using gcc:
$ conan profile update settings.compiler.libcxx=libstdc++11 default

Building Gerbera

# Get dependencies (building them if needed) and generate build files:
# The commands generate build system in build/ subfolder
$ conan install -pr ./conan/dev --build missing -if build . && conan build --configure -bf build .

# Now project is ready to build.

Note

Conan also installs a number of packages using system package manager. Therefore it’s a good idea to make sure that sudo works without password. Check also documentation for CONAN_SYSREQUIRES_MODE.

Note

Although it is possible to run CMake directly to configure the project (and Conan reference shows this multiple times in an example), it’s much more convenient to invoke it via conan helper.

This way customizations needs to be defined only once on the Conans command line (via -o parameter), which will affect dependencies (e.g. testing or js) and turned into WITH_* switches to CMake.

Tweaking

Use Ninja

$ conan config set general.cmake_generator=Ninja

Set up different compiler

Add to ~/.conan/profiles/default:

[settings]
compiler.version=10

[env]
CC=gcc-10
CXX=g++-10

If your system has an outdated CMake

Add to ~/.conan/profiles/default:

[build_requires]
cmake/3.17.3

Then just clean the build directory and rerun conan install && conan build.

There may be no prebuilt pacakge with particular compiler / settings

Conan has prebuilt binaries, but they may not be suitable. Some may be built with older C++ standard (conan-center-index#1984), while others may require newer libc (conan-docker-tools#205).

Therefore the most reasonable default is to build missing binary packages (which is handled nicely by Conan).

Also you may want to build dependencies with some specific flags, for example -flto to get better codegen.

You need to run rebuild missing or all packages:

# Build only missing packages
$ conan install --build=missing ...

# Rebuild all packages
$ conan install --build=force ...

See Conan documentation.

Use Conan profiles

It is possible to alter some options for consumed libraries (like static / shared) or build configuration (Debug / Release) via Conan. Conan provides a way to group such options into a profile: a text file used in install command.

It is also possible to define custom compile / link flags in the profile.

There is a number of profiles in the conan subfolder you can use for reference.

Cleanup

Conan stores all data in $HOME/.conan just remove this folder to free disk space.

To remove only packages use conan remove -f '*'

Searching for a package (or checking an update)

$ conan search "fmt" -r all

Existing package recipes:

Remote 'conan-center':
...
fmt/6.1.2
fmt/6.2.0
fmt/6.2.1

Building on FreeBSD

Everything works almost out of the box, except that there are no prebuilt packages.

# Python for Conan
$ pkg install python3 py37-pip py37-sqlite3

# Tools to build dependencies
$ pkg install autoconf automake libtool pkgconf gmake

# Fix build for Iconv
$ conan config set general.conan_make_program=gmake

Remaining system packages are managed by Conan.

Warning

conan_make_program is needed to build correctly IConv. However it interferes with CMake generator (if set to Ninja), so please switch to Ninja after building all dependencies.

Warning

It is not a good idea to build with GCC on FreeBSD since resulting binaries crash because system uses CLang and its libc++ which is incompatible with gccs libstdc++.

Cross-building

This is an example for Raspberry Pi 3 on Ubuntu host.

$ apt install g++-10-aarch64-linux-gnu
$ conan profile new raspberry-pi3

Populate file with content:

toolchain=/usr/aarch64-linux-gnu
target_host=aarch64-linux-gnu
cc_compiler=gcc-10
cxx_compiler=g++-10

[env]
CONAN_CMAKE_FIND_ROOT_PATH=$toolchain
CHOST=$target_host
AR=$target_host-ar
AS=$target_host-as
RANLIB=$target_host-ranlib
CC=$target_host-$cc_compiler
CXX=$target_host-$cxx_compiler
STRIP=$target_host-strip

[settings]
os=Linux
arch=armv8
compiler=gcc

compiler.version=10
compiler.libcxx=libstdc++11
$ conan install -pr:b default -pr:h ./conan/release -pr:h ./conan/minimal -pr:h raspberry-pi3 --build missing -if build . && conan build --configure -bf build .
$ cd build && make
...
[100%] Linking CXX executable gerbera
[100%] Built target gerbera
build $ file gerbera
gerbera: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=7bfdb98dd51a1a5dda5101a0e9f090806fb35a41, for GNU/Linux 3.7.0, with debug_info, not stripped
$ aarch64-linux-gnu-strip -s -o gerbera-s gerbera
$ du -hs gerbera-s
3.9M    gerbera-s

This is a minimal example to begin with. If you have packages from the target system you may omit the minimal profile or tune options on the command line.