Let’s get started with an example: We are going to create a string compressor applicationthat uses one of the most popular C++ libraries: Zlib.
We’ll use CMake as build system in this case but keep in mind that Conan works with anybuild system and is not limited to using CMake. You can check more examples with otherbuild systems in the Read Moresection.
Please, first clone the sources to recreate this project, you can find them in theexamples2 repository in GitHub:
$ git clone https://github.com/conan-io/examples2.git$ cd examples2/tutorial/consuming_packages/simple_cmake_project
We start from a very simple C language project with this structure:
.├── CMakeLists.txt└── src └── main.c
This project contains a basic CMakeLists.txt including the zlib dependency and thesource code for the string compressor program in main.c.
Let’s have a look at the main.c file:
main.c¶
#include <stdlib.h>#include <stdio.h>#include <string.h>#include <zlib.h>int main(void) { char buffer_in [256] = {"Conan is a MIT-licensed, Open Source package manager for C and C++ development " "for C and C++ development, allowing development teams to easily and efficiently " "manage their packages and dependencies across platforms and build systems."}; char buffer_out [256] = {0}; z_stream defstream; defstream.zalloc = Z_NULL; defstream.zfree = Z_NULL; defstream.opaque = Z_NULL; defstream.avail_in = (uInt) strlen(buffer_in); defstream.next_in = (Bytef *) buffer_in; defstream.avail_out = (uInt) sizeof(buffer_out); defstream.next_out = (Bytef *) buffer_out; deflateInit(&defstream, Z_BEST_COMPRESSION); deflate(&defstream, Z_FINISH); deflateEnd(&defstream); printf("Uncompressed size is: %lu\n", strlen(buffer_in)); printf("Compressed size is: %lu\n", strlen(buffer_out)); printf("ZLIB VERSION: %s\n", zlibVersion()); return EXIT_SUCCESS;}
Also, the contents of CMakeLists.txt are:
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.15)project(compressor C)find_package(ZLIB REQUIRED)add_executable(${PROJECT_NAME} src/main.c)target_link_libraries(${PROJECT_NAME} ZLIB::ZLIB)
Our application relies on the Zlib library. Conan, by default, tries to installlibraries from a remote server called ConanCenter.You can search there for libraries and also check the available versions. In our case,after checking the available versions for Zlib wechoose to use one of the latest versions: zlib/1.2.11.
The easiest way to install the Zlib library and find it from our project with Conan isusing a conanfile.txt file. Let’s create one with the following content:
conanfile.txt¶
[requires]zlib/1.2.11[generators]CMakeDepsCMakeToolchain
As you can see we added two sections to this file with a syntax similar to an INI file.
[requires] section is where we declare the libraries we want to use in theproject, in this case, zlib/1.2.11.
[generators] section tells Conan to generate the files that the compilers orbuild systems will use to find the dependencies and build the project. In this case,as our project is based in CMake, we will use CMakeDeps togenerate information about where the Zlib library files are installed andCMakeToolchain to pass build information to CMakeusing a CMake toolchain file.
Besides the conanfile.txt, we need a Conan profile to build our project. Conanprofiles allow users to define a configuration set for things like the compiler, buildconfiguration, architecture, shared or static libraries, etc. Conan, by default, willnot try to detect a profile automatically, so we need to create one. To let Conan tryto guess the profile, based on the current operating system and installed tools, pleaserun:
conan profile detect --force
This will detect the operating system, build architecture and compiler settings based onthe environment. It will also set the build configuration as Release by default. Thegenerated profile will be stored in the Conan home folder with name default and will beused by Conan in all commands by default unless another profile is specified via the commandline. An example of the output of this command for MacOS would be:
$ conan profile detect --forceFound apple-clang 14.0apple-clang>=13, using the major as versionDetected profile:[settings]arch=x86_64build_type=Releasecompiler=apple-clangcompiler.cppstd=gnu17compiler.libcxx=libc++compiler.version=14os=Macos
Note
A note about the detected C++ standard by Conan
Conan will always set the default C++ standard as the one that the detected compilerversion uses by default, except for the case of macOS using apple-clang. In this case,for apple-clang>=11, it sets compiler.cppstd=gnu17
. If you want to use a differentC++ standard, you can edit the default profile file directly. First, get the locationof the default profile using:
$ conan profile path default/Users/user/.conan2/profiles/default
Then open and edit the file and set compiler.cppstd
to the C++ standard you wantto use.
Note
Using a compiler other than the auto-detected one
If you want to change a Conan profile to use a compiler different from the defaultone, you need to change the compiler
setting and also tell Conan explicitly whereto find it using the tools.build:compiler_executablesconfiguration.
We will use Conan to install Zlib and generate the files that CMake needs tofind this library and build our project. We will generate those files in the folderbuild. To do that, run:
$ conan install . --output-folder=build --build=missing
You will get something similar to this as the output of that command:
$ conan install . --output-folder=build --build=missing...-------- Computing dependency graph ----------zlib/1.2.11: Not found in local cache, looking in remotes...zlib/1.2.11: Checking remote: conancenterzlib/1.2.11: Trying with 'conancenter'...Downloading conanmanifest.txtDownloading conanfile.pyDownloading conan_export.tgzDecompressing conan_export.tgzzlib/1.2.11: Downloaded recipe revision f1fadf0d3b196dc0332750354ad8ab7bGraph root conanfile.txt: /home/conan/examples2/tutorial/consuming_packages/simple_cmake_project/conanfile.txtRequirements zlib/1.2.11#f1fadf0d3b196dc0332750354ad8ab7b - Downloaded (conancenter)-------- Computing necessary packages ----------Requirements zlib/1.2.11#f1fadf0d3b196dc0332750354ad8ab7b:cdc9a35e010a17fc90bb845108cf86cfcbce64bf#dd7bf2a1ab4eb5d1943598c09b616121 - Download (conancenter)-------- Installing packages ----------Installing (downloading, building) binaries...zlib/1.2.11: Retrieving package cdc9a35e010a17fc90bb845108cf86cfcbce64bf from remote 'conancenter'Downloading conanmanifest.txtDownloading conaninfo.txtDownloading conan_package.tgzDecompressing conan_package.tgzzlib/1.2.11: Package installed cdc9a35e010a17fc90bb845108cf86cfcbce64bfzlib/1.2.11: Downloaded package revision dd7bf2a1ab4eb5d1943598c09b616121-------- Finalizing install (deploy, generators) ----------conanfile.txt: Generator 'CMakeToolchain' calling 'generate()'conanfile.txt: Generator 'CMakeDeps' calling 'generate()'conanfile.txt: Generating aggregated env files
As you can see in the output, there are a couple of things that happened:
Conan installed the Zlib library from the remote server, which should be the ConanCenter server by default if the library is available. This server stores both the Conanrecipes, which are the files that define how libraries must be built, and the binariesthat can be reused so we don’t have to build from sources every time.
Conan generated several files under the build folder. Those fileswere generated by both the
CMakeToolchain
andCMakeDeps
generators we set inthe conanfile.txt.CMakeDeps
generates files so that CMake finds the Zliblibrary we have just downloaded. On the other side,CMakeToolchain
generates atoolchain file for CMake so that we can transparently build our project with CMakeusing the same settings that we detected for our default profile.
Now we are ready to build and run our compressor app:
Windows¶
$ cd build# assuming Visual Studio 15 2017 is your VS version and that it matches your default profile$ cmake .. -G "Visual Studio 15 2017" -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake"$ cmake --build . --config Release...[100%] Built target compressor$ Release\compressor.exeUncompressed size is: 233Compressed size is: 147ZLIB VERSION: 1.2.11
Linux, macOS¶
$ cd build$ cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release$ cmake --build ....[100%] Built target compressor$ ./compressorUncompressed size is: 233Compressed size is: 147ZLIB VERSION: 1.2.11
See also
Getting started with Autotools
Getting started with Meson
Getting started with Bazel
Getting started with Bazel 7.x