Sei sulla pagina 1di 22

Rodolfo Lima

rodolfo@digitok.com.br
CMake
Behind the Scenes of Code Development

Outline

Motivation

CMake features

Basic usage

Medium-sized projects

FLTK-based projects

CMake scripting

Multi-platform environments

Troubleshooting

Conclusion

eferences

Motivation
GNU Autotools
ed / vi / emacs
CMakeLists.txt
cmake
Makefile
make
Develoer
User
CMake
ed / vi / emacs
Makefile
make
Develoer
User
Make

Kitware's CMake Features

Multi-environment ! Multi-platform

"isual #tudio projects$ Make!%CC$ &Code$ 'ou name it(

)ases project maintenance

*ne +recipe, to rule them all -.

/igh scalabilit'

C!C00 header dependenc' anal'sis

Multiple languages 1C$ C00$ Fortran.

/uman-parseable project definition

Cross-compiling$ canadian-cross st'le

2ice compiler output formatter 13hen using Make.

Can build project installers 13orks 3ith 2ullsoft4s 2#5# on 6indo3s.

7utomated testsuites

K8) and *penC" use CMake$ it must be good



Basic Usage
9( Create program source-
main(c
#include <stdio.h>
int main()
{
printf(Hello, nurse!\n);
return ;
!
:( Create project definition-
CMakeLists(t;t
pro"ect(hello)
add#e$ecuta%le(hello main.c)
<( %enerate Makefile
rodolfo@sabbat! " # cmake .
$$ %!e C comiler ide&tificatio& is GNU
$$ %!e C'' comiler ide&tificatio& is GNU
$$ C!eck for (orki&g C comiler) /usr/bi&/gcc
$$ C!eck for (orki&g C comiler) /usr/bi&/gcc $$ (orks
$$ Detecti&g C comiler A*+ i&fo
$$ Detecti&g C comiler A*+ i&fo $ do&e
$$ C!eck for (orki&g C'' comiler) /usr/bi&/c,,
$$ C!eck for (orki&g C'' comiler) /usr/bi&/c,, $$ (orks
$$ Detecti&g C'' comiler A*+ i&fo
$$ Detecti&g C'' comiler A*+ i&fo $ do&e
$$ Co&figuri&g do&e
$$ Ge&erati&g do&e
$$ *uild files !ave bee& (ritte& to) /!ome/rodolfo
=( Compile>
rodolfo@sabbat! " # make
-ca&&i&g dee&de&cies of target !ello
./0012 *uildi&g C ob3ect CMake4iles/!ello.dir/mai&.c.o
Li&ki&g C executable !ello
./0012 *uilt target !ello

Filtered Make Output
rodolfo&sa%%ath '(src(panostitch(rel(src ) ma*e
+ ,- .eneratin/ ..(..(src(pch.h./ch(panostitch#0el1ith2e%3nfo.h44
+ 5,- 6uilt tar/et panostitch#pch.h
+ 5,- 6uildin/ 7 o%"ect li%(s%a(78a*e9iles(s%a.dir(s%a#le:mar.c.o
(home(rodolfo(src(panostitch(li%(s%a(s%a#le:mar.c; 3n function <emalloc#<;
(home(rodolfo(src(panostitch(li%(s%a(s%a#le:mar.c;=>; ?arnin/; di:ision %@ Aero
+ B,- 6uildin/ 7 o%"ect li%(s%a(78a*e9iles(s%a.dir(s%a#le:mar#?rap.c.o
+ B,- 6uildin/ 7 o%"ect li%(s%a(78a*e9iles(s%a.dir(s%a#lapac*.c.o
+ C,- 6uildin/ 7 o%"ect li%(s%a(78a*e9iles(s%a.dir(s%a#crsm.c.o
+ C,- 6uildin/ 7 o%"ect li%(s%a(78a*e9iles(s%a.dir(s%a#ch*"ac.c.o
Din*in/ 7 static li%rar@ li%s%a.a
+ C,- 6uilt tar/et s%a
+ C,- 6uildin/ 7 o%"ect li%(le:mar(78a*e9iles(le:mar.dir(lm.c.o
+ >,- 6uildin/ 7 o%"ect li%(le:mar(78a*e9iles(le:mar.dir(E$%.c.o
+ >,- 6uildin/ 7 o%"ect li%(le:mar(78a*e9iles(le:mar.dir(misc.c.o
+ F5,- 6uildin/ 7 o%"ect li%(le:mar(78a*e9iles(le:mar.dir(lmlec.c.o
+ F5,- 6uildin/ 7 o%"ect li%(le:mar(78a*e9iles(le:mar.dir(lm%c.c.o
+ FB,- 6uildin/ 7 o%"ect li%(le:mar(78a*e9iles(le:mar.dir(lm%lec.c.o
Din*in/ 7 static li%rar@ li%le:mar.a
+ FB,- 6uilt tar/et le:mar
...a&d so o& u&til /001 or a comiler/li&ker error stos t!e rocess

Created argets

Main target- hello

Builds the application

clean-

Cleans up 1some. generated files

depends-

ebuilds file dependencies in case something +feels, 3rong

*bject file- main(o 1per source file.

?reprocessed source- main(i 1per source file.

7ssembl' output- main(s 1per source file.

5f some dependent file changes$ its targets 3ill be rebuild


automaticall' during +make,(

5f CMakeLists(t;t changes$ cmake 3ill be run automaticall' during


+make, to recreate the build tree

This 3orks even in "isual #tudio 1the project gets reloaded.



Build !pes

?redefined compiler parameters according to build t'pe

8ebug @ used during development

elease @ used in production code

el6ith8eb5nfo @ helpful 3hen debugging production code

Min#izeel @ generates space optimized code

#pecified during build tree creation

cmake . -DCMAKE_BUILD_TYPE=(Debug|RelW!"DebI#$%|...&

%ood strateg'- out-of-source builds

Compiler parameters can be customized b' setting variables

'e!(CMAKE_C_(LA)*_DEBU) +,-CMAKE_C_(LA)*_DEBU). -gg/b0&

'e!(CMAKE_C11_(LA)*_RELEA*E +,-CMAKE_C11_(LA)*_RELEA*E. -230&



"#ternal $i%raries

#earch installed libraries multiplatform-ly


pro"ect(parser)
find#pac*a/e(Di%Gml5 0HIJ30H2)
include#directories(){D36G8D5#3K7DJ2H#230!)
add#e$ecuta%le(parser main.cpp)
tar/et#lin*#li%raries(parser ){D36G8D5#D360E03HL!)

7 lot of libraries supported

*pen%L$ FLTK$ 3;6idgets$ Boost$ #8L$ BL7#$ FreeT'pe$(((

Aou can 3rite 'our o3n finder 1not for the faint-hearted.

Creation as eas' as e;ecutables


add#li%rar@(<name> +LMEM37 N LHE0H2 N 8O2JDH-
+HG7DJ2H#90O8#EDD-
sourceF source5 source5...)

6hen librar' t'pe isn4t specified-

use globall' defined variable


6J3D2#LHE0H2#D36LP<true,false>

);ecutables 728 libraries can have built libraries as dependencies

%2B +convenience libraries, concept

?latform idios'ncrasies taken care of


$i%rar! &ro'ects

Medium(Si)ed &ro'ects

Multiple source directories

Custom processing not involving source files

T'pical source tree-

root

src

lib

lib9

lib:

lib<

testsuite

res

doc

)ach director' gets its CMakeLists(t;t

?arent director' adds its children using-

addCsubdirector'1DsubdirE.

Build tree must be configured in root director'>

CMake intelligentl' configures the 3hole


director' tree

Targets from other directories can be used


an'3here in the source tree

targetClinkClibraries1hello lib9 lib: lib<.



Source File Configuration

#ometimes C!C00 macros in source files are needed to cope 3ith


different s'stems

confi/ure#file and add#definitions comes to rescue-


confi/ure#file(<input> <output> +7OQROKDR- +HL7EQH#IJOMHL- +&OKDR-)
add#definitions(S29OO S26E0 ...)
pro"ect(ima/e#suite)
set(TH0L3OK U.)
set(QE7VE.H#KE8H ){78EVH#Q0OWH7M#KE8H!)
find#pac*a/e(WQH.)
find#pac*a/e(QK.)
find#pac*a/e(Di%Gml5)
confi/ure#file(confi/.h.in confi/.h
&OKDR)
if(D36G8D5#9OJK2)
add#definitions(S2HEL#G8DPF)
endif()
add#e$ecuta%le(con:ert con:ert.cpp)
#cma*edefine QK.#9OJK2 F
#cma*edefine WQH.#9OJK2 F
#define QE7VE.H#KE8H &QE7VE.H#KE8H&
#define TH0L3OK &TH0L3OK&
CMakeLists.txt

);ample
co&fig.!.i&
#define QK.#9OJK2 F
(( #undef WQH.#9OJK2
#define QE7VE.H#KE8H ima/e#suite
#define TH0L3OK U.
Ge&erated co&fig.!
#include confi/.h
#if WQH.#9OJK2
(( do "pe/ stuff
#endif
co&vert.c excert

Custom argets

6hen custom-build files ! actions are needed

fle; ! bison ! moc ! F


add#custom#tar/et(<name> +EDD- +commandF +ar/sF...--
+7O88EK2 command5 +ar/s5...- ...-
+2HQHK2L depend depend depend ... -
+1O0V3K.#230H7MO0R dir-
+7O88HKM comment- +TH06EM38-
+LOJ07HL srcF +src5...--)

);ample 9

Command to be used-
add#custom#tar/et(parser.c %ison So parser.c parser.@
LOJ07HL parser.@)
add#e$ecuta%le(hello main.c parser.c)

);ample :
add#custom#tar/et(car.pn/.c %in5c car.pn/
LOJ07HL car.pn/)
add#e$ecuta%le(%in5c %in5c.c)
add#e$ecuta%le(hello main.c car.pn/.c)

F$K(Based &ro'ects
pro"ect(ima/e#suite)
find#pac*a/e(9DMV)
find#pac*a/e(WQH.)
find#pac*a/e(QK. 0HIJ30H2)
add#li%rar@(con:ert con:ert.cpp)
tar/et#lin*#li%raries(con:ert ){QK.#D360E03HL!)
include#directories(){QK.#3K7DJ2H#230!)
if(WQH.#9OJK2)
tar/et#lin*#li%raries(con:ert ){WQH.#D360E03HL!)
include#directories(){WQH.#3K7DJ2H#230!)
endif()
if(9DMV#9OJK2)
flt*#?rap#ui(:ie?er :ie?er.fl)
add#e$ecuta%le(:ie?er :ie?er.cpp ){:ie?er#9DMV#J3#L07L!)
tar/et#lin*#li%raries(:ie?er con:ert ){9DMV#D360E03HL!)
include#directories(){9DMV#3K7DJ2H#230L!)
lin*#directories(){9DMV#D360E0R#230L!)
endif()

5ncludes commands to deal 3ith fluid-generated files

);ample-

CMake Scripting

2eeded for special processing

5ncludes t'pical programming language statements

Loops

Condition

"ariables

Lists

Macros

+Functions,

54d rather use Lua$ but it4s too late no3

);ample-
macro(add#tool name)
add#custom#tar/et(){name!.c create#tool ){name!)
add#e$ecuta%le(){name! ){name!.c)
tar/et#lin*#li%raries(){name! ){6oost#D360E03HL!)
endmacro()
add#tool(resiAe)
add#tool(in:ert)
add#tool(mirror)
add#tool(crop)

For loop
foreach(tool resiAe in:ert mirror crop)
messa/e(Qreparin/ tool ){tool!)
add#custom#tar/et(){tool!.c create#tool ){tool!)
add#e$ecuta%le(){tool! ){tool!.c)
tar/et#lin*#li%raries(){tool! ){6oost#D360E03HL!)
endforeach()

5f clause
if(13KU5)
do#somethin/#?eird()
elseif(EQQDH O0 JK3G)
do#somethin/#neat()
endif()
if(HG3LML some#file.dat)
process(some#file.dat)
endif()
if(additional#file 8EM7HHL Xfile#.Y))
process(){additional#file!)
endif()
Some Useful Statements

$ists

Bseful to manage long list of elements

)lements can be manipulated depending on running platform

Bseful for source file lists

);ample-
set(sources :ie?er.cpp confi/.cpp)
if(13KU5)
list(EQQHK2 sources :ie?er#mfc.cpp)
elseif(JK3G)
list(EQQHK2 sources :ie?er#/t*.cpp)
else
messa/e(9EMED Qlatform not supported)
endif()
add#e$ecuta%le(:ie?er ){sources!)
list(DHK.MH sources srclen)
messa/e(){srclen! source files)
foreach(src ){sources!)
messa/e(Lource; ){src!)
endforeach()

Multi(platform "nvironments

CMake generates project files for several environments

5t detects during build tree creation 3hich environment the user is on

5f detected environment isn4t the one 'ou 3ant$ use-

cma*e . S. </enerator t@pe>

%enerator t'pe can be-

Bni;- +Bni; Makefiles,$ +CodeBlocks @ Bni; Makefiles,$ +)clipse


C8T= @ Bni; Makefiles,$ +K8evelop<,$ F

6indo3s- +Min%6 Makefiles,$ +M#A# Makefiles,$ +2Make


Makefiles,$ +Borland Makefiles,$ +6atcom 6Make,$ +Bni;
Makefiles, 1c'g3in.$ +"isual #tudio G :HHI,$ +"isual #tudio J
:HHG,$(((

Mac*# &- +K8evelop<,$ +Bni; Makefiles,$ +&Code,



rou%leshooting

#ometimes an installed librar' cannot be found

)dit generated CMakeCache(t;t manuall' to inform cmake 3here the


librar' reall' is(

CMakeCache(t;t e;cerpt-
((Mhe 6oost 93DHLRLMH8 li%rar@
6oost#93DHLRLMH8#D360E0R;93DHQEMHP(usr(li%(li%%oost#files@stemSmtSF#B.so
((Qath to a li%rar@.
6oost#93DHLRLMH8#D360E0R#2H6J.;93DHQEMHP6oost#93DHLRLMH8#D360E0R#2H6J.SKOM9OJK2
((Qath to a li%rar@.
6oost#93DHLRLMH8#D360E0R#0HDHELH;93DHQEMHP(usr(li%(li%%oost#files@stemSmtSF#B.so
((Qath to a file.
6oost#3K7DJ2H#230;QEMHP(usr(include(%oostSF#B

8elete CMakeCache(t;t to make CMake4s librar' search start from


scratch

Bseful 3hen installed libraries or tools have changed



rou%leshooting

Linker errors difficult to pinpoint 3ith filtered linker output

/eaders not included as the' should

#ometimes it4s useful to see ho3 the linker!compiler is being called

#olution- ma*e TH06OLHPF


rodolfo&sa%%ath '(tst5 ) ma*e TH06OLHPF
skip
+F,- 6uildin/ 7 o%"ect 78a*e9iles(hello.dir(main.c.o
(usr(%in(/cc So 78a*e9iles(hello.dir(main.c.o Sc (home(rodolfo(main.c
Din*in/ 7 e$ecuta%le hello
(usr(%in(cma*e SH cma*e#lin*#script 78a*e9iles(hello.dir(lin*.t$t SS:er%osePF
(usr(%in(/cc 78a*e9iles(hello.dir(main.c.o So hello Srd@namic Sl$ml5
ma*e+5-; Dea:in/ director@ Z(home(rodolfo<
(usr(%in(cma*e SH cma*e#pro/ress#report (home(rodolfo(78a*e9iles F
+F,- 6uilt tar/et hello
ma*e+F-; Dea:in/ director@ Z(home(rodolfo<
(usr(%in(cma*e SH cma*e#pro/ress#start (home(rodolfo(78a*e9iles

Conclusion

Build s'stems are underated in general 1but shouldn4t.

6hen not thought out 3ell$ development time shifts to3ards build s'stem
t3eaking instead of source file coding(

?rojects tend to gro3 bigger over time

#calable build s'stem desired

Multi-platform development alread' a realit'

#tubborn coders hate 3orking on different development environments


CMake takes care of 5our build s5stem 6(it! a little !el from 5ou78
5ou take care of 5our code.

*eferences

CMake homepage- http-!!333(cmake(org

K( Martin and B( /offman @ Mastering CMake: A Cross-Platform Build System$


Kit3are 5nc($ :HH<

K( Martin and B( /offman @ An Open Source Approach to Developing Softare in


a Small Organi!ation$ in 5))) #oft3are$ "ol( := 2umber 9 5)))$ Kanuar' :HHL

cmake manpage 1ver' compreensive.

CMake 3ikipage- http-!!333(cmake(org!6iki!CMake

Potrebbero piacerti anche