CMake Tutorial 8feb2012

Share Embed Donate


Short Description

cmake tutorial...

Description

CMake tutorial and its friends CPack, CTest and CDash

Eric NOULARD - [email protected]

http://www.cmake.org February, 8th 2012

This presentation is licensed http://creativecommons.org/licenses/by-sa/3.0/us/

CMake tutorial N

1 / 118

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 shouldexpect Alan, Alex, Bill, Brad, Clint, David, Eike, Julien, Mathieu, Michael & Michael, and many more. . . My son Louis for the nice CPack 3D logo done with Blender. and...Toulibre for hosting this presention in Toulouse, France. CMake tutorial N

2 / 118

Outlines

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: , Windows, MacOS, AIX, IRIX,

, iOS · · ·

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 CMake tutorial N

3 / 118

Outlines

Outline of Part I: CMake 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

4 / 118

Outlines

Outline of Part II: CPack

5

CPack: Packaging made easy

6

CPack with CMake

7

Various package generators

CMake tutorial N

5 / 118

Outlines

Outline of Part III: CTest and CDash

8

Systematic Testing

9

CTest submission to CDash

10

References

CMake tutorial N

6 / 118

Outlines

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?

Outlines

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 in several parts that need some building to put them together,

Outlines

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 in several parts that need some building to put them together, because softwares are written in various languages that may share the same building process,

Outlines

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 in 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, embbeded computers) and systems (Windows, Linux, *BSD, other Unices (many), Android, etc. . . ) CMake tutorial N

7 / 118

Outlines

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,. . . ?byte-compile?

interpreter

Perl

interprets

C++ Fortran C

compiles

links

executable

OCaml

object code

Programming languages

Python

executes

Running program

CMake tutorial N

8 / 118

Outlines

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,. . . ?byte-compile?

interpreter

Perl

interprets

C++ Fortran C

compiles

links

executable

OCaml

object code

Programming languages

Python

executes

Running program

CMake tutorial N

8 / 118

Outlines

Build systems: several choices Alternatives CMake is not the only build system [generator]: (portable) hand-written Makefiles, depends on make tool. Apache ant http://ant.apache.org/, dedicated to Java (almost). Portable IDE: Eclipse, Code::Blocks, Geany, NetBeans, . . . GNU Autotools: Autoconf, Automake, Libtool. Produce makefiles. Needs bourne shell (and M4 macro processor). see e.g. http://www.gnu.org/software/autoconf/ SCons: http://www.scons.org only depends on python. Extensible with python. ... CMake tutorial N

9 / 118

Outlines

Comparisons and [success] stories Disclaimer This presentation is biased. I mean totally. I am a big CMake fan, I’m contributing 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/ CMake tutorial N

10 / 118

Outlines

CMake/Auto[conf|make] on Ohloh

https://www.ohloh.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. CMake tutorial N

11 / 118

Outlines

CMake/Auto[conf|make] on Google Trend

http://www.google.com/trends Scale is based on the average worldwide traffic of cmake in all years. CMake tutorial N

12 / 118

Basic CMake usage

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

13 / 118

Basic CMake usage

A build system generator CMake is a generator: it generates native build systems files (Makefile, IDE project files, . . . ), CMake scripting language (declarative) is used to describe the build, The developer edit CMakeLists.txt, invoke CMake but should never edit the generated files, CMake may be (automatically) re-invoked by the build system,

CMake tutorial N

14 / 118

Basic CMake usage

The CMake workflow

When do things take place? CMake is a generator so it does not compile (i.e. build) the sources, the underlying build tool (make, XCode, Code::Blocks. . . ) does. CMake tutorial N

15 / 118

Basic CMake usage

The CMake workflow 1

CMake time: CMake is running & processing CMakeLists.txt

When do things take place? CMake is a generator so it does not compile (i.e. build) the sources, the underlying build tool (make, XCode, Code::Blocks. . . ) does. CMake tutorial N

15 / 118

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 so it does not compile (i.e. build) the sources, the underlying build tool (make, XCode, Code::Blocks. . . ) does. CMake tutorial N

15 / 118

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 so it does not compile (i.e. build) the sources, the underlying build tool (make, XCode, Code::Blocks. . . ) does. CMake tutorial N

15 / 118

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 so it does not compile (i.e. build) the sources, the underlying build tool (make, XCode, Code::Blocks. . . ) does. CMake tutorial N

15 / 118

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 so it does not compile (i.e. build) the sources, the underlying build tool (make, XCode, Code::Blocks. . . ) does. CMake tutorial N

15 / 118

Basic CMake usage

The CMake workflow (pictured) CMakeLists.txt

Source files

CMake tutorial N

16 / 118

Basic CMake usage

The CMake workflow (pictured) CMakeLists.txt

Project file(s), Makefiles, . . .

Source files Generated Sources files CMake time

CMake tutorial N

16 / 118

Basic CMake usage

The CMake workflow (pictured) CMakeLists.txt

Project file(s), Makefiles, . . .

Object files

Source files Generated Sources files CMake time Build time

CMake tutorial N

16 / 118

Basic CMake usage

The CMake workflow (pictured) CMakeLists.txt

Project file(s), Makefiles, . . .

Object files

Installed files

Source files Generated Sources files CMake time Build time Install time

CMake tutorial N

16 / 118

Basic CMake usage

The CMake workflow (pictured) CMakeLists.txt

Project file(s), Makefiles, . . .

Object files

Installed files

Source files Generated Sources files

Binary package

CMake time

Source package

Build time Install time CPack time

CMake tutorial N

16 / 118

Basic CMake usage

The CMake workflow (pictured) CMakeLists.txt

Project file(s), Makefiles, . . .

Object files

Installed files

Source files Generated Sources files

Binary package

CMake time

Source package

Build time Install time CPack time

Installed package

Package Install time

CMake tutorial N

16 / 118

Basic CMake usage

Building an executable

1 2 3 4 5 6

Listing 1: Building a simple program cmake minimum required (VERSION 2 . 8 ) # T h i s p r o j e c t use C s o u r c e code project ( TotallyFree C) # build executable using s p e c i f i e d # l i s t of source f i l e s add executable ( A c r o l i b r e 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 96 $ cmake --help-command add_executable ... add_executable Add an executable to the project using the specified source files. CMake tutorial N

17 / 118

Basic CMake usage

Builtin documentation 1 2 3 4

CMake builtin doc for ’project’ command $ cmake --help-command project cmake version 2.8.7.20120121-g751713-dirty project Set a name for the entire project.

5

project( [languageName1 languageName2 ... ] )

6 7

Sets the name of the project. Additionally this sets the variables _BINARY_DIR and _SOURCE_DIR to the respective values.

8 9 10 11

Optionally you can specify which languages your project supports. Example languages are CXX (i.e. C++), C, Fortran, etc. By default C and CXX are enabled. E.g. if you do not have a C++ compiler, you can disable the check for it by explicitly listing the languages you want to support, e.g. C. By using the special language "NONE" all checks for any language can be disabled.

12 13 14 15 16 17

CMake tutorial N

18 / 118

Basic CMake usage

Generating & building Building with CMake is easy: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

CMake + Unix Makefile $ ls totally-free acrolibre.c CMakeLists.txt $ mkdir build $ cd build $ cmake ../totally-free -- The C compiler identification is GNU 4.6.2 -- Check for working C compiler: /usr/bin/gcc -- Check for working C compiler: /usr/bin/gcc -- works ... $ make Scanning dependencies of target Acrolibre [100%] Building C object CMakeFiles/Acrolibre.dir/acrolibre.c.o Linking C executable Acrolibre [100%] Built target Acrolibre $ ./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. CMake tutorial N

19 / 118

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:

CMake tutorial N

20 / 118

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 separate from manually edited ones (thus you don’t have to clutter you favorite VCS ignore files).

CMake tutorial N

20 / 118

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 separate from manually edited ones (thus you don’t have to clutter you favorite VCS ignore files).

2

You can have several build trees for the same source tree

CMake tutorial N

20 / 118

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 separate from manually edited ones (thus you don’t have to clutter you 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 CMake tutorial N

20 / 118

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 entry file

CMake tutorial N

21 / 118

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 entry file

CMake tutorial N

21 / 118

The main program source 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

#i n c l u d e < s t d l i b . h> #i n c l u d e #i n c l u d e < s t r i n g s . h> #i f d e f USE ACRODICT #i n c l u d e "acrodict.h" #e n d i f i n t main ( i n t argc , c h a r ∗ a r g v [ ] ) { c o n s t c h a r ∗ name ; #i f d e f USE ACRODICT c o n s t a c r o I t e m t ∗ item ; #e n d i f i f ( argc < 2) { f p r i n t f ( s t d e r r , "%s: you need one argument\n" , a r g v [ 0 ] ) ; f p r i n t f ( s t d e r r , "%s \n" , a r g v [0]) ; e x i t ( EXIT FAILURE ) ; } name = a r g v [ 1 ] ; #i f n d e f USE ACRODICT i f ( s t r c a s e c m p ( name , "toulibre" ) ==0) { p r i n t f ( "Toulibre is a french

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

organization promoting FLOSS .\n" ) ; } #e l s e item = a c r o d i c t g e t ( name ) ; i f (NULL!= item ) { p r i n t f ( "%s: %s\n" , item−>name , item−> description ) ; } e l s e i f ( item=a c r o d i c t g e t a p p r o x ( name ) ) { p r i n t f ( " is unknown may be you mean :\n" , name ) ; p r i n t f ( "%s: %s\n" , item−>name , item−> description ) ; } #e n d i f else { p r i n t f ( "Sorry , I don’t know: \n " , name ) ; r e t u r n EXIT FAILURE ; } r e t u r n EXIT SUCCESS ; }

CMake tutorial N

22 / 118

The library source 1 2 3 4 5 6 7 8 9 10

1 2 3 4 5 6 7 8 9

#i f n d e f ACRODICT H #d e f i n e ACRODICT H typedef s t r u c t acroItem { c h a r ∗ name ; char ∗ d e s c r i p t i o n ; } acroItem t ; const acroItem t ∗ a c r o d i c t g e t ( c o n s t c h a r ∗ name ) ; #e n d i f

#i n c l u d e < s t d l i b . h> #i n c l u d e < s t r i n g . h> #i n c l u d e "acrodict.h" s t a t i c const acroItem t acrodict [ ] = { {"Toulibre" , "Toulibre is a french organization promoting FLOSS" } , {"GNU" , "GNU is Not Unix" } , {"GPL" , "GNU general Public License" }, {"BSD" , "Berkeley Software Distribution" } , {"CULTe" , "Club des Utilisateurs de Logiciels libres et de gnu/ linux de Toulouse et des environs" } ,

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

{"Lea" , "Lea -Linux: Linux entre ami(e )s" } , {"RMLL" , "Rencontres Mondiales du Logiciel Libre" } , {"FLOSS" , "Free Libre Open Source Software" } , {"" , "" } } ; const acroItem t ∗ a c r o d i c t g e t ( c o n s t c h a r ∗ name ) { i n t c u r r e n t =0; i n t found =0; 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 ) { i f ( s t r c a s e c m p ( name , a c r o d i c t [ c u r r e n t ] . name ) ==0) { found =1; } else { c u r r e n t ++; } } i f ( found ) { r e t u r n &( a c r o d i c t [ c u r r e n t ] ) ; } else { r e t u r n NULL ; } }

CMake tutorial N

23 / 118

Basic CMake usage

Building a library I Listing 2: Building a simple program + shared library 1 2 3 4 5 6 7 8 9

cmake minimum required (VERSION 2 . 8 ) p r o j e c t ( TotallyFree C) add executable ( Acrolibre a c r o l i b r e . c ) s e t ( LIBSRC a c r o d i c t . c a c r o d i c t . h ) a d d l i b r a r y ( a c r o d i c t ${LIBSRC } ) 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 ) t a r g e t l i n k l i b r a r i e s ( Acrodictlibre acrodict ) set target properties ( Acrodictlibre PROPERTIES COMPILE FLAGS "-DUSE_ACRODICT" )

Basic CMake usage

Building a library II And it builds... All in all CMake generates appropriate Unix makefiles which build all this smoothly. 1 2 3 4 5 6 7 8 9 10 11 12 13

CMake + Unix Makefile $ make [ 33%] Building C object CMakeFiles/acrodict.dir/acrodict.c.o Linking C shared library libacrodict.so [ 33%] Built target acrodict [ 66%] Building C object CMakeFiles/Acrodictlibre.dir/acrolibre.c.o Linking C executable Acrodictlibre [ 66%] Built target Acrodictlibre [100%] Building C object CMakeFiles/Acrolibre.dir/acrolibre.c.o Linking C executable Acrolibre [100%] Built target Acrolibre $ ls -F Acrodictlibre* CMakeCache.txt cmake_install.cmake Makefile Acrolibre* CMakeFiles/ libacrodict.so*

CMake tutorial N

25 / 118

Basic CMake usage

Building a library III And it works... We get the two different variants of our program, with varying capabilities. 1 2 3 4 5 6

Generated Makefiles has several builtin targets besides the expected ones:

$ ./Acrolibre toulibre Toulibre is a french organization promoting FLOSS. $ ./Acrolibre FLOSS Sorry, I don’t know: $ ./Acrodictlibre FLOSS FLOSS: Free Libre Open Source Software $ make help The following are some of the valid targets for this Makefile: ... all (the default if no target is provided) ... clean ... depend ... Acrodictlibre ... Acrolibre ... acrodict ...

one per target (library or executable) clean, all more to come . . .

Basic CMake usage

User controlled build option User controlled option May be our users don’t want the acronym dictionnary support. We can use CMake OPTION command. Listing 3: User controlled build option 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

cmake minimum required (VERSION 2 . 8 ) # T h i s p r o j e c t use C s o u r c e code p r o j e c t ( TotallyFree C) # 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 o p t i o n (WITH ACRODICT "Include acronym dictionary support" ON) s e t ( BUILD SHARED LIBS t r u e ) # build executable using s p e c i f i e d l i s t of source f i l e s add executable ( Acrolibre a c r o l i b r e . c ) i f (WITH ACRODICT) s e t ( LIBSRC a c r o d i c t . h a c r o d i c t . c ) a d d l i b r a r y ( a c r o d i c t ${LIBSRC } ) 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 ) t a r g e t l i n k l i b r a r i e s ( Acrodictlibre acrodict ) 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" ) e n d i f (WITH ACRODICT) CMake tutorial N

27 / 118

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 curse-based TUI: ccmake a QT-based GUI: cmake-gui

Call 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 .

CMake tutorial N

28 / 118

Basic CMake usage

Too much keyboard, time to click? II ccmake : the curse-based TUI (demo)

Here we can choose to toggle the WITH ACRONYM OPTION.

CMake tutorial N

29 / 118

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 ACRONYM OPTION. CMake tutorial N

30 / 118

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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Borland Makefiles MSYS Makefiles MinGW Makefiles NMake Makefiles NMake Makefiles JOM Unix Makefiles Visual Studio 10 Visual Studio 10 IA64 Visual Studio 10 Win64 Visual Studio 11 Visual Studio 11 Win64 Visual Studio 6 Visual Studio 7 Visual Studio 7 .NET 2003 Visual Studio 8 2005 Visual Studio 8 2005 Win64

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

Visual Studio 9 2008 Visual Studio 9 2008 IA64 Visual Studio 9 2008 Win64 Watcom WMake CodeBlocks - MinGW Makefiles CodeBlocks - NMake Makefiles CodeBlocks - Unix Makefiles Eclipse CDT4 - MinGW Makefiles Eclipse CDT4 - NMake Makefiles Eclipse CDT4 - Unix Makefiles KDevelop3 KDevelop3 - Unix Makefiles XCode Ninja (in development) http://martine.github.com/ninja/ CMake tutorial

N

31 / 118

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. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

CMake + MinGW Makefile $ ls totally-free acrodict.h acrodict.c acrolibre.c CMakeLists.txt $ mkdir build-win32 $ cd build-win32 ... $ make Scanning dependencies of target acrodict [ 33%] Building C object CMakeFiles/acrodict.dir/acrodict.c.obj Linking C shared library libacrodict.dll Creating library file: libacrodict.dll.a [ 33%] Built target acrodict Scanning dependencies of target Acrodictlibre [ 66%] Building C object CMakeFiles/Acrodictlibre.dir/acrolibre.c.obj Linking C executable Acrodictlibre.exe [ 66%] Built target Acrodictlibre Scanning dependencies of target Acrolibre [100%] Building C object CMakeFiles/Acrolibre.dir/acrolibre.c.obj Linking C executable Acrolibre.exe [100%] Built target Acrolibre

CMake tutorial N

32 / 118

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 4: install command examples 1 2 3 4 5 6 7 8 9 10 11

... add executable ( Acrolibre a c r o l i b r e . c ) i n s t a l l (TARGETS A c r o l i b r e DESTINATION b i n ) i f (WITH ACRODICT) ... 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 RUNTIME DESTINATION b i n LIBRARY DESTINATION l i b ARCHIVE DESTINATION l i b / s t a t i c ) 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 ) e n d i f (WITH ACRODICT)

CMake tutorial N

33 / 118

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 when you install:

CMake tutorial N

34 / 118

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 when you install: At CMake-time set CMAKE INSTALL PREFIX value $ cmake --help-variable CMAKE_INSTALL_PREFIX

CMake tutorial N

34 / 118

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 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

CMake tutorial N

34 / 118

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 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 CMake tutorial N

34 / 118

Basic CMake usage

The CMake workflow (pictured) CMakeLists.txt

Project file(s), Makefiles, . . .

Object files

Installed files

Source files Generated Sources files

Binary package

CMake time

Source package

Build time Install time CPack time

Installed package

Package Install time

CMake tutorial N

35 / 118

Basic CMake usage

Using CMake variables CMake variables They are used by the user to simplify its CMakeLists.txt, but CMake uses many (˜170+) of them to control/change its [default] behavior. Try: cmake --help-variables-list. Inside a CMake script set (CMAKE INSTALL PREFIX /home/eric/testinstall) $ cmake --help-command set On the command line/TUI/GUI Remember that (beside options) each CMake tool takes a single argument (source tree or existing build tree) $ cmake -DCMAKE_INSTALL_PREFIX=/home/eric/testinstall . CMake tutorial N

36 / 118

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 command are used in the CMakeLists.txt. 1 2 3 4 5 6 7 8 9 10 11 12

$ make DESTDIR=/tmp/testinstall install [ 33%] Built target acrodict [ 66%] Built target Acrodictlibre [100%] Built target Acrolibre Install the project... -- Install configuration: "" -- Installing: /tmp/testinstall/bin/Acrolibre -- Installing: /tmp/testinstall/bin/Acrodictlibre -- Removed runtime path from "/tmp/testinstall/bin/Acrodictlibre" -- Installing: /tmp/testinstall/lib/libacrodict.so -- Installing: /tmp/testinstall/include/acrodict.h $ CMake tutorial N

37 / 118

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 5: add CPack support 1 2 3 4 5 6 7 8 9 10 11 12

... e n d i f (WITH ACRODICT) ... # Near t h e end o f t h e CMakeLists . t x t # Chose y o u r CPack g e n e r a t o r s e t (CPACK GENERATOR "TGZ" ) # Setup package v e r s i o n s e t (CPACK PACKAGE VERSION MAJOR 0 ) s e t ( CPACK PACKAGE VERSION MINOR 1 ) s e t ( CPACK PACKAGE VERSION PATCH 0 ) # ’ c a l l ’ CPack i n c l u d e ( CPack )

$ make package [ 33%] Built target acrodict [ 66%] Built target Acrodictlibre [100%] Built target Acrolibre Run CPack packaging tool... CPack: Create package using TGZ CPack: Install projects CPack: - Run preinstall target for: TotallyFree CPack: - Install project: TotallyFree CPack: Create package CPack: - package: /... TotallyFree-0.1.0-Linux.tar.gz generated. $ tar ztvf TotallyFree-0.1.0-Linux.tar.gz ... 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

CMake tutorial N

38 / 118

Basic CMake usage

CPack the packaging friend CPack is a standalone generator As we will see later on, CPack is standalone application, which as CMake is a generator. $ cpack -G ZIP CPack: Create package using ZIP CPack: Install projects CPack: - Run preinstall target for: TotallyFree CPack: - Install project: TotallyFree CPack: Create package CPack: - package: /... TotallyFree-0.1.0-Linux.zip generated. $ unzip -t TotallyFree-0.1.0-Linux.zip Archive: TotallyFree-0.1.0-Linux.zip testing: To.../include/acrodict.h OK testing: To.../bin/Acrolibre OK testing: To.../bin/Acrodictlibre OK testing: To.../lib/libacrodict.so OK No errors detected in compressed data of TotallyFree-0.1.0-Linux.zip.

N

$ cpack -G RPM CPack: Create package using RPM CPack: Install projects CPack: - Run preinstall target for: TotallyFree CPack: - Install project: TotallyFree CPack: Create package CPackRPM: Will use GENERATED spec file: /... _CPack_Packages/Linux/RPM/SPECS/totallyfree.spec CPack: - package: /... TotallyFree-0.1.0-Linux.rpm generated. $ rpm -qpl TotallyFree-0.1.0-Linux.rpm /usr /usr/bin /usr/bin/Acrodictlibre /usr/bin/Acrolibre /usr/include /usr/include/acrodict.h /usr/lib /usr/lib/libacrodict.so CMake tutorial 39 / 118

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. Listing 6: add CTest support 1 2 3 4 5 6 7 8 9 10 11 12

... e n d i f (WITH ACRODICT) ... enable testing ( ) a d d t e s t ( t o u l i b r e −b u i l t i n A c r o l i b r e "toulibre" ) a d d t e s t ( t o u l i b r e −d i c t A c r o d i c t l i b r e "toulibre" ) a d d t e s t ( FLOSS−d i c t A c r o d i c t l i b r e "FLOSS" ) a d d t e s t ( FLOSS−f a i l A c r o l i b r e "FLOSS" )

$ make test Running tests... Test project /build Start 1: toulibre-builtin 1/4 Test #1: toulibre-builtin .... Passed Start 2: toulibre-dict 2/4 Test #2: toulibre-dict........ Passed Start 3: FLOSS-dict 3/4 Test #3: FLOSS-dict .......... Passed Start 4: FLOSS-fail 4/4 Test #4: FLOSS-fail ..........***Failed

0.00 sec 0.00 sec 0.00 sec 0.00 sec

75% tests passed, 1 tests failed out of 4 Total Test time (real) =

0.01 sec

The following tests FAILED: 4 - FLOSS-fail (Failed) CMake tutorial N

40 / 118

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 7: add CTest support 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

... e n d i f (WITH ACRODICT) ... enable testing ( ) a d d t e s t ( t o u l i b r e −b u i l t i n A c r o l i b r e "toulibre" ) a d d t e s t ( t o u l i b r e −d i c t A c r o d i c t l i b r e "toulibre" ) a d d t e s t ( FLOSS−d i c t A c r o d i c t l i b r e "FLOSS" ) a d d t e s t ( FLOSS−f a i l A c r o l i b r e "FLOSS" ) s e t t e s t s p r o p e r t i e s ( FLOSS−f a i l PROPERTIES PASS REGULAR EXPRESSION "Sorry , I don ’t know :.* FLOSS" )

$ make test Running tests... Test project /build Start 1: toulibre-builtin 1/4 Test #1: toulibre-builtin .... Passed Start 2: toulibre-dict 2/4 Test #2: toulibre-dict........ Passed Start 3: FLOSS-dict 3/4 Test #3: FLOSS-dict .......... Passed Start 4: FLOSS-fail 4/4 Test #4: FLOSS-fail .......... Passed

0.00 sec 0.00 sec 0.00 sec 0.00 sec

100% tests passed, 0 tests failed out of 4 Total Test time (real) =

0.01 sec

CMake tutorial N

41 / 118

Basic CMake usage

CTest the testing friend CTest is a standalone generic test driver As we will see later on, CTest is standalone application, which can run a set of test programs. $ ctest -R toulibre$ ctest -R FLOSS-fail -V Test project /build Test project 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: /Acrolibre "FLOSS" Total Test time (real) = 0.01 sec 4: Test timeout computed to be: 9.99988e+06 4: Sorry, I don’t know: 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 CMake tutorial N

42 / 118

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/

CMake tutorial N

43 / 118

Basic CMake usage

Summary CMake basics Using CMake basics we can already do a lot a 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 Runs systematic test with CTest and publish them with CDash CMake tutorial N

44 / 118

Basic CMake usage

Seeking more information or help There are several places you can go by yourself: 1

Read the FAQ: http://www.cmake.org/Wiki/CMake_FAQ

2

Read the Wiki: http://www.cmake.org/Wiki/CMake

3

Ask on the Mailing List: http://www.cmake.org/cmake/help/mailing.html

4

Browse the built-in help: cmake --help-xxxxx

CMake tutorial N

45 / 118

Discovering environment specificities

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

46 / 118

Discovering environment specificities

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

47 / 118

Discovering environment specificities

How to discover system System/compiler specific variables Right after the project command CMake has set up a bunch of 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 OSX. CYGWIN True for cygwin. compiler specific MSVC True when using Microsoft Visual C CMAKE COMPILER IS GNU True if the compiler is GNU.

MINGW true if the compiler is MinGW. N

CMake tutorial

48 / 118

Discovering environment specificities

Handle system specific code Some functions like strcasestr (lines 6 and 7) may not be available on all platforms. Listing 8: excerpt from acrodict.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

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 ) { i n t c u r r e n t =0; i n t found =0; #i f d e f GUESS NAME 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 ) { 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 ) | | ( 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 ) ) { found =1; } else { c u r r e n t ++; } } i f ( found ) { r e t u r n &( a c r o d i c t [ c u r r e n t ] ) ; } else #e n d i f { r e t u r n NULL ; } } CMake tutorial N

49 / 118

Discovering environment specificities

Use system specific 1 2 3 4 5 6 7 8 9 10 11 12 13 14

option

# 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 o p t i o n (WITH ACRODICT "Include acronym dictionary support" ON) i f (NOT WIN32 ) o p t i o n (WITH GUESS NAME "Guess acronym name" ON) e n d i f (NOT WIN32 ) ... i f (WITH ACRODICT) # l i s t o f sources in our l i b r a r y s e t ( LIBSRC a c r o d i c t . h a c r o d i c t . c ) i f (WITH GUESS NAME) 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" ) e n d i f (WITH GUESS NAME) a d d l i b r a r y ( a c r o d i c t ${LIBSRC } ) ...

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

CMake tutorial N

50 / 118

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 deals with system/compiler specific option/feature. MuseScore : http://musescore.org http://mscore.svn.sourceforge.net/viewvc/mscore/trunk/mscore/mscore/

Display CMakeLists.txt from MuseScore CERTI : https://savannah.nongnu.org/projects/certi/ http://cvs.savannah.gnu.org/viewvc/certi/?root=certi

CMake (of course): http://www.cmake.org LLVM: http://llvm.org/docs/CMake.html a lot more . . .

CMake tutorial N

51 / 118

Discovering environment specificities

What about projectConfig.h file? I Project config files Sometimes it’s easier to test for feature and then write a configuration file (config.h, project config.h, . . . ). The CMake way to do that is to: 1

lookup system informations 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.

CMake tutorial N

52 / 118

Discovering environment specificities

What about projectConfig.h file? II Listing 9: Excerpt from CERTI project main CMakeLists.txt 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

# Load C h ec ke r macros INCLUDE ( C h e c k F u n c t i o n E x i s t s ) FIND FILE ( HAVE STDINT H NAMES s t d i n t . h ) FIND FILE ( HAVE SYS SELECT H NAMES s e l e c t . h PATH SUFFIXES s y s ) INCLUDE ( C h e c k I n c l u d e F i l e ) CHECK INCLUDE FILE ( time . h HAVE TIME H ) FIND LIBRARY ( RT LIBRARY r t ) i f ( RT LIBRARY ) SET( CMAKE REQUIRED LIBRARIES ${CMAKE REQUIRED LIBRARIES} ${RT LIBRARY } ) e n d i f ( RT LIBRARY ) CHECK FUNCTION EXISTS ( c l o c k g e t t i m e HAVE CLOCK GETTIME) CHECK FUNCTION EXISTS ( c l o c k s e t t i m e HAVE CLOCK SETTIME ) CHECK FUNCTION EXISTS ( c l o c k g e t r e s HAVE CLOCK GETRES ) CHECK FUNCTION EXISTS ( c l o c k n a n o s l e e p HAVE CLOCK NANOSLEEP) IF (HAVE CLOCK GETTIME AND HAVE CLOCK SETTIME AND HAVE CLOCK GETRES ) SET( HAVE POSIX CLOCK 1 ) ENDIF (HAVE CLOCK GETTIME AND HAVE CLOCK SETTIME AND HAVE CLOCK GETRES ) ... CONFIGURE FILE ( ${CMAKE CURRENT SOURCE DIR} / c o n f i g . h . cmake ${CMAKE CURRENT BINARY DIR} / c o n f i g . h )

CMake tutorial N

53 / 118

Discovering environment specificities

What about projectConfig.h file? III 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Excerpt from CERTI config.h.cmake /* define if the compiler has numeric_limits */ #cmakedefine HAVE_NUMERIC_LIMITS /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRINGS_H 1 ... /* Name of package */ #cmakedefine PACKAGE "@PACKAGE_NAME@" /* Define to the address where bug reports for this package should be sent. */ #cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" /* Define to the full name of this package. */ #cmakedefine PACKAGE_NAME "@PACKAGE_NAME@" /* Define to the full name and version of this package. */ #cmakedefine PACKAGE_STRING "@PACKAGE_NAME@-@PACKAGE_VERSION@"

CMake tutorial N

54 / 118

Discovering environment specificities

What about projectConfig.h file? IV And you get something like: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Excerpt from generated CERTI config.h /* define if the compiler has numeric_limits */ #define HAVE_NUMERIC_LIMITS /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 ... /* Name of package */ /* #undef PACKAGE */ /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "[email protected]" /* Define to the full name of this package. */ #define PACKAGE_NAME "CERTI" /* Define to the full name and version of this package. */ /* #undef PACKAGE_STRING */

CMake tutorial N

55 / 118

Discovering environment specificities

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

56 / 118

Discovering environment specificities

The

find package

command I

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

Listing 10: using libxml2 1 2 3 4 5 6 7 8 9

f i n d p a c k a g e ( LibXml2 ) i f ( LIBXML2 FOUND ) a d d d e f i n i t i o n s (−DHAVE XML ${LIBXML2 DEFINITIONS } ) i n c l u d e d i r e c t o r i e s ( ${LIBXML2 INCLUDE DIR } ) e l s e ( LIBXML2 FOUND ) s e t ( LIBXML2 LIBRARIES "" ) e n d i f ( LIBXML2 FOUND ) ... t a r g e t l i n k l i b r a r i e s ( MyTarget ${LIBXML2 LIBRARIES } ) CMake tutorial N

57 / 118

Discovering environment specificities

The

find package

command II

Find modules usually defines standard variables (for module XXX) 1

2

3

4

5 6

XXX FOUND: Set to false, or undefined, if we haven’t found, or don’t want to use XXX. XXX INCLUDE DIRS: The final set of include directories listed in one variable for use by client code. XXX LIBRARIES: The libraries to link against to use XXX. These should include full paths. XXX DEFINITIONS: Definitions to use when compiling code that uses XXX. XXX EXECUTABLE: Where to find the XXX tool. 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 (130 as of CMake 2.8.7)

CMake tutorial N

58 / 118

Discovering environment specificities

The

find package

command III

You may write your own: http://www.cmake.org/Wiki/CMake:Module_Maintainers You may find/borrow modules from other projects which use CMake KDE4: http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/ PlPlot: http://plplot.svn.sourceforge.net/viewvc/plplot/ trunk/cmake/modules/ http://cmake-modules.googlecode.com/svn/trunk/Modules/ probably many more. . .

A module may provide not only CMake variables but new CMake macros (we will see that later with the MACRO, FUNCTION CMake language commands)

CMake tutorial N

59 / 118

Discovering environment specificities

The other

find xxxx

commands I

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 reside: find path

CMake tutorial N

60 / 118

Discovering environment specificities

The other 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

find xxxx

commands II

# − Find P r e l u d e c o m p i l e r # 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 . # 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 # T h i s module d e f i n e s # PRELUDE COMPILER , t h e p r e l u d e c o m p i l e r # 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 # PRELUDE INCLUDE DIR , where t o f i n d dword . h , e t c . # 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 . # 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 # 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 . ... i f ( PRELUDE PATH HINT ) message (STATUS "FindPrelude: using PATH HINT: ${PRELUDE_PATH_HINT}" ) else ( ) s e t ( PRELUDE PATH HINT ) endif ( ) # 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 f i n d p r o g r a m ( PRELUDE COMPILER NAMES p r e l u d e c PATHS ${PRELUDE PATH HINT} PATH SUFFIXES b i n NO DEFAULT PATH DOC "Path to the Prelude compiler command ’preludec ’" ) f i n d p r o g r a m ( PRELUDE COMPILER NAMES p r e l u d e c PATHS ${PRELUDE PATH HINT} PATH SUFFIXES b i n DOC "Path to the Prelude compiler command ’preludec ’" )

CMake tutorial N

61 / 118

Discovering environment specificities

The other 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

find xxxx

commands III

i f ( PRELUDE COMPILER ) # 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 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) # remove b i n 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) # add p a t h t o PRELUDE PATH HINT l i s t (APPEND PRELUDE PATH HINT ${PRELUDE PATH} ) e x e c u t e p r o c e s s (COMMAND ${PRELUDE COMPILER} −v e r s i o n OUTPUT VARIABLE PRELUDE COMPILER VERSION OUTPUT STRIP TRAILING WHITESPACE ) e n d i f ( PRELUDE COMPILER ) f i n d p a t h ( PRELUDE INCLUDE DIR NAMES dword . h PATHS ${PRELUDE PATH HINT} PATH SUFFIXES l i b / p r e l u d e DOC "The Prelude include headers" ) ... # 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 # a l l l i s t e d v a r i a b l e s a r e TRUE i n c l u d e ( FindPackageHandleStandardArgs ) FIND PACKAGE HANDLE STANDARD ARGS(PRELUDE REQUIRED VARS PRELUDE COMPILER PRELUDE INCLUDE DIR )

CMake tutorial N

62 / 118

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 . . . )

CMake tutorial N

63 / 118

Discovering environment specificities

Advanced use of external package II ExternalProject Add The ExternalProject.cmake CMake module defines a highlevel 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

CMake tutorial N

64 / 118

More CMake scripting

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

65 / 118

More CMake scripting

The different CMake “modes” Normal mode: the mode used when processing CMakeLists.txt Command mode: cmake -E , command line mode which offers basic command in a portable way:

Process scripting mode: cmake -P , used to execute a CMake script which is not a CMakeLists.txt. Wizard mode: cmake -i, interactive equivalent of the Normal mode.

CMake tutorial N

66 / 118

More CMake scripting

The different CMake “modes” Normal mode: the mode used when processing CMakeLists.txt Command mode: cmake -E , command line mode which offers basic command 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 , used to execute a CMake script which is not a CMakeLists.txt. Wizard mode: cmake -i, interactive equivalent of the Normal mode.

CMake tutorial N

66 / 118

More CMake scripting

The different CMake “modes” Normal mode: the mode used when processing CMakeLists.txt Command mode: cmake -E , command line mode which offers basic command 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 , used to execute a CMake script which is not a CMakeLists.txt. Not all CMake commands are scriptable!! Wizard mode: cmake -i, interactive equivalent of the Normal mode.

CMake tutorial N

66 / 118

More CMake scripting

Command mode Just try: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

list of command mode commands $ cmake -E CMake Error: cmake version 2.8.7 Usage: cmake -E [command] [arguments ...] Available commands: chdir dir cmd [args]... - run command in a given directory compare_files file1 file2 - check if file1 is same as file2 copy file destination - copy file to destination (either file or directory) copy_directory source destination - copy directory ’source’ content to directory ’destination’ copy_if_different in-file out-file - copy file if input has changed echo [string]... - displays arguments as text echo_append [string]... - displays arguments as text but no new line environment - display the current environment make_directory dir - create a directory md5sum file1 [...] - compute md5sum of files remove [-f] file1 file2 ... - remove the file(s), use -f to force it remove_directory dir - remove a directory and its contents rename oldname newname - rename a file or directory (on one volume) tar [cxt][vfz][cvfj] file.tar file/dir1 file/dir2 ... - create a tar archive time command [args] ... - run command and return elapsed time touch file - touch a file. touch_nocreate file - touch a file but do not create it. Available on UNIX only: create_symlink old new - create a symbolic link new -> old

CMake tutorial N

67 / 118

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 Remember: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

$ cmake --help-command-list $ cmake --help-command $ cmake --help-command message cmake version 2.8.7 message Display a message to the user. message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...) The optional keyword determines the type of message: (none) = Important information STATUS = Incidental information WARNING = CMake Warning, continue processing AUTHOR_WARNING = CMake Warning (dev), continue processing SEND_ERROR = CMake Error, continue but skip generation FATAL_ERROR = CMake Error, stop all processing CMake tutorial N

68 / 118

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, . . . CMake tutorial N

69 / 118

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 CMake package using a previously installed CMake. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

# # # # # # # # #

Simple cmake s c r i p t which may be used t o b u i l d 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 cd tmp / cmake −P CMake−a u t o b u i l d−v2 . cmake you s h o u l d end up w i t h a tmp / cmake−x . y . z s o u r c e t r e e tmp / cmake−x . y . z−b u i l d b u i l d t r e e 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 .

cmake minimum required (VERSION 2 . 8 ) s e t (CMAKE VERSION "2.8.7" ) s e t ( CMAKE FILE PREFIX "cmake -${CMAKE_VERSION}" ) s e t (CMAKE REMOTE PREFIX "http :// www.cmake.org/files/v2.8/" ) s e t ( CMAKE FILE SUFFIX ".tar.gz" ) s e t ( CMAKE BUILD TYPE "Debug" ) s e t (CPACK GEN "TGZ" )

CMake tutorial N

70 / 118

More CMake scripting

Portable script for building CMake II 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

s e t ( LOCAL FILE "./${CMAKE_FILE_PREFIX}${CMAKE_FILE_SUFFIX}" ) s e t ( REMOTE FILE "${CMAKE_REMOTE_PREFIX}${CMAKE_FILE_PREFIX}${CMAKE_FILE_SUFFIX}" ) message (STATUS "Trying to autoinstall CMake version ${CMAKE_VERSION} using ${ REMOTE_FILE} file ..." ) message (STATUS "Downloading ..." ) i f ( EXISTS ${LOCAL FILE } ) message (STATUS "Already there: nothing to do" ) e l s e ( EXISTS ${LOCAL FILE } ) message (STATUS "Not there , trying to download ..." ) f i l e (DOWNLOAD ${REMOTE FILE} ${LOCAL FILE} TIMEOUT 600 STATUS DL STATUS LOG DL LOG SHOW PROGRESS) l i s t (GET DL STATUS 0 DL NOK) i f ( "${DL_LOG}" MATCHES "404 Not Found" ) s e t (DL NOK 1 ) e n d i f ( "${DL_LOG}" MATCHES "404 Not Found" ) i f (DL NOK) # 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 # 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 f i l e (REMOVE ${LOCAL FILE } ) message (SEND ERROR "Download failed: ${DL_LOG}" )

CMake tutorial N

71 / 118

More CMake scripting

Portable script for building CMake III 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

e l s e (DL NOK) message (STATUS "Download successful." ) e n d i f (DL NOK) e n d i f ( EXISTS ${LOCAL FILE } ) message (STATUS "Unarchiving the file" ) 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} RESULT VARIABLE UNTAR RES OUTPUT VARIABLE UNTAR OUT ERROR VARIABLE UNTAR ERR ) message (STATUS "CMake version ${CMAKE_VERSION} has been unarchived in ${ CMAKE_CURRENT_SOURCE_DIR }/${CMAKE_FILE_PREFIX }." ) message (STATUS "Configuring with CMake (build type=${CMAKE_BUILD_TYPE })..." ) f i l e (MAKE DIRECTORY ${CMAKE FILE PREFIX}−b u i l d ) e x e c u t e p r o c e s s (COMMAND ${CMAKECOMMAND} −DCMAKE BUILD TYPE=${CMAKE BUILD TYPE} − DBUILD QtDialog :BOOL=ON . . / ${CMAKE FILE PREFIX} WORKING DIRECTORY ${CMAKE FILE PREFIX}−b u i l d RESULT VARIABLE CONFIG RES OUTPUT VARIABLE CONFIG OUT ERROR VARIABLE CONFIG ERR TIMEOUT 2 0 0 ) message (STATUS "Building with cmake --build ..." )

CMake tutorial N

72 / 118

More CMake scripting

Portable script for building CMake IV 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

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

CMake tutorial N

73 / 118

More CMake scripting

Build specific commands create executable or library: add executable, add library add compiler/linker definitions/options: add definition , 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 : 190+ different properties may be used.

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

CMake tutorial N

74 / 118

More CMake scripting

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

75 / 118

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

Executable 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 CMake tutorial N

76 / 118

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.

CMake tutorial N

77 / 118

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 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). CMake tutorial N

78 / 118

More CMake scripting

Custom targets and commands Custom Custom targets and custom commands are a way to create target which may be used to execute arbitrary command 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), ...

CMake tutorial N

79 / 118

More CMake scripting

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

80 / 118

More CMake scripting

Generated files List all the sources CMake advocates to specify all the source files explicitly (this 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 this case you must tell CMake that they are GENERATED files using: 1 2

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} PROPERTIES GENERATED TRUE)

CMake tutorial N

81 / 118

More CMake scripting

The CMake workflow (pictured) CMakeLists.txt

Project file(s), Makefiles, . . .

Object files

Installed files

Source files Generated Sources files

Binary package

CMake time

Source package

Build time Install time

Installed package

CPack time Package Install time

CMake tutorial N

82 / 118

More CMake scripting

Example I 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

### 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 i n c l u d e d i r e c t o r i e s ( ${CMAKE CURRENT SOURCE DIR} ) f i n d p a c k a g e ( LexYacc ) 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 ) s e t ( YACC OUT PREFIX ${CMAKE CURRENT BINARY DIR} / y . tab ) 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 ) 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 ) 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 ) 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 ) #Exec Lex add custom command ( OUTPUT ${LEX WANTED OUT PREFIX } . c COMMAND ${LEX PROGRAM} ARGS −l −o${LEX WANTED OUT PREFIX } . c ${LEX SRC} DEPENDS ${LEX SRC} ) s e t (GENERATED SRCS ${GENERATED SRCS} ${LEX WANTED OUT PREFIX } . c ) #Exec Yacc add custom command ( OUTPUT ${YACC WANTED OUT PREFIX } . c ${YACC WANTED OUT PREFIX } . h COMMAND ${YACC PROGRAM} ARGS ${YACC COMPAT ARG} −d ${YACC SRC} COMMAND ${CMAKECOMMAND} −E copy ${YACC OUT PREFIX } . h ${YACC WANTED OUT PREFIX } . h COMMAND ${CMAKECOMMAND} −E copy ${YACC OUT PREFIX } . c ${YACC WANTED OUT PREFIX } . c DEPENDS ${YACC SRC}

CMake tutorial N

83 / 118

More CMake scripting

Example II 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

) s e t (GENERATED SRCS ${GENERATED SRCS} ${YACC WANTED OUT PREFIX } . c ${YACC WANTED OUT PREFIX } . h ) # 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 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) # 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 # 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 . . . # GNU CC s p e c i f i c w a r n i n g s t o p i f ( CMAKE COMPILER IS GNUCC ) message (STATUS "INHIBIT Compiler warning for LEX/YACC generated files" ) SET SOURCE FILES PROPERTIES ( ${YACC WANTED OUT PREFIX } . c ${YACC WANTED OUT PREFIX } . h PROPERTIES COMPILE FLAGS "-w" ) SET SOURCE FILES PROPERTIES ( ${LEX WANTED OUT PREFIX } . c PROPERTIES COMPILE FLAGS "-w" ) e n d i f ( CMAKE COMPILER IS GNUCC ) ... s e t ( LSCHED SRC lsmc dependency . c l s m c c o r e . c l s m c u t i l s . c lsmc time . c l s m c t a s k f i l e p a r s e r . c ${GENERATED SRCS} ) a d d l i b r a r y ( lsmc ${LSCHED SRC} )

CMake tutorial N

84 / 118

Advanced CMake usage

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

85 / 118

Advanced CMake usage

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

86 / 118

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 Toolchain see http://www.cmake.org/Wiki/CMake_Cross_Compiling. 1 2 3

mkdir build-win32 cd build-win32 cmake -DCMAKE_TOOLCHAIN_FILE=../totally-free/Toolchain-cross-mingw32-linux.cmake ../totally-free/

Demo CMake tutorial N

87 / 118

Advanced CMake usage

Linux to Win32 Toolchain example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

# 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 SET(CMAKE SYSTEM NAME Windows ) # 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 # f o r c l a s s i c a l mingw32 see h t t p : / / www . mingw . o r g / #s e t ( COMPILER PREFIX ” i 5 8 6−mingw32msvc ” ) # f o r 32 o r 64 b i t s mingw−w64 see h t t p : / / mingw−w64 . s o u r c e f o r g e . n e t / s e t ( COMPILER PREFIX "i686 -w64 -mingw32" ) #s e t ( COMPILER PREFIX ” x 8 6 6 4−w64−mingw32 ” # which c o m p i l e r s t o use f o r C and C++ f i n d p r o g r a m (CMAKE RC COMPILER NAMES ${COMPILER PREFIX}−w i n d r e s ) #SET ( CMAKE RC COMPILER ${COMPILER PREFIX}−w i n d r e s ) f i n d p r o g r a m (CMAKE C COMPILER NAMES ${COMPILER PREFIX}−gcc ) #SET ( CMAKE C COMPILER ${COMPILER PREFIX}−g c c ) f i n d p r o g r a m (CMAKE CXX COMPILER NAMES ${COMPILER PREFIX}−g++) #SET ( CMAKE CXX COMPILER ${COMPILER PREFIX}−g++) # here i s the t a r g e t environment located SET(USER ROOT PATH / home / e r k / erk−win32−dev ) SET(CMAKE FIND ROOT PATH / u s r / ${COMPILER PREFIX} ${USER ROOT PATH} ) # 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 : # 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 # programs i n the host environment s e t (CMAKE FIND ROOT PATH MODE PROGRAM NEVER) s e t ( CMAKE FIND ROOT PATH MODE LIBRARY ONLY) s e t (CMAKE FIND ROOT PATH MODE INCLUDE ONLY) CMake tutorial N

88 / 118

Advanced CMake usage

Outline 1

Basic CMake usage

2

Discovering environment specificities Handling platform specificities Working with external packages

3

More CMake scripting Custom commands Generated files

4

Advanced CMake usage Cross-compiling with CMake Export your project

CMake tutorial N

89 / 118

Advanced CMake usage

Exporting/Import your project Export/Import to/from others CMake can help project using CMake as a build system to export/import targets to/from other project using CMake as a build system. No more time for that today sorry, see: http://www.cmake.org/Wiki/CMake/Tutorials/Exporting_ and_Importing_Targets

CMake tutorial N

90 / 118

CPack: Packaging made easy

Outline

5

CPack: Packaging made easy

6

CPack with CMake

7

Various package generators

CMake tutorial N

91 / 118

CPack: Packaging made easy

Introduction A Package generator In the same way as CMake generates build files, CPack generates packager files. Archive generators [ZIP,TGZ,. . . ] (All platforms) DEB, RPM (Linux) Cygwin Source or Binary (Windows/Cygwin) NSIS (Windows, Linux) DragNDrop, Bundle, OSXX11 (MacOS) CMake tutorial N

92 / 118

CPack with CMake

Outline

5

CPack: Packaging made easy

6

CPack with CMake

7

Various package generators

CMake tutorial N

93 / 118

CPack with CMake

The CMake workflow (pictured) CMakeLists.txt

Project file(s), Makefiles, . . .

Object files

Installed files

Source files Generated Sources files

Binary package

CMake time

Source package

Build time Install time

Installed package

CPack time Package Install time

CMake tutorial N

94 / 118

CPack with CMake

The CPack application CPack standalone CPack is a standalone application which 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) CMake tutorial N

95 / 118

CPack with CMake

CPack variables in CMakeLists.txt When used with CMake, one writes something like this in CMakeLists.txt: 1 2 3 4 5 6 7 8 9 10 11

s e t (CPACK GENERATOR "TGZ" ) i f ( WIN32 ) l i s t (APPEND CPACK GENERATOR "NSIS" ) e l s e i f (APPLE) l i s t (APPEND CPACK GENERATOR "Bundle" ) e n d i f ( WIN32 ) s e t (CPACK SOURCE GENERATOR "ZIP;TGZ" ) s e t (CPACK PACKAGE VERSION MAJOR 0 ) s e t ( CPACK PACKAGE VERSION MINOR 1 ) s e t ( CPACK PACKAGE VERSION PATCH 0 ) 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. CMake tutorial N

96 / 118

CPack with CMake

A CPack config file I A CPack config file looks like this one: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

# 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 . # 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 # 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 . ... SET( CPACK BINARY BUNDLE "" ) SET( CPACK BINARY CYGWIN "" ) SET( CPACK BINARY DEB "" ) ... SET( CPACK BINARY ZIP "" ) SET(CPACK CMAKE GENERATOR "Unix Makefiles" ) SET(CPACK GENERATOR "TGZ" ) SET( CPACK INSTALL CMAKE PROJECTS "/home/erk/erkit/CMakeTutorial/ examples/build;TotallyFree;ALL;/" ) SET( CPACK INSTALL PREFIX "/usr/local" ) SET(CPACK MODULE PATH "" ) SET( CPACK NSIS DISPLAY NAME "TotallyFree 0.1.0" )

CMake tutorial N

97 / 118

CPack with CMake

A CPack config file II 16 17 18 19 20 21

22 23 24 25 26 27 28 29

SET( CPACK NSIS INSTALLER ICON CODE "" ) SET( CPACK NSIS INSTALL ROOT "$PROGRAMFILES" ) SET( CPACK NSIS PACKAGE NAME "TotallyFree 0.1.0" ) SET( CPACK OUTPUT CONFIG FILE "/home/erk/erkit/CMakeTutorial/ examples/build/CPackConfig.cmake" ) SET(CPACK PACKAGE DEFAULT LOCATION "/" ) SET( CPACK PACKAGE DESCRIPTION FILE "/home/erk/CMake/cmake -Verk HEAD/share/cmake -2.8/ Templates/CPack.GenericDescription.txt ") SET(CPACK PACKAGE DESCRIPTION SUMMARY "TotallyFree built using CMake" ) SET( CPACK PACKAGE FILE NAME "TotallyFree -0.1.0 - Linux" ) SET( CPACK PACKAGE INSTALL DIRECTORY "TotallyFree 0.1.0" ) SET( CPACK PACKAGE INSTALL REGISTRY KEY "TotallyFree 0.1.0" ) SET(CPACK PACKAGE NAME "TotallyFree" ) SET(CPACK PACKAGE RELOCATABLE "true" ) SET(CPACK PACKAGE VENDOR "Humanity" ) SET( CPACK PACKAGE VERSION "0.1.0" )

CMake tutorial N

98 / 118

CPack with CMake

A CPack config file III 30 31 32 33 34 35 36 37 38 39 40 41 42

SET( CPACK RESOURCE FILE LICENSE "/home/erk/CMake/cmake -Verk -HEAD /share/cmake -2.8/ Templates/CPack.GenericLicense.txt" ) SET( CPACK RESOURCE FILE README "/home/erk/CMake/cmake -Verk -HEAD/ share/cmake -2.8/ Templates/CPack.GenericDescription.txt" ) SET( CPACK RESOURCE FILE WELCOME "/home/erk/CMake/cmake -Verk -HEAD /share/cmake -2.8/ Templates/CPack.GenericWelcome.txt" ) SET( CPACK SET DESTDIR "OFF" ) SET(CPACK SOURCE CYGWIN "" ) SET(CPACK SOURCE GENERATOR "TGZ;TBZ2;TZ" ) SET( CPACK SOURCE OUTPUT CONFIG FILE "/home/erk/erkit/ CMakeTutorial/examples/build/ CPackSourceConfig.cmake" ) SET( CPACK SOURCE TBZ2 "ON" ) SET(CPACK SOURCE TGZ "ON" ) SET( CPACK SOURCE TZ "ON" ) SET( CPACK SOURCE ZIP "OFF" ) SET(CPACK SYSTEM NAME "Linux" ) SET(CPACK TOPLEVEL TAG "Linux" )

CMake tutorial N

99 / 118

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

Currently cpack has [almost] no builtin documentation support besides cpack --help (work is underway though), thus the best CPack documentation is currently found on the Wiki: http://www.cmake.org/Wiki/CMake:CPackConfiguration http://www.cmake.org/Wiki/CMake:CPackPackageGenerators http://www.cmake.org/Wiki/CMake: Component_Install_With_CPack

CMake tutorial N

100 / 118

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 3 3 3

(re)sets CPACK GENERATOR to the one currently being iterated over includes the CPACK PROJECT CONFIG FILE installs the project into CPack private location (using DESTDIR) calls the generator and produces the package(s) for that generator

CMake tutorial N

101 / 118

CPack with CMake

CPack running steps III 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

cpack command line example $ cpack -G "TGZ;RPM" CPack: Create package using TGZ CPack: Install projects CPack: - Run preinstall target for: TotallyFree CPack: - Install project: TotallyFree CPack: Create package CPack: - package: /build/TotallyFree-0.1.0-Linux.tar.gz generated. CPack: Create package using RPM CPack: Install projects CPack: - Run preinstall target for: TotallyFree CPack: - Install project: TotallyFree CPack: Create package CPackRPM: Will use GENERATED spec file: /build/_CPack_Packages/Linux/RPM/SPECS/totallyfree.spec

CPack: - package: /build/TotallyFree-0.1.0-Linux.rpm generated. $

CMake tutorial N

102 / 118

CPack with CMake

CPack running steps IV 1 2 3 4 5 6 7 8 9 10 11

make package example $ make package [ 33%] Built target acrodict [ 66%] Built target Acrodictlibre [100%] Built target Acrolibre Run CPack packaging tool... CPack: Create package using TGZ CPack: Install projects CPack: - Run preinstall target for: TotallyFree CPack: - Install project: TotallyFree CPack: Create package 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. CMake tutorial N

103 / 118

CPack with CMake

CPack running steps V 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

make package source example $ make package_source make package_source Run CPack packaging tool for source... CPack: Create package using TGZ CPack: Install projects CPack: - Install directory: /totally-free CPack: Create package CPack: - package: /build/TotallyFree-0.1.0-Source.tar.gz generated. CPack: Create package using TBZ2 CPack: Install projects CPack: - Install directory: /totally-free CPack: Create package CPack: - package: /build/TotallyFree-0.1.0-Source.tar.bz2 generated. CPack: Create package using TZ CPack: Install projects CPack: - Install directory: /totally-free CPack: Create package CPack: - package: /build/TotallyFree-0.1.0-Source.tar.Z generated. CMake tutorial N

104 / 118

CPack with CMake

The CPack workflow (pictured) CMakeLists.txt

Source files

CMake tutorial N

105 / 118

CPack with CMake

The CPack workflow (pictured) CMakeLists.txt

Tree rce

Sou

Source files

CMake tutorial N

105 / 118

CPack with CMake

The CPack workflow (pictured) CMakeLists.txt

Tree rce

Sou

Source files

ild Bu

ee Tr

CMake time Build time Install time (from CPack) CPack time Package Install time

CMake tutorial N

105 / 118

CPack with CMake

The CPack workflow (pictured) CMakeLists.txt

CPackConfig.cmake

Tree rce

Sou

Source files

CMake time

ild Bu

ee Tr

CPackSourceConfig.cmake

Build time Install time (from CPack) CPack time Package Install time

CMake tutorial N

105 / 118

CPack with CMake

The CPack workflow (pictured) CMakeLists.txt

CPackConfig.cmake

Tree rce

Sou

Source files

CMake time

ild Bu

ee Tr

CPackSourceConfig.cmake

Build time Install time (from CPack) CPack time Package Install time

Source package

CMake tutorial N

105 / 118

CPack with CMake

The CPack workflow (pictured) CMakeLists.txt

CPackConfig.cmake

Tree rce

Sou

Source files

CMake time

ild Bu

ee Tr

CPack Installed files

CPackSourceConfig.cmake

Build time Install time (from CPack) CPack time Package Install time

Source package

CMake tutorial N

105 / 118

CPack with CMake

The CPack workflow (pictured) CMakeLists.txt

CPackConfig.cmake

Tree rce

Sou

Source files

CMake time

ild Bu

ee Tr

CPack Installed files

Binary package

CPackSourceConfig.cmake

Build time Install time (from CPack) CPack time Package Install time

Source package

CMake tutorial N

105 / 118

CPack with CMake

The CPack workflow (pictured) CMakeLists.txt

CPackConfig.cmake

Tree rce

Sou

Source files

CMake time

ild Bu

ee Tr

CPack Installed files

Binary package

Installed package

CPackSourceConfig.cmake

Build time Install time (from CPack) CPack time Package Install time

Source package

CMake tutorial N

105 / 118

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 directories with install, exclude and include rules. CPack binary package The CPack configuration file is: CPackConfig.cmake. Moreover CPack knows that a project is built with CMake and inherits many properties from the install rules found in the project. CMake tutorial N

106 / 118

Various package generators

Outline

5

CPack: Packaging made easy

6

CPack with CMake

7

Various package generators

CMake tutorial N

107 / 118

Various package generators

Archive Generators A family of generators The archive generators is a family of generators which is supported 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 ZIP Zip archive CMake tutorial N

108 / 118

Various package generators

Linux-friendly generators Tar-kind archive generators Binary RPM: only needs rpmbuild to work. Binary DEB: works on any Linux distros.

CPack vs native tools One could argue “why using CPack for building .deb or .rpm”. The primary target of CPack RPM and DEB generators are people who are NOT professional packager. Those people can get a clean package without too much effort and get better package than a bare TAR archive. No official packaging replacement Those generators are no replacement for official packaging tools. CMake tutorial N

109 / 118

Various package generators

Windows-friendly generators Zip archive generator NullSoft System Installer generator (http://nsis.sourceforge.net/ Support component installation, produce nice GUI installer. MSI installer requested: http://public.kitware.com/Bug/view.php?id=11575. Cygwin: Binary and Source generators.

CMake tutorial N

110 / 118

Various package generators

MacOS-friendly generators Tar-kind archive generators

Bundle

DragNDrop PackageMaker

OSXX11

Don’t ask me I’m not a MacOS user and I don’t know them. Go and read the Wiki or ask on the ML. http://www.cmake.org/Wiki/CMake: CPackPackageGenerators http://www.cmake.org/cmake/help/mailing.html

CMake tutorial N

111 / 118

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. CMake tutorial N

112 / 118

Various package generators

Packaging Components II demo with ComponentExample More detailed documentation here: http://www.cmake.org/Wiki/CMake:Component_Install_With_CPack

Component aware generator Not all generators do support component (i.e. they are MONOLITHIC) Some produce a single package file containing all components. (e.g. NSIS) Others produce several package files containing one or several components. (e.g. ArchiveGenerator, RPM, DEB) CMake tutorial N

113 / 118

Systematic Testing

Outline

8

Systematic Testing

9

CTest submission to CDash

10

References

CMake tutorial N

114 / 118

CTest submission to CDash

Outline

8

Systematic Testing

9

CTest submission to CDash

10

References

CMake tutorial N

115 / 118

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/ CDash 2.0 should be released in the next few weeks (mid-february) A course on CMake/CTest/CDash in Lyon on April, 2 2012 (http://formations.kitware.fr) CMake tutorial N

116 / 118

References

Outline

8

Systematic Testing

9

CTest submission to CDash

10

References

CMake tutorial N

117 / 118

References

References I CDash home page, Feb. 2011. http://www.cdash.org.

CMake home page, Feb. 2012. http://www.cmake.org.

CMake Wiki, Feb. 2012. http://www.cmake.org/Wiki/CMake.

Development/CMake on KDE TechBase, Feb. 2012. http://techbase.kde.org/Development/CMake.

Ken Martin and Bill Hoffman. Mastering CMake: A Cross-Platform Build System. Kitware, Inc., 5th edition edition, 2010. ISBN-13 978-1930934221.

CMake tutorial 118 / 118 N

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF