2016 09 27 CMake Tutorial

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 171

CMake tutorial

and its friends CPack, CTest and CDash

Eric NOULARD - eric.noulard@gmail.com

https://cmake.org
Compiled on September 28, 2016

This presentation is licensed

http://creativecommons.org/licenses/by-sa/3.0/us/
https://github.com/TheErk/CMake-tutorial

Initially given by Eric Noulard for Toulibre on February, 8th 2012.

https://github.com/TheErk/CMake-tutorial CMake tutorial


1 / 136
N
Thanks to. . .

Kitware for making a really nice set of tools and making them
open-source
the CMake mailing list for its friendliness and its more than
valuable source of information
CMake developers for their tolerance when I break the dashboard
or mess-up with the Git workflow,
CPack users for their patience when things don’t work as they
should expect
Alan, Alex, Bill, Brad, Clint, David, Eike, Julien, Mathieu, Michael
& Michael, Stephen, Domen, and many more. . .
My son Louis for the nice CPack 3D logo done with Blender.
and...Toulibre for initially hosting this presention in Toulouse,
France.
https://github.com/TheErk/CMake-tutorial CMake tutorial
2 / 136
N
Overview

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


3 / 136
N
Overview

And thanks to contributors as well. . .

History
This presentation was initially made by Eric Noulard for a Toulibre
(http://www.toulibre.fr) given in Toulouse (France) on February, 8th
2012. After that, the source of the presentation has been release under CC-
BY-SA, http://creativecommons.org/licenses/by-sa/3.0/us/ and
put on https://github.com/TheErk/CMake-tutorial then contributors
stepped-in.

Many thanks to all contributors (alphabetical order):

Contributors
Sébastien Dinot, Andreas Mohr.

https://github.com/TheErk/CMake-tutorial CMake tutorial


4 / 136
N
Introduction

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


5 / 136
N
Introduction

CMake tool sets

CMake
CMake is a cross-platform build systems generator which makes
it easier to build software in a unified manner on a broad set
of platforms:

, , , , AIX, IRIX, , ···

CMake has friends softwares that may be used on their own or


together:
CMake: build system generator
CPack: package generator
CTest: systematic test driver
CDash: a dashboard collector
https://github.com/TheErk/CMake-tutorial CMake tutorial
6 / 136
N
Introduction

Outline of Part I: CMake


1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


7 / 136
N
Introduction

Outline of Part II: CPack

7 CPack: Packaging made easy

8 CPack with CMake

9 Various package generators

https://github.com/TheErk/CMake-tutorial CMake tutorial


8 / 136
N
Introduction

Outline of Part III: CTest and CDash

10 Systematic Testing

11 CTest submission to CDash

12 References

https://github.com/TheErk/CMake-tutorial CMake tutorial


9 / 136
N
Introduction

Build what?

Software build system


A software build system is the usage of a [set of] tool[s] for
building software applications.

Why do we need that?


Introduction

Build what?

Software build system


A software build system is the usage of a [set of] tool[s] for
building software applications.

Why do we need that?


because most softwares consist of several parts that need some
building to put them together,
Introduction

Build what?

Software build system


A software build system is the usage of a [set of] tool[s] for
building software applications.

Why do we need that?


because most softwares consist of several parts that need some
building to put them together,
because softwares are written in various languages that may
share the same building process,
Introduction

Build what?

Software build system


A software build system is the usage of a [set of] tool[s] for
building software applications.

Why do we need that?


because most softwares consist of several parts that need some
building to put them together,
because softwares are written in various languages that may
share the same building process,
because we want to build the same software for various
computers (PC, Macintosh, Workstation, mobile phones and other PDA,
embedded computers) and systems (Windows, Linux, *BSD, other Unices
(many), Android, etc. . . )

https://github.com/TheErk/CMake-tutorial CMake tutorial


10 / 136
N
Introduction

Programming languages

Compiled vs interpreted or what?


Building an application requires the use of some programming
language: Python, Java, C++, Fortran, C, Go, Tcl/Tk, Ruby,
Perl, OCaml,. . .

Python
?byte-compile?
Perl interpreter
Programming
languages

Matlab interprets

OCaml
Running
C/C++ executes program
executable
compiles
object

links
code

Fortran
ADA

https://github.com/TheErk/CMake-tutorial CMake tutorial


11 / 136
N
Introduction

Programming languages

Compiled vs interpreted or what?


Building an application requires the use of some programming
language: Python, Java, C++, Fortran, C, Go, Tcl/Tk, Ruby,
Perl, OCaml,. . .

Python
?byte-compile?
Perl interpreter
Programming
languages

Matlab interprets

OCaml
Running
C/C++ executes program
executable
compiles
object

links
code

Fortran
ADA

https://github.com/TheErk/CMake-tutorial CMake tutorial


11 / 136
N
Introduction

Build systems: several choices

Alternatives
CMake is not the only build system [generator]:
(portable) hand-written Makefiles, depends on make tool (may
be GNU Make).
Apache ant (or Maven or Gradle), dedicated to Java (almost).
Portable IDE: Eclipse, Code::Blocks, Geany, NetBeans, . . .
GNU Autotools: Autoconf, Automake, Libtool. Produce
makefiles. Bourne shell needed (and M4 macro processor).
http://www.scons.org only depends on Python.
...

https://github.com/TheErk/CMake-tutorial CMake tutorial


12 / 136
N
Introduction

Build systems or build systems generator

Build systems
A tool which builds, a.k.a. compiles, a set of source files in
order to produce binary executables and libraries. Those kind
of tools usually takes as input a file (e.g. a Makefile) and while
reading it issues compile commands. The main goal of a build
tool is to (re)build the minimal subset of files when something
changes. A non exhaustive list: [GNU] make, ninja, MSBuild,
SCons, ant, . . .

A Build systems generator is a tool which generates files for a


particular build system. e.g. CMake or Autotools.

https://github.com/TheErk/CMake-tutorial CMake tutorial


13 / 136
N
Introduction

What build systems do?

Targets and sources


The main feature of a build system is to offer a way to describe
how a target (executable, PDF, shared library. . . ) is built from
its sources (set of object files and/or libraries, a latex or rst file,
set of C/C++/Fortran files. . . ). Basically a target depends on
one or several sources and one can run a set of commands in
order to built the concerned target from its sources.

The main goals/features may be summarized as:


describe dependency graph between sources and targets
associate one or several commands to rebuilt target from source(s)
issue the minimal set of commands in order to rebuild a target
https://github.com/TheErk/CMake-tutorial CMake tutorial
14 / 136
N
Introduction

A sample Makefile for make


1 CC=gcc
2 CFLAGS=−Wall −Werror −p e d a n t i c −s t d=c99
3 LDFLAGS=
4 EXECUTABLES=A c r o d i c t l i b r e A c r o l i b r e
5
6 # d e f a u l t r u l e ( t h e f i r s t one )
7 a l l : $ (EXECUTABLES)
8 # explicit link target
9 Acrolibre : acrolibre . o
10 $ (CC) $ ( CFLAGS ) −o $@ $ˆ
11 # e x p l i c i t l i n k and c o m p i l e t a r g e t
12 Acrodictlibre : acrolibre . c acrodict . o
13 $ (CC) $ ( CFLAGS ) −DUSE ACRODICT −o $@ $ˆ
14
15 # I m p l i c i t rule using f i l e extension
16 # Every . o f i l e depends on c o r r e s p o n d i n g . c ( and may be . h ) f i l e
17 %.o : %. c %.h
18 $ (CC) $ ( CFLAGS ) −c $<
19 %.o : %. c
20 $ (CC) $ ( CFLAGS ) −c $<
21 clean :
22 @\rm −f ∗ . o $ (EXECUTABLES)

https://github.com/TheErk/CMake-tutorial CMake tutorial


15 / 136
N
Introduction

Comparisons and [success] stories

Disclaimer
This presentation is biased. I mean totally.
I am a big CMake fan, I did contribute to CMake, thus I’m not
impartial at all. But I will be ready to discuss why CMake is
the greatest build system out there :-)

Go and forge your own opinion:


Bare list: http://en.wikipedia.org/wiki/List_of_build_
automation_software
A comparison:
http://www.scons.org/wiki/SconsVsOtherBuildTools
KDE success story (2006): “Why the KDE project switched to
CMake – and how” http://lwn.net/Articles/188693/
https://github.com/TheErk/CMake-tutorial CMake tutorial
16 / 136
N
Introduction

CMake/Auto[conf|make] on OpenHub

https://www.openhub.net/languages/compare
Language comparison of CMake to automake and autoconf
showing the percentage of developers commits that modify a
source file of the respective language (data from 2012).
https://github.com/TheErk/CMake-tutorial CMake tutorial
17 / 136
N
Introduction

CMake/Autoconf/Gradle on Google Trend

https://www.google.com/trends
Scale is based on the average worldwide request traffic search-
ing for CMake, Autoconf and Gradle in all years (2004–now).

https://github.com/TheErk/CMake-tutorial CMake tutorial


18 / 136
N
Basic CMake usage

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


19 / 136
N
Basic CMake usage

A build system generator

CMake is a generator: it generates native build systems files


(Makefile, Ninja, IDE project files [XCode, CodeBlocks, Eclipse
CDT, Codelite, Visual Studio, Sublime Text. . . ], . . . ),
CMake scripting language (declarative) is used to describe the
build,
The developer edits CMakeLists.txt, invokes CMake but should
never edit the generated files,
CMake may be (automatically) re-invoked by the build system,
CMake has friends who may be very handy (CPack, CTest, CDash)

https://github.com/TheErk/CMake-tutorial CMake tutorial


20 / 136
N
Basic CMake usage

The CMake workflow

When do things take place?


CMake is a generator which means it does not compile (i.e.
build) the sources, the underlying build tool (make, Ninja,
XCode, Visual Studio. . . ) does.

https://github.com/TheErk/CMake-tutorial CMake tutorial


21 / 136
N
Basic CMake usage

The CMake workflow

1 CMake time: CMake is running & processing CMakeLists.txt

When do things take place?


CMake is a generator which means it does not compile (i.e.
build) the sources, the underlying build tool (make, Ninja,
XCode, Visual Studio. . . ) does.

https://github.com/TheErk/CMake-tutorial CMake tutorial


21 / 136
N
Basic CMake usage

The CMake workflow

1 CMake time: CMake is running & processing CMakeLists.txt


2 Build time: the build tool runs and invokes (at least) the compiler

When do things take place?


CMake is a generator which means it does not compile (i.e.
build) the sources, the underlying build tool (make, Ninja,
XCode, Visual Studio. . . ) does.

https://github.com/TheErk/CMake-tutorial CMake tutorial


21 / 136
N
Basic CMake usage

The CMake workflow

1 CMake time: CMake is running & processing CMakeLists.txt


2 Build time: the build tool runs and invokes (at least) the compiler
3 Install time: the compiled binaries are installed
i.e. from build area to an install location.

When do things take place?


CMake is a generator which means it does not compile (i.e.
build) the sources, the underlying build tool (make, Ninja,
XCode, Visual Studio. . . ) does.

https://github.com/TheErk/CMake-tutorial CMake tutorial


21 / 136
N
Basic CMake usage

The CMake workflow

1 CMake time: CMake is running & processing CMakeLists.txt


2 Build time: the build tool runs and invokes (at least) the compiler
3 Install time: the compiled binaries are installed
i.e. from build area to an install location.
4 CPack time: CPack is running for building package

When do things take place?


CMake is a generator which means it does not compile (i.e.
build) the sources, the underlying build tool (make, Ninja,
XCode, Visual Studio. . . ) does.

https://github.com/TheErk/CMake-tutorial CMake tutorial


21 / 136
N
Basic CMake usage

The CMake workflow

1 CMake time: CMake is running & processing CMakeLists.txt


2 Build time: the build tool runs and invokes (at least) the compiler
3 Install time: the compiled binaries are installed
i.e. from build area to an install location.
4 CPack time: CPack is running for building package
5 Package Install time: the package (from previous step) is installed

When do things take place?


CMake is a generator which means it does not compile (i.e.
build) the sources, the underlying build tool (make, Ninja,
XCode, Visual Studio. . . ) does.

https://github.com/TheErk/CMake-tutorial CMake tutorial


21 / 136
N
Basic CMake usage

The CMake workflow (pictured)


CMakeLists.txt

Source files

https://github.com/TheErk/CMake-tutorial CMake tutorial


22 / 136
N
Basic CMake usage

The CMake workflow (pictured)


Project file(s),
CMakeLists.txt
Makefiles, . . .

Source files

Generated
Sources files

CMake time

https://github.com/TheErk/CMake-tutorial CMake tutorial


22 / 136
N
Basic CMake usage

The CMake workflow (pictured)


Project file(s),
CMakeLists.txt Object files
Makefiles, . . .

Source files

Generated
Sources files

CMake time

Build time

https://github.com/TheErk/CMake-tutorial CMake tutorial


22 / 136
N
Basic CMake usage

The CMake workflow (pictured)


Project file(s),
CMakeLists.txt Object files
Makefiles, . . .

Installed
Source files files

Generated
Sources files

CMake time

Build time

Install time

https://github.com/TheErk/CMake-tutorial CMake tutorial


22 / 136
N
Basic CMake usage

The CMake workflow (pictured)


Project file(s),
CMakeLists.txt Object files
Makefiles, . . .

Installed
Source files files

Generated
Sources files
Binary
package
CMake time

Source Build time


package
Install time

CPack time

https://github.com/TheErk/CMake-tutorial CMake tutorial


22 / 136
N
Basic CMake usage

The CMake workflow (pictured)


Project file(s),
CMakeLists.txt Object files
Makefiles, . . .

Installed
Source files files

Generated
Sources files
Binary
package
CMake time

Source Build time


package
Install time Installed
CPack time package
Package Install time

https://github.com/TheErk/CMake-tutorial CMake tutorial


22 / 136
N
Basic CMake usage

Building an executable

Listing 1: Building a simple program


1 cmake minimum required (VERSION 3 . 0 )
2 # T h i s p r o j e c t use C s o u r c e code
3 p r o j e c t ( TotallyFree C)
4 s e t (CMAKE C STANDARD 9 9 )
5 s e t (CMAKE C EXTENSIONS F a l s e )
6 # build executable using s p e c i f i e d l i s t of source f i l e s
7 add executable ( Acrolibre a c r o l i b r e . c )

CMake scripting language is [mostly] declarative. It has


commands which are documented from within CMake:
$ cmake --help-command-list | wc -l
117
$ cmake --help-command add_executable
...
add_executable
Add an executable to the project using the specified source files.

https://github.com/TheErk/CMake-tutorial CMake tutorial


23 / 136
N
Basic CMake usage

Builtin documentation I
CMake builtin doc for ’project’ command
1 $ cmake --help-command project
2 project
3 -------
4
5 Set a name, version, and enable languages for the entire project.
6
7 project(<PROJECT-NAME> [LANGUAGES] [<language-name>...])
8 project(<PROJECT-NAME>
9 [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
10 [LANGUAGES <language-name>...])
11
12 Sets the name of the project and stores the name in the
13 ‘‘PROJECT_NAME‘‘ variable.
14 [...]
15 Optionally you can specify which languages your project supports.
16 Example languages are CXX (i.e. C++), C, Fortran, etc. By default C and CXX are enabled.
17 E.g. if you do not have a C++ compiler, you can disable the check for it by explicitly
18 listing the languages you want to support, e.g. C. By using the special language "NONE"
19 all checks for any language can be disabled.

https://github.com/TheErk/CMake-tutorial CMake tutorial


24 / 136
N
Basic CMake usage

Builtin documentation II
Online doc : https://cmake.org/documentation/
Unix Manual: cmake-variables(7), cmake-commands(7), cmake-xxx(7), . . .
All doc generated using Sphinx, QtHelp file as well:
1 get QtHelp file from CMake:
https://cmake.org/cmake/help/v3.6/CMake.qch
and copy it to CMake-tutorial/examples/
2 use CMake.qhcp you may find in the source of this tutorial:
CMake-tutorial/examples/CMake.qhcp
3 compile QtHelp collection file:
qcollectiongenerator CMake.qhcp -o CMake.qhc
4 display it using Qt Assistant:
assistant -collectionFile CMake.qhc

https://github.com/TheErk/CMake-tutorial CMake tutorial


25 / 136
N
Basic CMake usage

Generating & building


Building with CMake and make is easy:
Building with make
1 $ ls totally-free
2 acrolibre.c CMakeLists.txt
3 $ mkdir build
4 $ cd build
5 $ cmake ../totally-free
6 -- The C compiler identification is GNU 4.6.2
7 -- Check for working C compiler: /usr/bin/gcc
8 -- Check for working C compiler: /usr/bin/gcc -- works
9 ...
10 $ make
11 ...
12 [100%] Built target Acrolibre
13 $ ./Acrolibre toulibre

Source tree vs Build tree


Even the most simple project should never mix-up sources with
generated files. CMake supports out-of-source build.

https://github.com/TheErk/CMake-tutorial CMake tutorial


26 / 136
N
Basic CMake usage

Generating & building


Building with CMake and ninja is easy:
Building with ninja
1 $ ls totally-free
2 acrolibre.c CMakeLists.txt
3 $ mkdir build-ninja
4 $ cd build-ninja
5 $ cmake -GNinja ../totally-free
6 -- The C compiler identification is GNU 4.6.2
7 -- Check for working C compiler: /usr/bin/gcc
8 -- Check for working C compiler: /usr/bin/gcc -- works
9 ...
10 $ ninja
11 ...
12 [6/6] Linking C executable Acrodictlibre
13 $ ./Acrolibre toulibre

Source tree vs Build tree


Even the most simple project should never mix-up sources with
generated files. CMake supports out-of-source build.

https://github.com/TheErk/CMake-tutorial CMake tutorial


26 / 136
N
Basic CMake usage

Generating & building


Cross-Building with CMake and make is easy:
Building with cross-compiler
1 $ ls totally-free
2 acrolibre.c CMakeLists.txt
3 $ mkdir build-win32
4 $ cd build-win32
5 $ cmake -DCMAKE_TOOLCHAIN_FILE=../totally-free/Toolchain-cross-linux.cmake ../totally-free
6 -- The C compiler identification is GNU 6.1.1
7 -- Check for working C compiler: /usr/bin/i686-w64-mingw32-gcc
8 ...
9 $ make
10 ...
11 [100%] Linking C executable Acrolibre.exe
12 [100%] Built target Acrolibre
13 $ ./Acrolibre toulibre

Source tree vs Build tree


Even the most simple project should never mix-up sources with
generated files. CMake supports out-of-source build.

https://github.com/TheErk/CMake-tutorial CMake tutorial


26 / 136
N
Basic CMake usage

Always build out-of-source

Out-of-source is better
People are lazy (me too) and they think that because building
in source is possible and authorizes less typing they can get
away with it. In-source build is a BAD choice.

Out-of-source build is always better because:

https://github.com/TheErk/CMake-tutorial CMake tutorial


27 / 136
N
Basic CMake usage

Always build out-of-source

Out-of-source is better
People are lazy (me too) and they think that because building
in source is possible and authorizes less typing they can get
away with it. In-source build is a BAD choice.

Out-of-source build is always better because:


1 Generated files are separated from manually edited ones
(thus you don’t have to clutter your favorite VCS ignore files).

https://github.com/TheErk/CMake-tutorial CMake tutorial


27 / 136
N
Basic CMake usage

Always build out-of-source

Out-of-source is better
People are lazy (me too) and they think that because building
in source is possible and authorizes less typing they can get
away with it. In-source build is a BAD choice.

Out-of-source build is always better because:


1 Generated files are separated from manually edited ones
(thus you don’t have to clutter your favorite VCS ignore files).
2 You can have several build trees for the same source tree

https://github.com/TheErk/CMake-tutorial CMake tutorial


27 / 136
N
Basic CMake usage

Always build out-of-source

Out-of-source is better
People are lazy (me too) and they think that because building
in source is possible and authorizes less typing they can get
away with it. In-source build is a BAD choice.

Out-of-source build is always better because:


1 Generated files are separated from manually edited ones
(thus you don’t have to clutter your favorite VCS ignore files).
2 You can have several build trees for the same source tree
3 This way it’s always safe to completely delete the build tree in
order to do a clean build

https://github.com/TheErk/CMake-tutorial CMake tutorial


27 / 136
N
Basic CMake usage

Building program + autonomous library

We now have the following set of files in our source tree:


acrolibre.c, the main C program
acrodict.h, the Acrodict library header
acrodict.c, the Acrodict library source
CMakeLists.txt, the soon to be updated CMake input file

https://github.com/TheErk/CMake-tutorial CMake tutorial


28 / 136
N
Basic CMake usage

Building program + autonomous library

Conditional build
We want to keep a version of our program that can be compiled
and run without the new Acrodict library and the new version
which uses the library.

We now have the following set of files in our source tree:


acrolibre.c, the main C program
acrodict.h, the Acrodict library header
acrodict.c, the Acrodict library source
CMakeLists.txt, the soon to be updated CMake input file

https://github.com/TheErk/CMake-tutorial CMake tutorial


28 / 136
N
The main program source

organization promoting FLOSS


1 #i n c l u d e < s t d l i b . h> .\n" ) ;
2 #i n c l u d e <s t d i o . h> 24 }
3 #i n c l u d e < s t r i n g s . h> 25 #e l s e
4 #i f d e f USE ACRODICT 26 item = a c r o d i c t g e t ( name ) ;
5 #i n c l u d e "acrodict.h" 27 i f (NULL!= item ) {
6 #e n d i f 28 p r i n t f ( "%s: %s\n" , item−>name , item−>
7 i n t main ( i n t argc , c h a r ∗ a r g v [ ] ) { description ) ;
8 29 } e l s e i f ( item=a c r o d i c t g e t a p p r o x (
9 c o n s t c h a r ∗ name ; name ) ) {
10 #i f d e f USE ACRODICT 30 p r i n t f ( " <%s> is unknown may be you
11 c o n s t a c r o I t e m t ∗ item ; mean :\n" , name ) ;
12 #e n d i f 31 p r i n t f ( "%s: %s\n" , item−>name , item−>
13 description ) ;
14 i f ( argc < 2) { 32 }
15 f p r i n t f ( s t d e r r , "%s: you need one 33 #e n d i f
argument\n" , a r g v [ 0 ] ) ; 34 else {
16 f p r i n t f ( s t d e r r , "%s <name >\n" , a r g v 35 p r i n t f ( "Sorry , I don’t know: <%s>\n
[0]) ; " , name ) ;
17 e x i t ( EXIT FAILURE ) ; 36 r e t u r n EXIT FAILURE ;
18 } 37 }
19 name = a r g v [ 1 ] ; 38 r e t u r n EXIT SUCCESS ;
20 39 }
21 #i f n d e f USE ACRODICT
22 i f ( s t r c a s e c m p ( name , "toulibre" ) ==0) {
23 p r i n t f ( "Toulibre is a french

https://github.com/TheErk/CMake-tutorial CMake tutorial


29 / 136
N
The library source

10 {"Lea" , "Lea -Linux: Linux entre ami(e


1 #i f n d e f ACRODICT H )s" } ,
2 #d e f i n e ACRODICT H 11 {"RMLL" , "Rencontres Mondiales du
3 typedef s t r u c t acroItem { Logiciel Libre" } ,
4 c h a r ∗ name ; 12 {"FLOSS" , "Free Libre Open Source
5 char ∗ d e s c r i p t i o n ; Software" } ,
6 } acroItem t ; 13 {"" , "" } } ;
7 14 const acroItem t ∗
8 const acroItem t ∗ 15 a c r o d i c t g e t ( c o n s t c h a r ∗ name ) {
9 a c r o d i c t g e t ( c o n s t c h a r ∗ name ) ; 16 i n t c u r r e n t =0;
10 #e n d i f 17 i n t found =0;
18 w h i l e ( ( s t r l e n ( a c r o d i c t [ c u r r e n t ] . name
) >0) && ! found ) {
1 #i n c l u d e < s t d l i b . h> 19 i f ( s t r c a s e c m p ( name , a c r o d i c t [
2 #i n c l u d e < s t r i n g . h> c u r r e n t ] . name ) ==0) {
3 #i n c l u d e "acrodict.h" 20 found =1;
4 s t a t i c const acroItem t acrodict [ ] = { 21 } else {
5 {"Toulibre" , "Toulibre is a french 22 c u r r e n t ++;
organization promoting FLOSS" } , 23 }
6 {"GNU" , "GNU is Not Unix" } , 24 }
7 {"GPL" , "GNU general Public License" 25 i f ( found ) {
}, 26 r e t u r n &( a c r o d i c t [ c u r r e n t ] ) ;
8 {"BSD" , "Berkeley Software 27 } else {
Distribution" } , 28 r e t u r n NULL ;
9 {"CULTe" , "Club des Utilisateurs de 29 }
Logiciels libres et de gnu/ 30 }
linux de Toulouse et des
environs" } ,

https://github.com/TheErk/CMake-tutorial CMake tutorial


30 / 136
N
Basic CMake usage

A sample Makefile for make


1 CC=gcc
2 CFLAGS=−Wall −Werror −p e d a n t i c −s t d=c99
3 LDFLAGS=
4 EXECUTABLES=A c r o d i c t l i b r e A c r o l i b r e
5
6 # d e f a u l t r u l e ( t h e f i r s t one )
7 a l l : $ (EXECUTABLES)
8 # explicit link target
9 Acrolibre : acrolibre . o
10 $ (CC) $ ( CFLAGS ) −o $@ $ˆ
11 # e x p l i c i t l i n k and c o m p i l e t a r g e t
12 Acrodictlibre : acrolibre . c acrodict . o
13 $ (CC) $ ( CFLAGS ) −DUSE ACRODICT −o $@ $ˆ
14
15 # I m p l i c i t rule using f i l e extension
16 # Every . o f i l e depends on c o r r e s p o n d i n g . c ( and may be . h ) f i l e
17 %.o : %. c %.h
18 $ (CC) $ ( CFLAGS ) −c $<
19 %.o : %. c
20 $ (CC) $ ( CFLAGS ) −c $<
21 clean :
22 @\rm −f ∗ . o $ (EXECUTABLES)

https://github.com/TheErk/CMake-tutorial CMake tutorial


31 / 136
N
Basic CMake usage

Building a library
Listing 2: Building a simple program + shared library
1 cmake minimum required (VERSION 3 . 0 )
2 p r o j e c t ( TotallyFree C)
3 s e t (CMAKE C STANDARD 9 9 )
4 s e t (CMAKE C EXTENSIONS F a l s e )
5 add executable ( Acrolibre a c r o l i b r e . c )
6 s e t ( LIBSRC a c r o d i c t . c a c r o d i c t . h )
7 a d d l i b r a r y ( a c r o d i c t ${LIBSRC } )
8 add executable ( A c r o d i c t l i b r e a c r o l i b r e . c )
9 t a r g e t l i n k l i b r a r i e s ( Acrodictlibre acrodict )
10 s e t t a r g e t p r o p e r t i e s ( A c r o d i c t l i b r e PROPERTIES COMPILE FLAGS "-DUSE_ACRODICT" )

we precise that we want to compile with C99 flags

https://github.com/TheErk/CMake-tutorial CMake tutorial


32 / 136
N
Basic CMake usage

Building a library
Listing 3: Building a simple program + shared library
1 cmake minimum required (VERSION 3 . 0 )
2 p r o j e c t ( TotallyFree C)
3 s e t (CMAKE C STANDARD 9 9 )
4 s e t (CMAKE C EXTENSIONS F a l s e )
5 add executable ( Acrolibre a c r o l i b r e . c )
6 s e t ( LIBSRC a c r o d i c t . c a c r o d i c t . h )
7 a d d l i b r a r y ( a c r o d i c t ${LIBSRC } )
8 add executable ( A c r o d i c t l i b r e a c r o l i b r e . c )
9 t a r g e t l i n k l i b r a r i e s ( Acrodictlibre acrodict )
10 s e t t a r g e t p r o p e r t i e s ( A c r o d i c t l i b r e PROPERTIES COMPILE FLAGS "-DUSE_ACRODICT" )

we precise that we want to compile with C99 flags


we define a variable and ask to build a library

https://github.com/TheErk/CMake-tutorial CMake tutorial


32 / 136
N
Basic CMake usage

Building a library
Listing 4: Building a simple program + shared library
1 cmake minimum required (VERSION 3 . 0 )
2 p r o j e c t ( TotallyFree C)
3 s e t (CMAKE C STANDARD 9 9 )
4 s e t (CMAKE C EXTENSIONS F a l s e )
5 add executable ( Acrolibre a c r o l i b r e . c )
6 s e t ( LIBSRC a c r o d i c t . c a c r o d i c t . h )
7 a d d l i b r a r y ( a c r o d i c t ${LIBSRC } )
8 add executable ( A c r o d i c t l i b r e a c r o l i b r e . c )
9 t a r g e t l i n k l i b r a r i e s ( Acrodictlibre acrodict )
10 s e t t a r g e t p r o p e r t i e s ( A c r o d i c t l i b r e PROPERTIES COMPILE FLAGS "-DUSE_ACRODICT" )

we precise that we want to compile with C99 flags


we define a variable and ask to build a library
we link an executable to our library

https://github.com/TheErk/CMake-tutorial CMake tutorial


32 / 136
N
Basic CMake usage

Building a library
Listing 5: Building a simple program + shared library
1 cmake minimum required (VERSION 3 . 0 )
2 p r o j e c t ( TotallyFree C)
3 s e t (CMAKE C STANDARD 9 9 )
4 s e t (CMAKE C EXTENSIONS F a l s e )
5 add executable ( Acrolibre a c r o l i b r e . c )
6 s e t ( LIBSRC a c r o d i c t . c a c r o d i c t . h )
7 a d d l i b r a r y ( a c r o d i c t ${LIBSRC } )
8 add executable ( A c r o d i c t l i b r e a c r o l i b r e . c )
9 t a r g e t l i n k l i b r a r i e s ( Acrodictlibre acrodict )
10 s e t t a r g e t p r o p e r t i e s ( A c r o d i c t l i b r e PROPERTIES COMPILE FLAGS "-DUSE_ACRODICT" )

we precise that we want to compile with C99 flags


we define a variable and ask to build a library
we link an executable to our library
we compile the source files of a particular target with specific
compiler options

https://github.com/TheErk/CMake-tutorial CMake tutorial


32 / 136
N
Basic CMake usage

Building a library - continued I

And it builds...
All in all CMake generates appropriate Unix makefiles which
build all this smoothly.

CMake + Unix Makefile


1 $ make
2 [ 33%] Building C object CMakeFiles/acrodict.dir/acrodict.c.o
3 Linking C shared library libacrodict.so
4 [ 33%] Built target acrodict
5 [ 66%] Building C object CMakeFiles/Acrodictlibre.dir/acrolibre.c.o
6 Linking C executable Acrodictlibre
7 [ 66%] Built target Acrodictlibre
8 [100%] Building C object CMakeFiles/Acrolibre.dir/acrolibre.c.o
9 Linking C executable Acrolibre
10 [100%] Built target Acrolibre
11 $ ls -F
12 Acrodictlibre* CMakeCache.txt cmake_install.cmake Makefile
13 Acrolibre* CMakeFiles/ libacrodict.so*

https://github.com/TheErk/CMake-tutorial CMake tutorial


33 / 136
N
Basic CMake usage

Building a library - continued II


And it works...
We get the two different variants of our program, with varying
capabilities.

1 $ ./Acrolibre toulibre Generated Makefiles has


2 Toulibre is a french organization promoting FLOSS.
3 $ ./Acrolibre FLOSS several builtin targets besides
4
5
Sorry, I don’t know: <FLOSS>
$ ./Acrodictlibre FLOSS
the expected ones:
6 FLOSS: Free Libre Open Source Software
$ make help one per target (library or
The following are some of the valid targets
for this Makefile: executable)
... all (the default if no target is provided)
... clean
... depend
... Acrodictlibre
clean, all
... Acrolibre
... acrodict
... more to come . . .
https://github.com/TheErk/CMake-tutorial CMake tutorial
34 / 136
N
Basic CMake usage

Building a library - continued III


And it is homogeneously done whatever the generator...
The obtained build system contains the same set of targets
whatever the combination of generator and [cross-]compiler
used: Makefile+gcc, Ninja+clang, XCode, Visual Studio,
etc. . .

https://github.com/TheErk/CMake-tutorial CMake tutorial


35 / 136
N
Basic CMake usage

User controlled build option

User controlled option


Maybe our users don’t want the acronym dictionary support.
We can use CMake OPTION command.

Listing 6: User controlled build option


1 cmake minimum required (VERSION 3 . 0 )
2 # T h i s p r o j e c t use C s o u r c e code
3 p r o j e c t ( TotallyFree C)
4 # B u i l d o p t i o n w i t h d e f a u l t v a l u e t o ON
5 o p t i o n (WITH ACRODICT "Include acronym dictionary support" ON)
6 s e t ( BUILD SHARED LIBS t r u e )
7 # build executable using s p e c i f i e d l i s t of source f i l e s
8 add executable ( Acrolibre a c r o l i b r e . c )
9 i f (WITH ACRODICT)
10 s e t ( LIBSRC a c r o d i c t . h a c r o d i c t . c )
11 a d d l i b r a r y ( a c r o d i c t ${LIBSRC } )
12 add executable ( A c r o d i c t l i b r e a c r o l i b r e . c )
13 t a r g e t l i n k l i b r a r i e s ( Acrodictlibre acrodict )
14 s e t t a r g e t p r o p e r t i e s ( A c r o d i c t l i b r e PROPERTIES COMPILE FLAGS "-DUSE_ACRODICT" )
15 e n d i f (WITH ACRODICT)

https://github.com/TheErk/CMake-tutorial CMake tutorial


36 / 136
N
Basic CMake usage

Too much keyboard, time to click? I

CMake comes with severals tools


A matter of choice / taste:
a command line: cmake
a curses-based TUI: ccmake
a Qt-based GUI: cmake-gui

Calling convention
All tools expect to be called with a single argument which may
be interpreted in 2 different ways.
path to the source tree, e.g.: cmake /path/to/source
path to an existing build tree, e.g.: cmake-gui .

https://github.com/TheErk/CMake-tutorial CMake tutorial


37 / 136
N
Basic CMake usage

Too much keyboard, time to click? II


ccmake : the curses-based TUI (demo)

Here we can choose to toggle the WITH ACRODICT OPTION.

https://github.com/TheErk/CMake-tutorial CMake tutorial


38 / 136
N
Basic CMake usage

Too much keyboard, time to click? III


cmake-gui : the Qt-based GUI (demo)

Again, we can choose to toggle the WITH ACRODICT OPTION.

https://github.com/TheErk/CMake-tutorial CMake tutorial


39 / 136
N
Basic CMake usage

Remember CMake is a build generator?


The number of active generators depends on the platform we are
running on Unix, Apple, Windows:

1 Borland Makefiles 16 Visual Studio 8 2005 Win64


2 MSYS Makefiles 17 Visual Studio 9 2008
3 MinGW Makefiles 18 Visual Studio 9 2008 IA64
4 NMake Makefiles 19 Visual Studio 9 2008 Win64
5 NMake Makefiles JOM 20 Watcom WMake
6 Unix Makefiles 21 CodeBlocks - MinGW Makefiles
7 Visual Studio 10 22 CodeBlocks - NMake Makefiles
8 Visual Studio 10 IA64 23 CodeBlocks - Unix Makefiles
9 Visual Studio 10 Win64 24 Eclipse CDT4 - MinGW Makefiles
10 Visual Studio 11 25 Eclipse CDT4 - NMake Makefiles
11 Visual Studio 11 Win64 26 Eclipse CDT4 - Unix Makefiles
12 Visual Studio 6 27 KDevelop3
13 Visual Studio 7 28 KDevelop3 - Unix Makefiles
14 Visual Studio 7 .NET 2003 29 XCode
15 Visual Studio 8 2005 30 Ninja

https://github.com/TheErk/CMake-tutorial CMake tutorial


40 / 136
N
Basic CMake usage

Equally simple on other platforms


It is as easy for a Windows build, however names for executables
and libraries are computed in a platform specific way.
CMake + MinGW Makefile
1 $ ls totally-free
2 acrodict.h acrodict.c acrolibre.c CMakeLists.txt
3 $ mkdir build-win32
4 $ cd build-win32
5 $ cmake -DCMAKE_TOOLCHAIN_FILE=../totally-free/Toolchain-cross-linux.cmake ../totally-free
6 ...
7 $ make
8 Scanning dependencies of target acrodict
9 [ 33%] Building C object CMakeFiles/acrodict.dir/acrodict.c.obj
10 Linking C shared library libacrodict.dll
11 Creating library file: libacrodict.dll.a
12 [ 33%] Built target acrodict
13 Scanning dependencies of target Acrodictlibre
14 [ 66%] Building C object CMakeFiles/Acrodictlibre.dir/acrolibre.c.obj
15 Linking C executable Acrodictlibre.exe
16 [ 66%] Built target Acrodictlibre
17 Scanning dependencies of target Acrolibre
18 [100%] Building C object CMakeFiles/Acrolibre.dir/acrolibre.c.obj
19 Linking C executable Acrolibre.exe
20 [100%] Built target Acrolibre

https://github.com/TheErk/CMake-tutorial CMake tutorial


41 / 136
N
Basic CMake usage

Installing things

Install
Several parts or the software may need to be installed: this is
controlled by the CMake install command.
Remember cmake --help-command install!!

Listing 7: install command examples


1 ...
2 add executable ( Acrolibre a c r o l i b r e . c )
3 i n s t a l l (TARGETS A c r o l i b r e DESTINATION b i n )
4 i f (WITH ACRODICT)
5 ...
6 i n s t a l l (TARGETS A c r o d i c t l i b r e a c r o d i c t
7 RUNTIME DESTINATION b i n
8 LIBRARY DESTINATION l i b
9 ARCHIVE DESTINATION l i b / s t a t i c )
10 i n s t a l l ( FILES a c r o d i c t . h DESTINATION i n c l u d e )
11 e n d i f (WITH ACRODICT)

https://github.com/TheErk/CMake-tutorial CMake tutorial


42 / 136
N
Basic CMake usage

Controlling installation destination

Use relative DESTINATION


One should always use relative installation DESTINATION
unless you really want to use absolute path like /etc.

Then depending on when you install:

https://github.com/TheErk/CMake-tutorial CMake tutorial


43 / 136
N
Basic CMake usage

Controlling installation destination

Use relative DESTINATION


One should always use relative installation DESTINATION
unless you really want to use absolute path like /etc.

Then depending on when you install:


At CMake-time set CMAKE INSTALL PREFIX value
$ cmake --help-variable CMAKE_INSTALL_PREFIX

https://github.com/TheErk/CMake-tutorial CMake tutorial


43 / 136
N
Basic CMake usage

Controlling installation destination

Use relative DESTINATION


One should always use relative installation DESTINATION
unless you really want to use absolute path like /etc.

Then depending on when you install:


At CMake-time set CMAKE INSTALL PREFIX value
$ cmake --help-variable CMAKE_INSTALL_PREFIX
At Install-time use DESTDIR mechanism (Unix Makefiles)
$ make DESTDIR=/tmp/testinstall install

https://github.com/TheErk/CMake-tutorial CMake tutorial


43 / 136
N
Basic CMake usage

Controlling installation destination

Use relative DESTINATION


One should always use relative installation DESTINATION
unless you really want to use absolute path like /etc.

Then depending on when you install:


At CMake-time set CMAKE INSTALL PREFIX value
$ cmake --help-variable CMAKE_INSTALL_PREFIX
At Install-time use DESTDIR mechanism (Unix Makefiles)
$ make DESTDIR=/tmp/testinstall install
At CPack-time, CPack what? . . . be patient.
At Package-install-time, we will see that later
https://github.com/TheErk/CMake-tutorial CMake tutorial
43 / 136
N
Basic CMake usage

The CMake workflow (pictured)


Project file(s),
CMakeLists.txt Object files
Makefiles, . . .

Installed
Source files files

Generated
Sources files
Binary
package
CMake time

Source Build time


package
Install time Installed
CPack time package
Package Install time

https://github.com/TheErk/CMake-tutorial CMake tutorial


44 / 136
N
Basic CMake usage

Using CMake variables

CMake variables
They are used by the user to simplify its CMakeLists.txt,
but CMake uses many (˜400+) of them to control/change its
[default] behavior. Try: cmake --help-variable-list.

Inside a CMake script


set (CMAKE INSTALL PREFIX /home/eric/testinstall)
$ cmake --help-command set

On the command line/TUI/GUI


Remember that (besides options) each CMake tool takes a
single argument (source tree or existing build tree)
$ cmake -DCMAKE_INSTALL_PREFIX=/home/eric/testinstall .
https://github.com/TheErk/CMake-tutorial CMake tutorial
45 / 136
N
Basic CMake usage

The install target

Install target
The install target of the underlying build tool (in our case
make) appears in the generated build system as soon as some
install commands are used in the CMakeLists.txt.
1 $ make DESTDIR=/tmp/testinstall install
2 [ 33%] Built target acrodict
3 [ 66%] Built target Acrodictlibre
4 [100%] Built target Acrolibre
5 Install the project...
6 -- Install configuration: ""
7 -- Installing: /tmp/testinstall/bin/Acrolibre
8 -- Installing: /tmp/testinstall/bin/Acrodictlibre
9 -- Removed runtime path from "/tmp/testinstall/bin/Acrodictlibre"
10 -- Installing: /tmp/testinstall/lib/libacrodict.so
11 -- Installing: /tmp/testinstall/include/acrodict.h
12 $
https://github.com/TheErk/CMake-tutorial CMake tutorial
46 / 136
N
Basic CMake usage

Package the whole thing


CPack
CPack is a CMake friend application (detailed later) which
may be used to easily package your software.

Listing 8: add CPack support $ make package


[ 33%] Built target acrodict
1 ... [ 66%] Built target Acrodictlibre
2 e n d i f (WITH ACRODICT) [100%] Built target Acrolibre
3 ... Run CPack packaging tool...
4 # Near t h e end o f t h e CMakeLists . t x t CPack: Create package using TGZ
5 # Chose y o u r CPack g e n e r a t o r CPack: Install projects
6 s e t (CPACK GENERATOR "TGZ" ) CPack: - Run preinstall target for: TotallyFree
7 # Setup package v e r s i o n CPack: - Install project: TotallyFree
8 s e t (CPACK PACKAGE VERSION MAJOR 0 ) CPack: Create package
9 s e t ( CPACK PACKAGE VERSION MINOR 1 ) CPack: - package: <build-tree>/...
10 s e t ( CPACK PACKAGE VERSION PATCH 0 ) TotallyFree-0.1.0-Linux.tar.gz generated.
11 # ’ c a l l ’ CPack $ tar ztvf TotallyFree-0.1.0-Linux.tar.gz
12 i n c l u d e ( CPack ) ... TotallyFree-0.1.0-Linux/include/acrodict.h
... TotallyFree-0.1.0-Linux/bin/Acrolibre
... TotallyFree-0.1.0-Linux/bin/Acrodictlibre
... TotallyFree-0.1.0-Linux/lib/libacrodict.so

https://github.com/TheErk/CMake-tutorial CMake tutorial


47 / 136
N
Basic CMake usage

CPack the packaging friend

CPack is a standalone generator


As we will see later on, CPack is standalone application, which
like CMake is a generator.
$ cpack -G ZIP $ cpack -G RPM
CPack: Create package using ZIP CPack: Create package using RPM
CPack: Install projects CPack: Install projects
CPack: - Run preinstall target for: TotallyFree CPack: - Run preinstall target for: TotallyFree
CPack: - Install project: TotallyFree CPack: - Install project: TotallyFree
CPack: Create package CPack: Create package
CPack: - package: <build-tree>/... CPackRPM: Will use GENERATED spec file: <build-tree>/...
TotallyFree-0.1.0-Linux.zip generated. _CPack_Packages/Linux/RPM/SPECS/totallyfree.spec
$ unzip -t TotallyFree-0.1.0-Linux.zip CPack: - package: <build-tree>/...
Archive: TotallyFree-0.1.0-Linux.zip TotallyFree-0.1.0-Linux.rpm generated.
testing: To.../include/acrodict.h OK $ rpm -qpl TotallyFree-0.1.0-Linux.rpm
testing: To.../bin/Acrolibre OK /usr
testing: To.../bin/Acrodictlibre OK /usr/bin
testing: To.../lib/libacrodict.so OK /usr/bin/Acrodictlibre
No errors detected in compressed /usr/bin/Acrolibre
data of TotallyFree-0.1.0-Linux.zip. /usr/include
/usr/include/acrodict.h
/usr/lib
/usr/lib/libacrodict.so
https://github.com/TheErk/CMake-tutorial CMake tutorial
48 / 136
N
Basic CMake usage

Didn’t you mentioned testing? I


CTest
CTest is a CMake friend application (detailed later) which
may be used to easily test your software (if not cross-compiled
though).

Listing 9: add CTest support $ make test


Running tests...
1 ... Test project <buildtree-prefix>/build
2 e n d i f (WITH ACRODICT) Start 1: toulibre-builtin
3 ... 1/4 Test #1: toulibre-builtin .... Passed 0.00 sec
4 enable testing ( ) Start 2: toulibre-dict
5 a d d t e s t ( t o u l i b r e −b u i l t i n 2/4 Test #2: toulibre-dict........ Passed 0.00 sec
6 A c r o l i b r e "toulibre" ) Start 3: FLOSS-dict
7 a d d t e s t ( t o u l i b r e −d i c t 3/4 Test #3: FLOSS-dict .......... Passed 0.00 sec
8 A c r o d i c t l i b r e "toulibre" ) Start 4: FLOSS-fail
9 a d d t e s t ( FLOSS−d i c t 4/4 Test #4: FLOSS-fail ..........***Failed 0.00 sec
10 A c r o d i c t l i b r e "FLOSS" ) 75% tests passed, 1 tests failed out of 4
11 a d d t e s t ( FLOSS−f a i l Total Test time (real) = 0.01 sec
12 A c r o l i b r e "FLOSS" ) The following tests FAILED:
4 - FLOSS-fail (Failed)

https://github.com/TheErk/CMake-tutorial CMake tutorial


49 / 136
N
Basic CMake usage

Didn’t you mentioned testing? II


Tailor success rule
CTest uses the return code in order to get success/failure status,
but one can tailor the success/fail rule.

Listing 10: add CTest support $ make test


Running tests...
1 ... Test project <buildtree-prefix>/build
2 e n d i f (WITH ACRODICT) Start 1: toulibre-builtin
3 ... 1/4 Test #1: toulibre-builtin .... Passed 0.00 sec
4 enable testing ( ) Start 2: toulibre-dict
5 a d d t e s t ( t o u l i b r e −b u i l t i n 2/4 Test #2: toulibre-dict........ Passed 0.00 sec
6 A c r o l i b r e "toulibre" ) Start 3: FLOSS-dict
7 a d d t e s t ( t o u l i b r e −d i c t 3/4 Test #3: FLOSS-dict .......... Passed 0.00 sec
8 A c r o d i c t l i b r e "toulibre" ) Start 4: FLOSS-fail
9 a d d t e s t ( FLOSS−d i c t 4/4 Test #4: FLOSS-fail .......... Passed 0.00 sec
10 A c r o d i c t l i b r e "FLOSS" )
11 a d d t e s t ( FLOSS−f a i l 100% tests passed, 0 tests failed out of 4
12 A c r o l i b r e "FLOSS" )
13 s e t t e s t s p r o p e r t i e s ( FLOSS−f a i l Total Test time (real) = 0.01 sec
14 PROPERTIES
15 PASS REGULAR EXPRESSION
16 "Sorry , I don ’t know :.* FLOSS" )

https://github.com/TheErk/CMake-tutorial CMake tutorial


50 / 136
N
Basic CMake usage

CTest the testing friend

CTest is a standalone generic test driver


CTest is standalone application, which can run a set of test
programs.
$ ctest -R toulibre- $ ctest -R FLOSS-fail -V
Test project <build-tree>/build Test project <build-tree>
Start 1: toulibre-builtin Constructing a list of tests
1/2 Test #1: toulibre-builtin .. Passed 0.00 sec Done constructing a list of tests
Start 2: toulibre-dict Checking test dependency graph...
2/2 Test #2: toulibre-dict ..... Passed 0.00 sec Checking test dependency graph end
test 4
100% tests passed, 0 tests failed out of 2 Start 4: FLOSS-fail
4: Test command: <build-tree>/Acrolibre "FLOSS"
Total Test time (real) = 0.01 sec 4: Test timeout computed to be: 9.99988e+06
4: Sorry, I don’t know: <FLOSS>
1/1 Test #4: FLOSS-fail ...........***Failed 0.00 sec

0% tests passed, 1 tests failed out of 1


Total Test time (real) = 0.00 sec

The following tests FAILED:


4 - FLOSS-fail (Failed)
Errors while running CTest
https://github.com/TheErk/CMake-tutorial CMake tutorial
51 / 136
N
Basic CMake usage

CDash the test results publishing

Dashboard
CTest may help publishing the results of the tests on a CDash
dashboard (http://www.cdash.org/) for easing collective
regression testing. More on this later. . .

http://www.orfeo-toolbox.org/–http://dash.orfeo-toolbox.org/

https://github.com/TheErk/CMake-tutorial CMake tutorial


52 / 136
N
Basic CMake usage

Summary

CMake basics
Using CMake basics we can already do a lot of things with
minimal writing.

Write simple build specification file: CMakeLists.txt


Discover compilers (C, C++, Fortran)
Build executable and library (shared or static) in a cross-platform
manner
Package the resulting binaries with CPack
Run systematic tests with CTest and publish them with CDash

https://github.com/TheErk/CMake-tutorial CMake tutorial


53 / 136
N
Basic CMake usage

Seeking more information or help


There are several places you can go by yourself:
1 Read the documentation: https://cmake.org/documentation
(re-)

2 Read the FAQ: https://cmake.org/Wiki/CMake_FAQ


3 Read the Wiki: https://cmake.org/Wiki/CMake
4 Ask on the Mailing List: https://cmake.org/mailing-lists
5 Browse the built-in help:
man cmake-xxxx
cmake --help-xxxxx
assistant -collectionFile examples/CMake.qhc

https://github.com/TheErk/CMake-tutorial CMake tutorial


54 / 136
N
Discovering environment specificities

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


55 / 136
N
Discovering environment specificities

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


56 / 136
N
Discovering environment specificities

How to discover system

System/compiler specific variables


Right after the project command CMake has set up variables
which can be used to tailor the build in a platform specific way.

system specific
WIN32 True on Windows systems, including Win64.
UNIX True for UNIX and UNIX like operating systems.
APPLE True if running on Mac OS X.
CYGWIN True for Cygwin.
Have a look at cmake --system-information output
compiler specific
CMAKE <LANG> COMPILER ID A short string unique to the
compiler vendor : Clang, GNU, MSVC, Cray, Absoft TI, XL. . .

https://github.com/TheErk/CMake-tutorial CMake tutorial


57 / 136
N
Discovering environment specificities

Handle system specific code


Some functions like strcasestr (lines 6 and 7) may not be
available on all platforms.
Listing 11: excerpt from acrodict.c
1 c o n s t a c r o I t e m t ∗ a c r o d i c t g e t a p p r o x ( c o n s t c h a r ∗ name ) {
2 i n t c u r r e n t =0;
3 i n t found =0;
4 #i f d e f GUESS NAME
5 w h i l e ( ( s t r l e n ( a c r o d i c t [ c u r r e n t ] . name) >0) && ! found ) {
6 i f ( ( s t r c a s e s t r ( name , a c r o d i c t [ c u r r e n t ] . name ) ! = 0 ) | |
7 ( s t r c a s e s t r ( a c r o d i c t [ c u r r e n t ] . name , name ) ! = 0 ) ) {
8 found =1;
9 } else {
10 c u r r e n t ++;
11 }
12 }
13 i f ( found ) {
14 r e t u r n &( a c r o d i c t [ c u r r e n t ] ) ;
15 } else
16 #e n d i f
17 {
18 r e t u r n NULL ;
19 }
20 }

https://github.com/TheErk/CMake-tutorial CMake tutorial


58 / 136
N
Discovering environment specificities

Use system specific option

1 # B u i l d o p t i o n w i t h d e f a u l t v a l u e t o ON
2 o p t i o n (WITH ACRODICT "Include acronym dictionary support" ON)
3 i f (NOT WIN32 )
4 o p t i o n (WITH GUESS NAME "Guess acronym name" ON)
5 e n d i f (NOT WIN32 )
6 ...
7 i f (WITH ACRODICT)
8 # l i s t o f sources in our l i b r a r y
9 s e t ( LIBSRC a c r o d i c t . h a c r o d i c t . c )
10 i f (WITH GUESS NAME)
11 s e t s o u r c e f i l e s p r o p e r t i e s ( a c r o d i c t . c PROPERTIES COMPILE FLAGS "-DGUESS_NAME" )
12 e n d i f (WITH GUESS NAME)
13 a d d l i b r a r y ( a c r o d i c t ${LIBSRC } )
14 ...

Line 4 defines a CMake option, but not on WIN32 system. Then


on line 11, if the option is set then we pass a source specific
compile flags.
cmake --help-command set source files properties

https://github.com/TheErk/CMake-tutorial CMake tutorial


59 / 136
N
Discovering environment specificities

System specific in real life

Real [numeric] life project


Real projects (i.e. not the toy of this tutorial) have many parts
of their CMakeLists.txt which deal with system/compiler
specific option/feature.

MuseScore
CERTI, http://git.savannah.gnu.org/cgit/certi.git/tree
SchedMCore, https://svn.onera.fr/schedmcore/trunk/
CMake (of course)
LLVM, http://llvm.org/docs/CMake.html
many more . . .

https://github.com/TheErk/CMake-tutorial CMake tutorial


60 / 136
N
Discovering environment specificities

What about projectConfig.h file? I

Project config files


Sometimes it’s easier to test for features and then write a
configuration file (config.h, project config.h, . . . ). The
CMake way to do that is to:
1 lookup system information using CMake variable, functions,
macros (built-in or imported) then set various variables,
2 use the defined variable in order to write a template
configuration header file
3 then use configure file in order to produce the actual config
file from the template.

https://github.com/TheErk/CMake-tutorial CMake tutorial


61 / 136
N
Discovering environment specificities

What about projectConfig.h file? II


Listing 12: Excerpt from CERTI project’s main CMakeLists.txt
1 # Load C h ec ke r macros
2 INCLUDE ( C h e c k F u n c t i o n E x i s t s )
3
4 FIND FILE ( HAVE STDINT H NAMES s t d i n t . h )
5 FIND FILE ( HAVE SYS SELECT H NAMES s e l e c t . h
6 PATH SUFFIXES s y s )
7 INCLUDE ( C h e c k I n c l u d e F i l e )
8 CHECK INCLUDE FILE ( time . h HAVE TIME H )
9 FIND LIBRARY ( RT LIBRARY r t )
10 i f ( RT LIBRARY )
11 SET( CMAKE REQUIRED LIBRARIES ${CMAKE REQUIRED LIBRARIES} ${RT LIBRARY } )
12 e n d i f ( RT LIBRARY )
13
14 CHECK FUNCTION EXISTS ( c l o c k g e t t i m e HAVE CLOCK GETTIME)
15 CHECK FUNCTION EXISTS ( c l o c k s e t t i m e HAVE CLOCK SETTIME )
16 CHECK FUNCTION EXISTS ( c l o c k g e t r e s HAVE CLOCK GETRES )
17 CHECK FUNCTION EXISTS ( c l o c k n a n o s l e e p HAVE CLOCK NANOSLEEP)
18 IF (HAVE CLOCK GETTIME AND HAVE CLOCK SETTIME AND HAVE CLOCK GETRES )
19 SET( HAVE POSIX CLOCK 1 )
20 ENDIF (HAVE CLOCK GETTIME AND HAVE CLOCK SETTIME AND HAVE CLOCK GETRES )
21 ...
22 CONFIGURE FILE ( ${CMAKE CURRENT SOURCE DIR} / c o n f i g . h . cmake
23 ${CMAKE CURRENT BINARY DIR} / c o n f i g . h )

https://github.com/TheErk/CMake-tutorial CMake tutorial


62 / 136
N
Discovering environment specificities

What about projectConfig.h file? III


Excerpt from CERTI config.h.cmake
1 /* define if the compiler has numeric_limits<T> */
2 #cmakedefine HAVE_NUMERIC_LIMITS
3
4 /* Define to 1 if you have the <stdint.h> header file. */
5 #cmakedefine HAVE_STDINT_H 1
6
7 /* Define to 1 if you have the <stdlib.h> header file. */
8 #cmakedefine HAVE_STDLIB_H 1
9
10 /* Define to 1 if you have the <strings.h> header file. */
11 #cmakedefine HAVE_STRINGS_H 1
12 ...
13 /* Name of package */
14 #cmakedefine PACKAGE "@PACKAGE_NAME@"
15
16 /* Define to the address where bug reports for this package should be sent. */
17 #cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
18
19 /* Define to the full name of this package. */
20 #cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
21
22 /* Define to the full name and version of this package. */
23 #cmakedefine PACKAGE_STRING "@PACKAGE_NAME@-@PACKAGE_VERSION@"

https://github.com/TheErk/CMake-tutorial CMake tutorial


63 / 136
N
Discovering environment specificities

What about projectConfig.h file? IV


And you get something like:
Excerpt from generated CERTI config.h
1 /* define if the compiler has numeric_limits<T> */
2 #define HAVE_NUMERIC_LIMITS
3
4 /* Define to 1 if you have the <stdint.h> header file. */
5 #define HAVE_STDINT_H 1
6
7 /* Define to 1 if you have the <stdlib.h> header file. */
8 #define HAVE_STDLIB_H 1
9
10 /* Define to 1 if you have the <strings.h> header file. */
11 #define HAVE_STRINGS_H 1
12 ...
13 /* Name of package */
14 /* #undef PACKAGE */
15
16 /* Define to the address where bug reports for this package should be sent. */
17 #define PACKAGE_BUGREPORT "certi-devel@nongnu.org"
18
19 /* Define to the full name of this package. */
20 #define PACKAGE_NAME "CERTI"
21
22 /* Define to the full name and version of this package. */
23 /* #undef PACKAGE_STRING */

https://github.com/TheErk/CMake-tutorial CMake tutorial


64 / 136
N
Discovering environment specificities

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


65 / 136
N
Discovering environment specificities

The find package command I

Finding external package


Project may be using external libraries, programs, files
etc. . . Those can be found using the find package command.

Listing 13: using libxml2


1 f i n d p a c k a g e ( LibXml2 )
2 i f ( LIBXML2 FOUND )
3 a d d d e f i n i t i o n s (−DHAVE XML ${LIBXML2 DEFINITIONS } )
4 i n c l u d e d i r e c t o r i e s ( ${LIBXML2 INCLUDE DIR } )
5 e l s e ( LIBXML2 FOUND )
6 s e t ( LIBXML2 LIBRARIES "" )
7 e n d i f ( LIBXML2 FOUND )
8 ...
9 t a r g e t l i n k l i b r a r i e s ( MyTarget ${LIBXML2 LIBRARIES } )

https://github.com/TheErk/CMake-tutorial CMake tutorial


66 / 136
N
Discovering environment specificities

The find package command II


Find modules usually define standard variables (for module XXX)
1 XXX FOUND: Set to false, or undefined, if we haven’t found, or don’t
want to use XXX.
2 XXX INCLUDE DIRS: The final set of include directories listed in one
variable for use by client code.
3 XXX LIBRARIES: The libraries to link against to use XXX. These
should include full paths.
4 XXX DEFINITIONS: Definitions to use when compiling code that uses
XXX.
5 XXX EXECUTABLE: File location of the XXX tool’s binary.
6 XXX LIBRARY DIRS: Optionally, the final set of library directories
listed in one variable for use by client code.

See doc cmake --help-module FindLibXml2


Many modules are provided by CMake (230 as of CMake 3.6.2)

https://github.com/TheErk/CMake-tutorial CMake tutorial


67 / 136
N
Discovering environment specificities

The find package command III


Projects which are built with CMake usually provide a Project
Config file see doc: https://cmake.org/cmake/help/
git-master/manual/cmake-packages.7.html
You may write your own:
https://cmake.org/Wiki/CMake:Module_Maintainers
A module may provide not only CMake variables but new CMake
macros (we will see that later with the MACRO, FUNCTION
CMake language commands)

https://github.com/TheErk/CMake-tutorial CMake tutorial


68 / 136
N
Discovering environment specificities

The other find xxxx commands

The find xxx command family


find package is a high level module finding mechanism but
there are lower-level CMake commands which may be used to
write find modules or anything else inside CMakeLists.txt

to find an executable program: find program


to find a library: find library
to find any kind of file: find file
to find a path where a file resides: find path

https://github.com/TheErk/CMake-tutorial CMake tutorial


69 / 136
N
Discovering environment specificities

FindPrelude.cmake example I
The FindPrelude.cmake is part of the Prelude synchronous
language compiler made by ONERA:
https://forge.onera.fr/projects/Prelude. This a
source-to-source compiler which takes as input prelude file
(.plul) and generates a bunch of C files which may be compiled
in a dynamic library. The FindPrelude.cmake helps to
automatize this task.

https://github.com/TheErk/CMake-tutorial CMake tutorial


70 / 136
N
Discovering environment specificities

FindPrelude.cmake example II
1 # − Find P r e l u d e c o m p i l e r
2 # Find t h e P r e l u d e s y n c h r o n o u s language c o m p i l e r w i t h a s s o c i a t e d i n c l u d e s p a t h .
3 # See h t t p : / / www . l i f l . f r / ˜ f o r g e t / p r e l u d e . h t m l
4 # and h t t p s : / / f o r g e . o n e r a . f r / p r o j e c t s / p r e l u d e
5 # T h i s module d e f i n e s
6 # PRELUDE COMPILER , t h e p r e l u d e c o m p i l e r
7 # PRELUDE COMPILER VERSION , t h e v e r s i o n o f t h e p r e l u d e c o m p i l e r
8 # PRELUDE INCLUDE DIR , where t o f i n d dword . h , e t c .
9 # PRELUDE FOUND, I f f a l s e , P r e l u d e was n o t f o u n d .
10 # On can s e t PRELUDE PATH HINT b e f o r e u s i n g f i n d p a c k a g e ( P r e l u d e ) and t h e
11 # module w i t h use t h e PATH as a h i n t t o f i n d p r e l u d e c .
12 #
13 # The h i n t can be g i v e n on t h e command l i n e t o o :
14 # cmake −DPRELUDE PATH HINT=/DATA/ ERIC / P r e l u d e / p r e l u d e−x . y / p a t h / t o / s o u r c e
15 #
16 # The module d e f i n e s some f u n c t i o n s :
17 # P r e l u d e C o m p i l e (NODE <P r e l u d e Main Node>
18 # PLU FILES <P r e l u d e f i l e s >
19 # [ USER C FILES <C f i l e s >]
20 # [ NOENCODING ]
21 # [ REAL IS DOUBLE ]
22 # [ BOOL IS STDBOOL ]
23 # [ TRACING f m t ] )
24 #

https://github.com/TheErk/CMake-tutorial CMake tutorial


71 / 136
N
Discovering environment specificities

FindPrelude.cmake example III


25
26 i f ( PRELUDE PATH HINT )
27 message (STATUS "FindPrelude: using PATH HINT: ${PRELUDE_PATH_HINT}" )
28 else ( )
29 s e t ( PRELUDE PATH HINT )
30 endif ( )
31
32 #One can add h i s / h e r own b u i l t i n PATH .
33 #FILE ( TO CMAKE PATH ” / DATA/ ERIC / P r e l u d e / p r e l u d e−x . y ” MYPATH)
34 # l i s t (APPEND PRELUDE PATH HINT ${MYPATH} )
35
36 # FIND PROGRAM t w i c e u s i n g NO DEFAULT PATH on f i r s t s h o t
37 f i n d p r o g r a m ( PRELUDE COMPILER
38 NAMES p r e l u d e c
39 PATHS ${PRELUDE PATH HINT}
40 PATH SUFFIXES b i n
41 NO DEFAULT PATH
42 DOC "Path to the Prelude compiler command ’preludec ’" )
43
44 f i n d p r o g r a m ( PRELUDE COMPILER
45 NAMES p r e l u d e c
46 PATHS ${PRELUDE PATH HINT}
47 PATH SUFFIXES b i n
48 DOC "Path to the Prelude compiler command ’preludec ’" )
49

https://github.com/TheErk/CMake-tutorial CMake tutorial


72 / 136
N
Discovering environment specificities

FindPrelude.cmake example IV
50 i f ( PRELUDE COMPILER )
51 # g e t t h e p a t h where t h e p r e l u d e c o m p i l e r was f o u n d
52 g e t f i l e n a m e c o m p o n e n t (PRELUDE PATH ${PRELUDE COMPILER} PATH)
53 # remove b i n
54 g e t f i l e n a m e c o m p o n e n t (PRELUDE PATH ${PRELUDE PATH} PATH)
55 # add p a t h t o PRELUDE PATH HINT
56 l i s t (APPEND PRELUDE PATH HINT ${PRELUDE PATH} )
57 e x e c u t e p r o c e s s (COMMAND ${PRELUDE COMPILER} −v e r s i o n
58 OUTPUT VARIABLE PRELUDE COMPILER VERSION
59 OUTPUT STRIP TRAILING WHITESPACE )
60 message (STATUS "Prelude compiler version is : ${PRELUDE_COMPILER_VERSION}" )
61 e x e c u t e p r o c e s s (COMMAND ${PRELUDE COMPILER} −h e l p
62 OUTPUT VARIABLE PRELUDE OPTIONS LIST
63 OUTPUT STRIP TRAILING WHITESPACE )
64 s e t ( PRELUDE TRACING OPTION )
65 s t r i n g (REGEX MATCH "-tracing output" PRELUDE TRACING OPTION "${PRELUDE_OPTIONS_LIST}" )
66 i f ( PRELUDE TRACING OPTION )
67 message (STATUS "Prelude compiler support -tracing." )
68 s e t (PRELUDE SUPPORT TRACING "YES" )
69 e l s e ( PRELUDE TRACING OPTION )
70 message (STATUS "Prelude compiler DOES NOT support -tracing." )
71 s e t (PRELUDE SUPPORT TRACING "NO" )
72 e n d i f ( PRELUDE TRACING OPTION )
73 e n d i f ( PRELUDE COMPILER )
74

https://github.com/TheErk/CMake-tutorial CMake tutorial


73 / 136
N
Discovering environment specificities

FindPrelude.cmake example V
75 f i n d p a t h ( PRELUDE INCLUDE DIR
76 NAMES dword . h
77 PATHS ${PRELUDE PATH HINT}
78 PATH SUFFIXES l i b / p r e l u d e
79 DOC "The Prelude include headers" )
80
81 # Check i f LTTng i s t o be s u p p o r t e d
82 i f (NOT LTTNG FOUND)
83 o p t i o n (ENABLE LTTNG SUPPORT "Enable LTTng support" OFF)
84 i f (ENABLE LTTNG SUPPORT)
85 f i n d p a c k a g e ( LTTng )
86 i f (LTTNG FOUND)
87 message (STATUS "Will build LTTng support into library ..." )
88 i n c l u d e d i r e c t o r i e s ( ${LTTNG INCLUDE DIR } )
89 e n d i f (LTTNG FOUND)
90 e n d i f (ENABLE LTTNG SUPPORT)
91 endif ( )
92
93 # Macros used t o c o m p i l e a p r e l u d e l i b r a r y
94 i n c l u d e ( CMakeParseArguments )
95 f u n c t i o n ( Prelude Compile )
96 s e t ( o p t i o n s NOENCODING REAL IS DOUBLE BOOL IS STDBOOL )
97 s e t ( oneValueArgs NODE TRACING )
98 s e t ( m u l t i V a l u e A r g s PLU FILES USER C FILES )
99 cmake parse arguments (PLU "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )

https://github.com/TheErk/CMake-tutorial CMake tutorial


74 / 136
N
Discovering environment specificities

FindPrelude.cmake example VI
100
101 i f (PLU NOENCODING)
102 s e t (PRELUDE ENCODING "-no_encoding" )
103 s e t ( PRELUDE OUTPUT DIR "${ CMAKE_CURRENT_BINARY_DIR }/${PLU_NODE }/ noencoding" )
104 s e t ( PRELUDE ENCODING SUFFIX "-noencoding" )
105 else ( )
106 s e t (PRELUDE ENCODING)
107 s e t ( PRELUDE OUTPUT DIR "${ CMAKE_CURRENT_BINARY_DIR }/${PLU_NODE }/ encoded" )
108 s e t ( PRELUDE ENCODING SUFFIX "-encoded" )
109 endif ( )
110
111 i f ( PLU REAL IS DOUBLE )
112 s e t ( PRELUDE REAL OPT "-real_is_double" )
113 else ( )
114 s e t ( PRELUDE REAL OPT "" )
115 endif ( )
116
117 i f ( PLU BOOL IS STDBOOL )
118 s e t (PRELUDE BOOL OPT "-bool_is_stdbool" )
119 else ( )
120 s e t (PRELUDE BOOL OPT "" )
121 endif ( )
122
123 i f (PRELUDE SUPPORT TRACING)
124 i f ( PLU TRACING )

https://github.com/TheErk/CMake-tutorial CMake tutorial


75 / 136
N
Discovering environment specificities

FindPrelude.cmake example VII


125 s e t ( PRELUDE TRACING OPT "-tracing" )
126 s e t ( PRELUDE TRACING OPT VALUE "${PLU_TRACING}" )
127 else ( )
128 s e t ( PRELUDE TRACING OPT "-tracing" )
129 s e t ( PRELUDE TRACING OPT VALUE "no" )
130 endif ( )
131 e l s e (PRELUDE SUPPORT TRACING)
132 s e t ( PRELUDE TRACING OPT "" )
133 s e t ( PRELUDE TRACING OPT VALUE "" )
134 e n d i f (PRELUDE SUPPORT TRACING)
135
136 f i l e (MAKE DIRECTORY ${PRELUDE OUTPUT DIR} )
137 s e t ( PRELUDE GENERATED FILES
138 ${PRELUDE OUTPUT DIR} / ${PLU NODE } . c
139 ${PRELUDE OUTPUT DIR} / ${PLU NODE } . h )
140
141 add custom command (
142 OUTPUT ${PRELUDE GENERATED FILES}
143 COMMAND ${PRELUDE COMPILER} ${PRELUDE ENCODING} ${PRELUDE BOOL OPT} ${PRELUDE REAL OPT}
144 DEPENDS ${PLU PLU FILES}
145 WORKING DIRECTORY ${CMAKE CURRENT SOURCE DIR}
146 COMMENT "Compile prelude source(s): ${PLU_PLU_FILES })"
147 )
148 s e t s o u r c e f i l e s p r o p e r t i e s ( ${PRELUDE GENERATED FILES}
149 PROPERTIES GENERATED TRUE)

https://github.com/TheErk/CMake-tutorial CMake tutorial


76 / 136
N
Discovering environment specificities

FindPrelude.cmake example VIII


150 i n c l u d e d i r e c t o r i e s ( ${PRELUDE INCLUDE DIR} ${CMAKE CURRENT SOURCE DIR} ${PRELUDE OUTPUT DIR}
151 a d d l i b r a r y ( ${PLU NODE}${PRELUDE ENCODING SUFFIX} SHARED
152 ${PRELUDE GENERATED FILES} ${PLU USER C FILES}
153 )
154 i f (LTTNG FOUND)
155 t a r g e t l i n k l i b r a r i e s ( ${PLU NODE}${PRELUDE ENCODING SUFFIX} ${LTTNG LIBRARIES } )
156 endif ( )
157 message (STATUS "Prelude: Added rule for building prelude library: ${PLU_NODE}" )
158 endfunction ( Prelude Compile )
159
160 # h a n d l e t h e QUIETLY and REQUIRED a r g u m e n t s and s e t PRELUDE FOUND t o TRUE i f
161 # a l l l i s t e d v a r i a b l e s a r e TRUE
162 i n c l u d e ( FindPackageHandleStandardArgs )
163 FIND PACKAGE HANDLE STANDARD ARGS(PRELUDE
164 REQUIRED VARS PRELUDE COMPILER PRELUDE INCLUDE DIR )
165 # VERSION FPHSA o p t i o n s n o t h a n d l e d by CMake v e r s i o n < 2 . 8 . 2 )
166 # VERSION VAR PRELUDE COMPILER VERSION )
167 ma rk as ad vanced ( PRELUDE INCLUDE DIR )

https://github.com/TheErk/CMake-tutorial CMake tutorial


77 / 136
N
Discovering environment specificities

Advanced use of external package I

Installed External package


The previous examples suppose that you have the package you
are looking for on your host.
you did install the runtime libraries
you did install eventual developer libraries, headers and tools

What if the external packages:


are only available as source (tarball, VCS repositories, . . . )
use a build system (autotools or CMake or . . . )

https://github.com/TheErk/CMake-tutorial CMake tutorial


78 / 136
N
Discovering environment specificities

Advanced use of external package II


ExternalProject Add
The ExternalProject.cmake CMake module defines a high-
level macro which does just that:
1 download/checkout source
2 update/patch
3 configure
4 build
5 install (and test)

. . . an external project

$ cmake --help-module ExternalProject

https://github.com/TheErk/CMake-tutorial CMake tutorial


79 / 136
N
More CMake scripting

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


80 / 136
N
More CMake scripting

The different CMake “modes”

Normal mode: the mode used when processing CMakeLists.txt


Command mode: cmake -E <command>, command line mode which
offers basic commands in a portable way:

Process scripting mode: cmake -P <script>, used to execute a


CMake script which is not a CMakeLists.txt filename.

Wizard mode: cmake -i, interactive equivalent of the Normal


mode.

https://github.com/TheErk/CMake-tutorial CMake tutorial


81 / 136
N
More CMake scripting

The different CMake “modes”

Normal mode: the mode used when processing CMakeLists.txt


Command mode: cmake -E <command>, command line mode which
offers basic commands in a portable way:
works on all supported CMake platforms. I.e. you don’t want to
rely on shell or native command interpreter capabilities.
Process scripting mode: cmake -P <script>, used to execute a
CMake script which is not a CMakeLists.txt filename.

Wizard mode: cmake -i, interactive equivalent of the Normal


mode.

https://github.com/TheErk/CMake-tutorial CMake tutorial


81 / 136
N
More CMake scripting

The different CMake “modes”

Normal mode: the mode used when processing CMakeLists.txt


Command mode: cmake -E <command>, command line mode which
offers basic commands in a portable way:
works on all supported CMake platforms. I.e. you don’t want to
rely on shell or native command interpreter capabilities.
Process scripting mode: cmake -P <script>, used to execute a
CMake script which is not a CMakeLists.txt filename.
Not all CMake commands are scriptable!!
Wizard mode: cmake -i, interactive equivalent of the Normal
mode.

https://github.com/TheErk/CMake-tutorial CMake tutorial


81 / 136
N
More CMake scripting

Command mode
list of command mode commands
1 $ cmake -E
2 CMake Error: cmake version 3.6.2
3 Usage: cmake -E <command> [arguments...]
4 Available commands:
5 chdir dir cmd [args...] - run command in a given directory
6 compare_files file1 file2 - check if file1 is same as file2
7 copy <file>... destination - copy files to destination (either file or directory)
8 copy_directory <dir>... destination - copy content of <dir>... directories to ’destination’ directory
9 copy_if_different <file>... destination - copy files if it has changed
10 echo [<string>...] - displays arguments as text
11 echo_append [<string>...] - displays arguments as text but no new line
12 env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...
13 - run command in a modified environment
14 environment - display the current environment
15 make_directory <dir>... - create parent and <dir> directories
16 md5sum <file>... - create MD5 checksum of files
17 remove [-f] <file>... - remove the file(s), use -f to force it
18 remove_directory dir - remove a directory and its contents
19 rename oldname newname - rename a file or directory (on one volume)
20 tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]
21 - create or extract a tar or zip archive
22 sleep <number>... - sleep for given number of seconds
23 time command [args...] - run command and return elapsed time
24 touch file - touch a file.
25 touch_nocreate file - touch a file but do not create it.
26 Available on UNIX only:
27 create_symlink old new - create a symbolic link new -> old
https://github.com/TheErk/CMake-tutorial CMake tutorial
82 / 136
N
More CMake scripting

CMake scripting

Overview of CMake language


CMake is a declarative language which contains 90+
commands. It contains general purpose constructs: set , unset,
if , elseif , else , endif, foreach, while, break see cmake-
language(7

Remember:
1 $ cmake --help-command-list
2 $ cmake --help-command <command-name>
3 $ cmake --help-command message
4 cmake version 2.8.7
5 message
6 Display a message to the user.
7 message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR]
8 "message to display" ...)
9 The optional keyword determines the type of message:
10 (none) = Important information
11 STATUS = Incidental information
12 WARNING = CMake Warning, continue processing
13 AUTHOR_WARNING = CMake Warning (dev), continue processing
14 SEND_ERROR = CMake Error, continue but skip generation
https://github.com/TheErk/CMake-tutorial CMake tutorial
15 FATAL_ERROR = CMake Error, stop all processing 83 / 136
N
More CMake scripting

Higher level commands as well

file manipulation with file : READ, WRITE, APPEND,


RENAME, REMOVE, MAKE DIRECTORY

advanced files operations: GLOB, GLOB RECURSE file name in a


path, DOWNLOAD, UPLOAD
working with path: file (TO CMAKE PATH /TO NATIVE PATH ...),
get filename component
execute an external process (with stdout, stderr and return code
retrieval): execute process
builtin list manipulation command: list with sub-commands
LENGTH, GET, APPEND, FIND, APPEND, INSERT,
REMOVE ITEM, REMOVE AT, REMOVE DUPLICATES REVERSE, SORT

string manipulation: string , upper/lower case conversion, length,


comparison, substring, regular expression match, . . .

https://github.com/TheErk/CMake-tutorial CMake tutorial


84 / 136
N
More CMake scripting

Portable script for building CMake I


As an example of what can be done with pure CMake script
(script mode) here is a script for building the CMake package
using a previously installed CMake.
1 # Simple cmake s c r i p t which may be used t o b u i l d
2 # cmake f r o m a u t o m a t i c a l l y downloaded s o u r c e
3 #
4 # cd tmp /
5 # cmake −P CMake−a u t o b u i l d−v2 . cmake
6 # you s h o u l d end up w i t h a
7 # tmp / cmake−x . y . z s o u r c e t r e e
8 # tmp / cmake−x . y . z−b u i l d b u i l d t r e e
9 # c o n f i g u r e and c o m p i l e d t r e e , u s i n g t h e t a r b a l l f o u n d on K i t w a r e .
10 #
11 # i f you a c c e s s t h e i n t e r n e t t h r o u g h a p r o x y t h e n you s h o u l d
12 # s e t t h e ” h t t p p r o x y ” and ” h t t p s p r o x y ” e n v i r o n m e n t v a r i a b l e
13 # t o a p p p r o p r i a t e v a l u e b e f o r e r u n n i n g t h e CMake s c r i p t .
14 # e.g.:
15 # e x p o r t h t t p p r o x y=h t t p : / / myproxy . mydomain . f r : 8 0
16 # e x p o r t h t t p s p r o x y=h t t p s : / / myproxy . mydomain . f r : 8 0
17
18

https://github.com/TheErk/CMake-tutorial CMake tutorial


85 / 136
N
More CMake scripting

Portable script for building CMake II


19 cmake minimum required (VERSION 3 . 0 )
20 s e t (CMAKE VERSION "3.6.2" )
21 s e t ( CMAKE FILE PREFIX "cmake -${CMAKE_VERSION}" )
22 s t r i n g (REGEX MATCH "[0 -9]\\.[0 -9]" CMAKE MAJOR "${CMAKE_VERSION}" )
23 s e t (CMAKE REMOTE PREFIX "http :// www.cmake.org/files/v${CMAKE_MAJOR }/" )
24 s e t ( CMAKE FILE SUFFIX ".tar.gz" )
25 s e t ( CMAKE BUILD TYPE "Debug" )
26 s e t ( CMAKE BUILD QTDIALOG "ON" )
27 s e t (CMAKE BUILD GENERATOR "" )
28 #t r y N i n j a ( h t t p s : / / n i n j a−b u i l d . o r g ) i f you have i t i n s t a l l e d
29 #s e t ( CMAKE BUILD GENERATOR ”−GNinja ” )
30 s e t (CPACK GEN "TGZ" )
31 #t r y a n o t h e r CPack g e n e r a t o r
32 s e t (CPACK GEN "RPM" )
33
34 s e t ( LOCAL FILE "./${CMAKE_FILE_PREFIX}${CMAKE_FILE_SUFFIX}" )
35 s e t ( REMOTE FILE "${CMAKE_REMOTE_PREFIX}${CMAKE_FILE_PREFIX}${CMAKE_FILE_SUFFIX}" )
36
37 message (STATUS "Trying to autoinstall CMake version ${CMAKE_VERSION} using ${
REMOTE_FILE} file ..." )
38
39 message (STATUS "Downloading ..." )
40 i f ( EXISTS ${LOCAL FILE } )
41 message (STATUS "Already there: nothing to do" )
42 e l s e ( EXISTS ${LOCAL FILE } )

https://github.com/TheErk/CMake-tutorial CMake tutorial


86 / 136
N
More CMake scripting

Portable script for building CMake III


43 message (STATUS "Not there , trying to download ..." )
44 f i l e (DOWNLOAD ${REMOTE FILE} ${LOCAL FILE}
45 TIMEOUT 600
46 STATUS DL STATUS
47 LOG DL LOG
48 SHOW PROGRESS)
49 l i s t (GET DL STATUS 0 DL NOK)
50 i f ( "${DL_LOG}" MATCHES "404 Not Found" )
51 s e t (DL NOK 1 )
52 e n d i f ( "${DL_LOG}" MATCHES "404 Not Found" )
53 i f (DL NOK)
54 # we s h a l l remove t h e f i l e because i t i s c r e a t e d
55 # w i t h an i n a p p r o p r i a t e c o n t e n t
56 f i l e (REMOVE ${LOCAL FILE } )
57 message (SEND ERROR "Download failed: ${DL_LOG}" )
58 e l s e (DL NOK)
59 message (STATUS "Download successful." )
60 e n d i f (DL NOK)
61 e n d i f ( EXISTS ${LOCAL FILE } )
62
63 message (STATUS "Unarchiving the file" )
64 e x e c u t e p r o c e s s (COMMAND ${CMAKECOMMAND} −E t a r z x v f ${LOCAL FILE}
65 RESULT VARIABLE UNTAR RES
66 OUTPUT VARIABLE UNTAR OUT
67 ERROR VARIABLE UNTAR ERR

https://github.com/TheErk/CMake-tutorial CMake tutorial


87 / 136
N
More CMake scripting

Portable script for building CMake IV


68 )
69 message (STATUS "CMake version ${CMAKE_VERSION} has been unarchived in ${
CMAKE_CURRENT_SOURCE_DIR }/${CMAKE_FILE_PREFIX }." )
70
71 message (STATUS "Configuring with CMake (build type=${CMAKE_BUILD_TYPE}, QtDialog=${
CMAKE_BUILD_QTDIALOG}, build generator=${CMAKE_BUILD_GENERATOR })..." )
72 f i l e (MAKE DIRECTORY ${CMAKE FILE PREFIX}−b u i l d )
73 e x e c u t e p r o c e s s (COMMAND ${CMAKECOMMAND} ${CMAKE BUILD GENERATOR} −DCMAKE BUILD TYPE=
${CMAKE BUILD TYPE} −DBUILD QtDialog :BOOL=${CMAKE BUILD QTDIALOG} . . / ${
CMAKE FILE PREFIX}
74 WORKING DIRECTORY ${CMAKE FILE PREFIX}−b u i l d
75 RESULT VARIABLE CONFIG RES
76 OUTPUT VARIABLE CONFIG OUT
77 ERROR VARIABLE CONFIG ERR
78 TIMEOUT 200
79 )
80 i f ( CONFIG RES )
81 message (ERROR "Configuration failed: ${CONFIG_OUT} / ${CONFIG_ERR}" )
82 endif ( )
83
84 message (STATUS "Building with cmake --build ..." )
85 e x e c u t e p r o c e s s (COMMAND ${CMAKECOMMAND} −−b u i l d .
86 WORKING DIRECTORY ${CMAKE FILE PREFIX}−b u i l d
87 RESULT VARIABLE CONFIG RES
88 OUTPUT VARIABLE CONFIG OUT

https://github.com/TheErk/CMake-tutorial CMake tutorial


88 / 136
N
More CMake scripting

Portable script for building CMake V


89 ERROR VARIABLE CONFIG ERR
90 )
91
92 message (STATUS "Create package ${CPACK_GEN} with CPack ..." )
93 e x e c u t e p r o c e s s (COMMAND ${CMAKE CPACK COMMAND} −G ${CPACK GEN}
94 WORKING DIRECTORY ${CMAKE FILE PREFIX}−b u i l d
95 RESULT VARIABLE CONFIG RES
96 OUTPUT VARIABLE CONFIG OUT
97 ERROR VARIABLE CONFIG ERR
98 )
99 message (STATUS "CMake version ${CMAKE_VERSION} has been built in ${
CMAKE_CURRENT_SOURCE_DIR }/${CMAKE_FILE_PREFIX }." )
100 s t r i n g (REGEX MATCH "CPack: - package :(.*) generated" PACKAGES "${CONFIG_OUT}" )
101 message (STATUS "CMake package(s) are: ${CMAKE_MATCH_1}" )

https://github.com/TheErk/CMake-tutorial CMake tutorial


89 / 136
N
More CMake scripting

Portable script for building ROSACE


Case Study
Another example taken from the “ROSACE Open Source Case
Study” may be found here see ROSACE-CaseStudy-auto.cmake
The script:
Download or checkout Lustre compiler and build it
Download or checkout Prelude compiler and build it
Download or checkout SchedMCore toolsuit and build it
Checkout the ROSACE Case Study and build it using the
previously built tools.

https://github.com/TheErk/CMake-tutorial CMake tutorial


90 / 136
N
More CMake scripting

Build specific commands

create executable or library: add executable, add library


add compiler/linker definitions/options: add definitions ,
include directories , target link libraries
powerful installation specification: install
probing command: try compile , try run
fine control of various properties: set target properties ,
set source files properties , set directory properties ,
set tests properties , set property : 300+ different properties
may be used.

$ cmake --help-property-list
$ cmake --help-property COMPILE_FLAGS

https://github.com/TheErk/CMake-tutorial CMake tutorial


91 / 136
N
More CMake scripting

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


92 / 136
N
More CMake scripting

What are CMake targets?

CMake target
Many times in the documentation you may read about CMake
target. A target is something that CMake should build (i.e.
generate something enabling the building of the target).
A CMake target has dependencies and properties.

1 Executables are targets: add executable


2 Libraries are targets: add library
3 There exist some builtin targets: install, clean, package, . . .
4 You may create custom targets: add custom target

https://github.com/TheErk/CMake-tutorial CMake tutorial


93 / 136
N
More CMake scripting

Target dependencies and properties I


A CMake target has dependencies and properties.

Dependencies
Most of the time, source dependencies are computed from
target specifications using CMake builtin dependency scanner
(C, C++, Fortran) whereas library dependencies are inferred
via target link libraries specification.

If this is not enough then one can use add dependencies, or some
properties.

https://github.com/TheErk/CMake-tutorial CMake tutorial


94 / 136
N
More CMake scripting

Target dependencies and properties II


Properties
Properties may be attached to either target or source file (or
even test). They may be used to tailor the prefix or suffix to
be used for libraries, compile flags, link flags, linker language,
shared libraries version, . . .

see : set target properties or set source files properties


Sources vs Targets
Properties set to a target like COMPILE FLAGS are used for
all sources of the concerned target. Properties set to a source
are used for the source file itself (which may be involved in
several targets).

https://github.com/TheErk/CMake-tutorial CMake tutorial


95 / 136
N
More CMake scripting

Custom targets and commands

Custom
Custom targets and custom commands are a way to create a
target which may be used to execute arbitrary commands at
Build-time.
for target : add custom target
for command : add custom command, in order to add some
custom build step to another (existing) target.

This is usually for: generating source files (Flex, Bison) or other


files derived from source like embedded documentation (Doxygen),
...

https://github.com/TheErk/CMake-tutorial CMake tutorial


96 / 136
N
More CMake scripting

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


97 / 136
N
More CMake scripting

Generated files

List all the sources


CMake advocates to specify all the source files explicitly (i.e.
do not use file (GLOB ...)) This is the only way to keep robust
dependencies. Moreover you usually already need to do that
when using a VCS (CVS, Subversion, Git, hg,. . . ).

However some files may be generated during the build (using


add custom xxx), in which case you must tell CMake that they
are GENERATED files using:
1 s e t s o u r c e f i l e s p r o p e r t i e s ( ${SOME GENERATED FILES}
2 PROPERTIES GENERATED TRUE)

https://github.com/TheErk/CMake-tutorial CMake tutorial


98 / 136
N
More CMake scripting

The CMake workflow (pictured)


Project file(s),
CMakeLists.txt Object files
Makefiles, . . .

Installed
Source files files

Generated
Sources files
Binary
package
CMake time

Source Build time


package
Install time Installed
CPack time package
Package Install time

https://github.com/TheErk/CMake-tutorial CMake tutorial


99 / 136
N
More CMake scripting

Example I
1 ### Handle Source g e n e r a t i o n f o r t a s k f i l e p a r s e r
2 i n c l u d e d i r e c t o r i e s ( ${CMAKE CURRENT SOURCE DIR} )
3 f i n d p a c k a g e ( LexYacc )
4 s e t ( YACC SRC ${CMAKE CURRENT SOURCE DIR} / l s m c t a s k f i l e s y n t a x . yy )
5 s e t ( YACC OUT PREFIX ${CMAKE CURRENT BINARY DIR} / y . tab )
6 s e t (YACC WANTED OUT PREFIX ${CMAKE CURRENT BINARY DIR} / l s m c t a s k f i l e s y n t a x )
7 s e t ( LEX SRC ${CMAKE CURRENT SOURCE DIR} / l s m c t a s k f i l e t o k e n s . l l )
8 s e t ( LEX OUT PREFIX ${CMAKE CURRENT BINARY DIR} / l s m c t a s k f i l e t o k e n s y y )
9 s e t ( LEX WANTED OUT PREFIX ${CMAKE CURRENT BINARY DIR} / l s m c t a s k f i l e t o k e n s )
10
11 #Exec Lex
12 add custom command (
13 OUTPUT ${LEX WANTED OUT PREFIX } . c
14 COMMAND ${LEX PROGRAM} ARGS −l −o${LEX WANTED OUT PREFIX } . c ${LEX SRC}
15 DEPENDS ${LEX SRC}
16 )
17 s e t (GENERATED SRCS ${GENERATED SRCS} ${LEX WANTED OUT PREFIX } . c )
18 #Exec Yacc
19 add custom command (
20 OUTPUT ${YACC WANTED OUT PREFIX } . c ${YACC WANTED OUT PREFIX } . h
21 COMMAND ${YACC PROGRAM} ARGS ${YACC COMPAT ARG} −d ${YACC SRC}
22 COMMAND ${CMAKECOMMAND} −E copy ${YACC OUT PREFIX } . h ${YACC WANTED OUT PREFIX } . h
23 COMMAND ${CMAKECOMMAND} −E copy ${YACC OUT PREFIX } . c ${YACC WANTED OUT PREFIX } . c
24 DEPENDS ${YACC SRC}

https://github.com/TheErk/CMake-tutorial CMake tutorial


100 / 136
N
More CMake scripting

Example II
25 )
26 s e t (GENERATED SRCS ${GENERATED SRCS}
27 ${YACC WANTED OUT PREFIX } . c ${YACC WANTED OUT PREFIX } . h )
28 # T e l l CMake t h a t some f i l e a r e g e n e r a t e d
29 s e t s o u r c e f i l e s p r o p e r t i e s ( ${GENERATED SRCS} PROPERTIES GENERATED TRUE)
30
31 # I n h i b i t c o m p i l e r w a r n i n g f o r LEX / YACC g e n e r a t e d f i l e s
32 # Note t h a t t h e i n h i b i t i o n i s COMPILER d ep e n de n t . . .
33 # GNU CC s p e c i f i c w a r n i n g s t o p
34 i f ( CMAKE COMPILER IS GNUCC )
35 message (STATUS "INHIBIT Compiler warning for LEX/YACC generated files" )
36 SET SOURCE FILES PROPERTIES ( ${YACC WANTED OUT PREFIX } . c ${YACC WANTED OUT PREFIX } . h
37 PROPERTIES COMPILE FLAGS "-w" )
38
39 SET SOURCE FILES PROPERTIES ( ${LEX WANTED OUT PREFIX } . c
40 PROPERTIES COMPILE FLAGS "-w" )
41 e n d i f ( CMAKE COMPILER IS GNUCC )
42 ...
43 s e t ( LSCHED SRC
44 lsmc dependency . c l s m c c o r e . c l s m c u t i l s . c
45 lsmc time . c l s m c t a s k f i l e p a r s e r . c
46 ${GENERATED SRCS} )
47 a d d l i b r a r y ( lsmc ${LSCHED SRC} )

https://github.com/TheErk/CMake-tutorial CMake tutorial


101 / 136
N
Advanced CMake usage

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


102 / 136
N
Advanced CMake usage

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


103 / 136
N
Advanced CMake usage

Cross-compiling

Definition: Cross-compiling
Cross-compiling is when the host system, the one the compiler
is running on, is not the same as the target system, the one
the compiled program will be running on.

CMake can handle cross-compiling using a Toolchain description


file, see https://cmake.org/Wiki/CMake_Cross_Compiling.
1 mkdir build-win32
2 cd build-win32
3 cmake -DCMAKE_TOOLCHAIN_FILE=../totally-free/Toolchain-cross-mingw32-linux.cmake ../totally-free/

Demo

https://github.com/TheErk/CMake-tutorial CMake tutorial


104 / 136
N
Advanced CMake usage

Linux to Windows Toolchain example


1 # t h e name o f t h e t a r g e t o p e r a t i n g s y s t e m
2 SET(CMAKE SYSTEM NAME Windows )
3
4 # Choose an a p p r o p r i a t e c o m p i l e r p r e f i x
5 # f o r c l a s s i c a l mingw32
6 # see h t t p : / / www . mingw . o r g /
7 #s e t ( COMPILER PREFIX ” i586−mingw32msvc ” )
8 # f o r 32 o r 64 b i t s mingw−w64
9 # see h t t p : / / mingw−w64 . s o u r c e f o r g e . n e t /
10 s e t ( COMPILER PREFIX "i686 -w64 -mingw32" )
11 #s e t ( COMPILER PREFIX ” x86 64−w64−mingw32 ”
12
13 # which c o m p i l e r s t o use f o r C and C++
14 f i n d p r o g r a m (CMAKE RC COMPILER NAMES ${COMPILER PREFIX}−w i n d r e s )
15 #SET ( CMAKE RC COMPILER ${COMPILER PREFIX}−w i n d r e s )
16 f i n d p r o g r a m (CMAKE C COMPILER NAMES ${COMPILER PREFIX}−gcc )
17 #SET ( CMAKE C COMPILER ${COMPILER PREFIX}−g c c )
18 f i n d p r o g r a m (CMAKE CXX COMPILER NAMES ${COMPILER PREFIX}−g++)
19 #SET ( CMAKE CXX COMPILER ${COMPILER PREFIX}−g++)
20
21 # here i s the t a r g e t environment located
22 SET(USER ROOT PATH / home / e r k / erk−win32−dev )
23 SET(CMAKE FIND ROOT PATH / u s r / ${COMPILER PREFIX} ${USER ROOT PATH} )
24 # a d j u s t t h e d e f a u l t b e h a v i o u r o f t h e FIND XXX ( ) commands :
25 # s e a r c h h e a d e r s and l i b r a r i e s i n t h e t a r g e t e n v i r o n m e n t , s e a r c h
26 # programs i n the host environment
27 s e t (CMAKE FIND ROOT PATH MODE PROGRAM NEVER)
28 s e t ( CMAKE FIND ROOT PATH MODE LIBRARY ONLY)
https://github.com/TheErk/CMake-tutorial CMake tutorial
29 s e t (CMAKE FIND ROOT PATH MODE INCLUDE ONLY) 105 / 136
N
Advanced CMake usage

Outline
1 Overview
2 Introduction
3 Basic CMake usage
4 Discovering environment specificities
Handling platform specificities
Working with external packages
5 More CMake scripting
Custom commands
Generated files
6 Advanced CMake usage
Cross-compiling with CMake
Export your project

https://github.com/TheErk/CMake-tutorial CMake tutorial


106 / 136
N
Advanced CMake usage

Exporting/Import your project

Export/Import to/from others


CMake can help a project using CMake as a build system to
export/import targets to/from another project using CMake as
a build system.

No more time for that today sorry, see:


https://cmake.org/cmake/help/latest/manual/
cmake-packages.7.html#creating-packages

https://github.com/TheErk/CMake-tutorial CMake tutorial


107 / 136
N
CPack: Packaging made easy

Outline

7 CPack: Packaging made easy

8 CPack with CMake

9 Various package generators

https://github.com/TheErk/CMake-tutorial CMake tutorial


108 / 136
N
CPack: Packaging made easy

Introduction

A Package generator
In the same way that CMake generates build files, CPack
generates package files.

Archive generators
[ZIP,TGZ,. . . ] (All platforms)
DEB, RPM (Linux)
Cygwin Source or Binary
(Windows/Cygwin)
NSIS (Windows, Linux)
DragNDrop, Bundle,
OSXX11 (Mac OS)

https://github.com/TheErk/CMake-tutorial CMake tutorial


109 / 136
N
CPack with CMake

Outline

7 CPack: Packaging made easy

8 CPack with CMake

9 Various package generators

https://github.com/TheErk/CMake-tutorial CMake tutorial


110 / 136
N
CPack with CMake

The CMake workflow (pictured)


Project file(s),
CMakeLists.txt Object files
Makefiles, . . .

Installed
Source files files

Generated
Sources files
Binary
package
CMake time

Source Build time


package
Install time Installed
CPack time package
Package Install time

https://github.com/TheErk/CMake-tutorial CMake tutorial


111 / 136
N
CPack with CMake

The CPack application

CPack standalone
CPack is a standalone application whose behavior is driven by
a configuration file e.g. CPackConfig.cmake. This file is a
CMake language script which defines CPACK XXXX variables:
the config parameters of the CPack run.

CPack with CMake


When CPack is used to package a project built with CPack,
then the CPack configuration is usually generated by CMake
by including CPack.cmake in the main CMakeLists.txt:
include(CPack)

https://github.com/TheErk/CMake-tutorial CMake tutorial


112 / 136
N
CPack with CMake

CPack variables in CMakeLists.txt


When used with CMake, one writes something like this in
CMakeLists.txt:
1 s e t (CPACK GENERATOR "TGZ" )
2 i f ( WIN32 )
3 l i s t (APPEND CPACK GENERATOR "NSIS" )
4 e l s e i f (APPLE)
5 l i s t (APPEND CPACK GENERATOR "Bundle" )
6 e n d i f ( WIN32 )
7 s e t (CPACK SOURCE GENERATOR "ZIP;TGZ" )
8 s e t (CPACK PACKAGE VERSION MAJOR 0 )
9 s e t ( CPACK PACKAGE VERSION MINOR 1 )
10 s e t ( CPACK PACKAGE VERSION PATCH 0 )
11 i n c l u d e ( CPack )

This will create CPackSourceConfig.cmake and


CPackConfig.cmake in the build tree and will bring you the
package and package source built-in targets.
https://github.com/TheErk/CMake-tutorial CMake tutorial
113 / 136
N
CPack with CMake

A CPack config file I


A CPack config file looks like this one:
1 # T h i s f i l e w i l l be c o n f i g u r e d t o c o n t a i n v a r i a b l e s f o r CPack .
2 # These v a r i a b l e s s h o u l d be s e t i n t h e CMake l i s t f i l e o f t h e
3 # p r o j e c t b e f o r e CPack module i s i n c l u d e d .
4 ...
5 SET( CPACK BINARY BUNDLE "" )
6 SET( CPACK BINARY CYGWIN "" )
7 SET( CPACK BINARY DEB "" )
8 ...
9 SET( CPACK BINARY ZIP "" )
10 SET(CPACK CMAKE GENERATOR "Unix Makefiles" )
11 SET(CPACK GENERATOR "TGZ" )
12 SET( CPACK INSTALL CMAKE PROJECTS "/home/erk/erkit/CMakeTutorial/
examples/build;TotallyFree;ALL;/" )
13 SET( CPACK INSTALL PREFIX "/usr/local" )
14 SET(CPACK MODULE PATH "" )
15 SET( CPACK NSIS DISPLAY NAME "TotallyFree 0.1.0" )

https://github.com/TheErk/CMake-tutorial CMake tutorial


114 / 136
N
CPack with CMake

A CPack config file II


16 SET( CPACK NSIS INSTALLER ICON CODE "" )
17 SET( CPACK NSIS INSTALL ROOT "$PROGRAMFILES" )
18 SET( CPACK NSIS PACKAGE NAME "TotallyFree 0.1.0" )
19 SET( CPACK OUTPUT CONFIG FILE "/home/erk/erkit/CMakeTutorial/
examples/build/CPackConfig.cmake" )
20 SET(CPACK PACKAGE DEFAULT LOCATION "/" )
21 SET( CPACK PACKAGE DESCRIPTION FILE "/home/erk/CMake/cmake -Verk -
HEAD/share/cmake -2.8/ Templates/CPack.GenericDescription.txt
")
22 SET(CPACK PACKAGE DESCRIPTION SUMMARY "TotallyFree built using
CMake" )
23 SET( CPACK PACKAGE FILE NAME "TotallyFree -0.1.0 - Linux" )
24 SET( CPACK PACKAGE INSTALL DIRECTORY "TotallyFree 0.1.0" )
25 SET( CPACK PACKAGE INSTALL REGISTRY KEY "TotallyFree 0.1.0" )
26 SET(CPACK PACKAGE NAME "TotallyFree" )
27 SET(CPACK PACKAGE RELOCATABLE "true" )
28 SET(CPACK PACKAGE VENDOR "Humanity" )
29 SET( CPACK PACKAGE VERSION "0.1.0" )

https://github.com/TheErk/CMake-tutorial CMake tutorial


115 / 136
N
CPack with CMake

A CPack config file III


30 SET( CPACK RESOURCE FILE LICENSE "/home/erk/CMake/cmake -Verk -HEAD
/share/cmake -2.8/ Templates/CPack.GenericLicense.txt" )
31 SET( CPACK RESOURCE FILE README "/home/erk/CMake/cmake -Verk -HEAD/
share/cmake -2.8/ Templates/CPack.GenericDescription.txt" )
32 SET( CPACK RESOURCE FILE WELCOME "/home/erk/CMake/cmake -Verk -HEAD
/share/cmake -2.8/ Templates/CPack.GenericWelcome.txt" )
33 SET( CPACK SET DESTDIR "OFF" )
34 SET(CPACK SOURCE CYGWIN "" )
35 SET(CPACK SOURCE GENERATOR "TGZ;TBZ2;TZ" )
36 SET( CPACK SOURCE OUTPUT CONFIG FILE "/home/erk/erkit/
CMakeTutorial/examples/build/ CPackSourceConfig.cmake" )
37 SET( CPACK SOURCE TBZ2 "ON" )
38 SET(CPACK SOURCE TGZ "ON" )
39 SET( CPACK SOURCE TZ "ON" )
40 SET( CPACK SOURCE ZIP "OFF" )
41 SET(CPACK SYSTEM NAME "Linux" )
42 SET(CPACK TOPLEVEL TAG "Linux" )

https://github.com/TheErk/CMake-tutorial CMake tutorial


116 / 136
N
CPack with CMake

CPack running steps I


For a CMake enabled project one can run CPack in two ways:
1 use the build tool to run targets: package or package source
2 invoke CPack manually from within the build tree e.g.:
$ cpack -G RPM
The CPack documentation is currently found on the Wiki or on
the CPack specific modules:
https://cmake.org/Wiki/CMake:CPackPackageGenerators
https://cmake.org/Wiki/CMake:
Component_Install_With_CPack
cpack --help-module CPackXXX with CPack, CPackComponent,
CPackRPM, CPackDEB, CPackIFW, CPackWIX, . . .

https://github.com/TheErk/CMake-tutorial CMake tutorial


117 / 136
N
CPack with CMake

CPack running steps II


Whichever way you call it, the CPack steps are:
1 cpack command starts and parses arguments etc. . .
2 it reads CPackConfig.cmake (usually found in the build tree) or
the file given as an argument to --config command line option.
3 it iterates over the generators list found in CPACK GENERATOR (or
from -G command line option). For each generator:
3 (re)sets CPACK GENERATOR to the one currently being iterated over
3 includes the CPACK PROJECT CONFIG FILE
3 installs the project into a CPack private location (using DESTDIR)
3 calls the generator and produces the package(s) for that generator

https://github.com/TheErk/CMake-tutorial CMake tutorial


118 / 136
N
CPack with CMake

CPack running steps III


cpack command line example
1 $ cpack -G "TGZ;RPM"
2 CPack: Create package using TGZ
3 CPack: Install projects
4 CPack: - Run preinstall target for: TotallyFree
5 CPack: - Install project: TotallyFree
6 CPack: Create package
7 CPack: - package: <...>/build/TotallyFree-0.1.0-Linux.tar.gz generated.
8 CPack: Create package using RPM
9 CPack: Install projects
10 CPack: - Run preinstall target for: TotallyFree
11 CPack: - Install project: TotallyFree
12 CPack: Create package
13 CPackRPM: Will use GENERATED spec file: <...>/build/_CPack_Packages/Linux/RPM/SPECS/totallyfree.spec
14 CPack: - package: <...>/build/TotallyFree-0.1.0-Linux.rpm generated.
15 $

https://github.com/TheErk/CMake-tutorial CMake tutorial


119 / 136
N
CPack with CMake

CPack running steps IV


make package example
1 $ make package
2 [ 33%] Built target acrodict
3 [ 66%] Built target Acrodictlibre
4 [100%] Built target Acrolibre
5 Run CPack packaging tool...
6 CPack: Create package using TGZ
7 CPack: Install projects
8 CPack: - Run preinstall target for: TotallyFree
9 CPack: - Install project: TotallyFree
10 CPack: Create package
11 CPack: - package: <...>/build/TotallyFree-0.1.0-Linux.tar.gz generated.

Rebuild project
In the make package case CMake is checking that the project
does not need a rebuild.

https://github.com/TheErk/CMake-tutorial CMake tutorial


120 / 136
N
CPack with CMake

CPack running steps V


make package source example
1 $ make package_source
2 make package_source
3 Run CPack packaging tool for source...
4 CPack: Create package using TGZ
5 CPack: Install projects
6 CPack: - Install directory: <...>/totally-free
7 CPack: Create package
8 CPack: - package: <...>/build/TotallyFree-0.1.0-Source.tar.gz generated.
9 CPack: Create package using TBZ2
10 CPack: Install projects
11 CPack: - Install directory: <...>/totally-free
12 CPack: Create package
13 CPack: - package: <...>/build/TotallyFree-0.1.0-Source.tar.bz2 generated.
14 CPack: Create package using TZ
15 CPack: Install projects
16 CPack: - Install directory: <...>/totally-free
17 CPack: Create package
18 CPack: - package: <...>/build/TotallyFree-0.1.0-Source.tar.Z generated.

https://github.com/TheErk/CMake-tutorial CMake tutorial


121 / 136
N
CPack with CMake

The CPack workflow (pictured)

CMakeLists.txt

Source files

https://github.com/TheErk/CMake-tutorial CMake tutorial


122 / 136
N
CPack with CMake

The CPack workflow (pictured)

CMakeLists.txt

ee
rce Tr
Sou
Source files

https://github.com/TheErk/CMake-tutorial CMake tutorial


122 / 136
N
CPack with CMake

The CPack workflow (pictured)

CMakeLists.txt

ee
rc e Tr
Sou ee
Tr
ild
Source files Bu

CMake time

Build time

Install time (from CPack)

CPack time

Package Install time

https://github.com/TheErk/CMake-tutorial CMake tutorial


122 / 136
N
CPack with CMake

The CPack workflow (pictured)

CMakeLists.txt CPackConfig.cmake

ee
rc e Tr
Sou ee
Tr
ild
Source files Bu

CMake time
CPackSourceConfig.cmake
Build time

Install time (from CPack)

CPack time

Package Install time

https://github.com/TheErk/CMake-tutorial CMake tutorial


122 / 136
N
CPack with CMake

The CPack workflow (pictured)

CMakeLists.txt CPackConfig.cmake

ee
rc e Tr
Sou ee
Tr
ild
Source files Bu

CMake time
CPackSourceConfig.cmake
Build time

Install time (from CPack)

CPack time Source


Package Install time package

https://github.com/TheErk/CMake-tutorial CMake tutorial


122 / 136
N
CPack with CMake

The CPack workflow (pictured)

CMakeLists.txt CPackConfig.cmake

ee CPack
rc e Tr Installed files
Sou ee
Tr
ild
Source files Bu

CMake time
CPackSourceConfig.cmake
Build time

Install time (from CPack)

CPack time Source


Package Install time package

https://github.com/TheErk/CMake-tutorial CMake tutorial


122 / 136
N
CPack with CMake

The CPack workflow (pictured)

CMakeLists.txt CPackConfig.cmake

ee CPack
rc e Tr Installed files
Sou ee
Tr
ild
Source files Bu
Binary
package

CMake time
CPackSourceConfig.cmake
Build time

Install time (from CPack)

CPack time Source


Package Install time package

https://github.com/TheErk/CMake-tutorial CMake tutorial


122 / 136
N
CPack with CMake

The CPack workflow (pictured)

CMakeLists.txt CPackConfig.cmake

ee CPack
rc e Tr Installed files
Sou ee
Tr
ild
Source files Bu
Binary Installed
package package

CMake time
CPackSourceConfig.cmake
Build time

Install time (from CPack)

CPack time Source


Package Install time package

https://github.com/TheErk/CMake-tutorial CMake tutorial


122 / 136
N
CPack with CMake

Source vs Binary Generators


CPack does not really distinguish “source” from “binaries”!!

CPack source package


The CPack configuration file is: CPackSourceConfig.cmake.
The CPack source generator is essentially packaging directo-
ries with install, exclude and include rules.

CPack binary package


The CPack configuration file is: CPackConfig.cmake. More-
over CPack knows that a project is built with CMake and
inherits many properties from the install rules found in the
project.

https://github.com/TheErk/CMake-tutorial CMake tutorial


123 / 136
N
Various package generators

Outline

7 CPack: Packaging made easy

8 CPack with CMake

9 Various package generators

https://github.com/TheErk/CMake-tutorial CMake tutorial


124 / 136
N
Various package generators

Archive Generators

A family of generators
The archive generators is a family of generators which is sup-
ported on all CMake supported platforms through libarchive:
http://code.google.com/p/libarchive/.

STGZ Self extracting Tar GZip compression


TBZ2 Tar BZip2 compression
TGZ Tar GZip compression
TZ Tar Compress compression
TXZ Tar XZ compression
7Z 7-zip archive
ZIP Zip archive
https://github.com/TheErk/CMake-tutorial CMake tutorial
125 / 136
N
Various package generators

Linux-friendly generators I

Tar-kind archive generators


Binary RPM: only needs rpmbuild to work.
Binary DEB: works on any Linux distros.
IFW: Qt Installer framework

CPack vs native tools


One could argue “why use CPack for building .deb or .rpm”.
The primary target of CPack RPM and DEB generators are
people who are NOT professional packagers. Those people can
get a clean package without too much effort and get a better
package than a bare TAR archive.

https://github.com/TheErk/CMake-tutorial CMake tutorial


126 / 136
N
Various package generators

Linux-friendly generators II
No official packaging replacement
Those generators are no replacement for official packaging
tools.

https://github.com/TheErk/CMake-tutorial CMake tutorial


127 / 136
N
Various package generators

Windows-friendly generators

Zip archive generator


NullSoft System Installer generator:
http://nsis.sourceforge.net/
Supports component installation, produces nice GUI installer.
WiX installer: http://wixtoolset.org/
Windows Installer XML which produces MSI.
IFW: Qt Installer framework
Cygwin: Binary and Source generators.

https://github.com/TheErk/CMake-tutorial CMake tutorial


128 / 136
N
Various package generators

Mac OS-friendly generators

Tar-kind archive generators Bundle


DragNDrop OSXX11
PackageMaker may be Qt IFW as well...

Don’t ask me
I’m not a Mac OS user and I don’t know them.
Go and read the CPack doc or ask on the ML.
https://cmake.org/mailing-lists/

https://github.com/TheErk/CMake-tutorial CMake tutorial


129 / 136
N
Various package generators

Packaging Components I
CMake+CPack installation components?
Sometimes you want to split the installer into components.
1 Use COMPONENT argument in your install rules (in the
CMakeLists.txt),
2 Add some more [CPack] information about how to group
components,
3 Choose a component-aware CPack generator
4 Choose the behavior (1 package file per component, 1 package file
per group, etc. . . )
5 Possibly specify generator specific behavior in
CPACK PROJECT CONFIG FILE
6 Run CPack.

https://github.com/TheErk/CMake-tutorial CMake tutorial


130 / 136
N
Various package generators

Packaging Components II
demo with ComponentExample

More detailed documentation here:


https://cmake.org/Wiki/CMake:Component_Install_With_CPack

Component aware generator


Not all generators do support components
(i.e. they are MONOLITHIC)
Some produce a single package file containing all components.
(e.g. NSIS, WiX, Qt IFW)
Others produce several package files containing one or several
components.
(e.g. ArchiveGenerator, RPM, DEB)

https://github.com/TheErk/CMake-tutorial CMake tutorial


131 / 136
N
Systematic Testing

Outline

10 Systematic Testing

11 CTest submission to CDash

12 References

https://github.com/TheErk/CMake-tutorial CMake tutorial


132 / 136
N
CTest submission to CDash

Outline

10 Systematic Testing

11 CTest submission to CDash

12 References

https://github.com/TheErk/CMake-tutorial CMake tutorial


133 / 136
N
CTest submission to CDash

More to come on CTest/CDash

Sorry...out of time!!
CMake and its friends are so much fun and powerful that I ran
out of time to reach a detailed presentation of CTest/CDash,
stay tuned for next time. . .

In the meantime:
Go there: http://www.cdash.org
Open your own (free) Dashboard: http://my.cdash.org/

https://github.com/TheErk/CMake-tutorial CMake tutorial


134 / 136
N
References

Outline

10 Systematic Testing

11 CTest submission to CDash

12 References

https://github.com/TheErk/CMake-tutorial CMake tutorial


135 / 136
N
References

References I
CDash home page, Jun. 2016.
http://www.cdash.org.

CMake home page, Jun. 2016.


https://cmake.org.

CMake online documentation, Jun. 2016.


https://cmake.org/documentation.

CMake Wiki, Jun. 2016.


https://cmake.org/Wiki/CMake.

KDE guidelines and HOWTOs/CMake, Jun. 2016.


https://community.kde.org/Guidelines_and_HOWTOs/CMake.

A cmake primer, Jun. 2016.


https://llvm.org/svn/llvm-project/llvm/trunk/docs/CMakePrimer.rst.

Ken Martin and Bill Hoffman.


Mastering CMake: A Cross-Platform Build System.
Kitware, Inc., 6th edition, based on CMake 3.1 edition, 2016.
ISBN 978-1-930934-31-3.

https://github.com/TheErk/CMake-tutorial CMake tutorial


136 / 136
N

You might also like