CMake Tutorial How to setup your C/C++ projects? Luis Díaz Más November, 2012

Introduction
CMake Language
Specific cases
CMake Tutorial
How to setup your C/C++ projects?
Luis Díaz Más
http://plagatux.es
November, 2012
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Outline
1
Introduction
What’s CMake?
Typical procedure
2
CMake Language
Concepts
Scripting
CPack
3
Specific cases
Qt libraries
Cross-compiling
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
What’s CMake?
System for configuring C/C++ projects. Independent of:
Platform
IDE/Editor
Compiler
Generates native makefiles and workspaces
Some of its major features
Open source
Simplicity of scripting language
Modules for finding/configuring software
Create custom targets/commands
“Out-of-Source” builds
Cross compiling
Integrated testing & packaging (CTest & CPack)
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Many IDEs, editors and SOs
IDE
Windows
Vis. Studio
Code::Blocks
Mac OS X
XCode
Linux
KDevelop
Anjuta
Multi-platform
Eclipse
QtCreator
Editors + Tools + Makefiles
Multi-platform
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Many IDEs, editors and SOs
IDE
Windows
Vis. Studio
Code::Blocks
Mac OS X
XCode
Linux
KDevelop
Anjuta
Multi-platform
Eclipse
QtCreator
Editors + Tools + Makefiles
Multi-platform
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Many IDEs, editors and SOs
IDE
Windows
Vis. Studio
Code::Blocks
Mac OS X
XCode
Linux
KDevelop
Anjuta
Multi-platform
Eclipse
QtCreator
Editors + Tools + Makefiles
Multi-platform
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Many IDEs, editors and SOs
IDE
Windows
Vis. Studio
Code::Blocks
Mac OS X
XCode
Linux
KDevelop
Anjuta
Multi-platform
Eclipse
QtCreator
Editors + Tools + Makefiles
Multi-platform
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Many IDEs, editors and SOs
IDE
Windows
Vis. Studio
Code::Blocks
Mac OS X
XCode
Linux
KDevelop
Anjuta
Multi-platform
Eclipse
QtCreator
Editors + Tools + Makefiles
Multi-platform
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Many IDEs, editors and SOs
IDE
Windows
Vis. Studio
Code::Blocks
Mac OS X
XCode
Linux
KDevelop
Anjuta
Multi-platform
Eclipse
QtCreator
Editors + Tools + Makefiles
Multi-platform
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Many IDEs, editors and SOs
IDE
Windows
Vis. Studio
Code::Blocks
Mac OS X
XCode
Linux
KDevelop
Anjuta
Multi-platform
Eclipse
QtCreator
Editors + Tools + Makefiles
Multi-platform
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Many IDEs, editors and SOs
IDE
Windows
Vis. Studio
Code::Blocks
Mac OS X
XCode
Linux
KDevelop
Anjuta
Multi-platform
Eclipse
QtCreator
Editors + Tools + Makefiles
Multi-platform
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Many IDEs, editors and SOs
IDE
Windows
Vis. Studio
Code::Blocks
Mac OS X
XCode
Linux
KDevelop
Anjuta
Multi-platform
Eclipse
QtCreator
Editors + Tools + Makefiles
Multi-platform
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Compilers
Compilers & Linkers
GNU Compilers (gcc, g++, asm, fortran, etc)
Visual Studio compilers
MinGW (Windows Port of GNU Compilers)
Intel compilers
Target-specific compilers (embedded hardware)
Cross-compiling
Eclipse + plugins ? Is it really necessary?
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Who are using CMake?
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Who are using CMake?
Many important libraries
& tools use CMake
VTK
KDE
Blender
Compiz
MySQL
Inkscape
Qt4 & Qt5
OpenCV
Point Clouds Library
Boost
ZLib
...
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Why to use CMake?
Do not depend on specific platform, IDE or compiler.
Many independent builds for each project.
Easy to tune specific-platform stuff.
Easy integration with other applications like Doxygen.
Console and Graphical applications.
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Typical project setup
CMakeLists.txt in root directory.
CMakeLists.txt files in code directories.
src → C/C++ libraries.
tests → unitary tests.
utils → apps using (or not) the libraries.
Procedure
1
2
3
4
5
Go to project path.
Create build path (debug|release) & go inside.
Run CMake indicating build & source paths.
Make or compile with appropriate workspace.
Install targets.
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
What’s CMake?
Typical procedure
Simple example
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Outline
1
Introduction
What’s CMake?
Typical procedure
2
CMake Language
Concepts
Scripting
CPack
3
Specific cases
Qt libraries
Cross-compiling
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Code organization
Each project in a independent directory.
Each subdirectory can contain a subproject.
Inheritance of configuration in subdirectories.
Order of processing: Root, dir1, dir3, dir4, dir2
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Source tree & Binary tree
The source tree contains:
Program sources & headers.
Data files.
CMake input files.
The binary tree contains:
Native build system files (dsw, dsp, makefiles, workspaces).
Libraries.
Executables.
Build outputs.
Any other build generated files.
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Predefined targets
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Basic variables
CMAKE_BUILD_TYPE (Debug | Release)
Determines type of compilation
CMAKE_VERBOSE_MAKEFILE (ON | OFF)
If it is enabled the compilation show all the information
CMAKE_MODULE_PATH
Path to where CMake modules are located
CMAKE_INSTALL_PREFIX
Where to install targets (be careful with privileges)
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Basic commands
Comments with #
Project
PROJECT( myProject )
Set and read variables
SET( VARIABLE ’Ou yeah ’ )
MESSAGE(STATUS ’ VARIABLE : $ { VARIABLE } ’ )
Conditional blocks
I F ( WIN32 )
MESSAGE(STATUS ’ ’ Doing s p e c i f i c windows s t u f f s ’ ’ )
ELIF ( LINUX )
MESSAGE(STATUS ’ ’ Doing s p e c i f i c l i n u x s t u f f s ’ ’ )
ELIF (APPLE)
MESSAGE(STATUS ’ ’ Doing s p e c i f i c apple s t u f f s ’ ’ )
ELSE ( )
MESSAGE(FATAL_ERROR ’ ’ Unrecognized o p e r a t i v e system ’ ’ )
ENDIF ( )
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Basic commands
Messages
MESSAGE( ’ I m p o r t a n t message ’ )
MESSAGE(STATUS ’ I n c i d e n t a l i n f o r m a t i o n ’ )
MESSAGE(WARNING ’CMake warning , c o n t i n u e processing ’ )
MESSAGE(SEND_ERROR ’CMake e r r o r , c o n t i n u e b u t s k i p i n g g e n e r a t i o n ’ )
MESSAGE(FATAL_ERROR ’CMake e r r o r , s t o p a l l processing ’ )
Subdirectories
ADD_SUBDIRECTORY( s r c )
ADD_SUBDIRECTORY( t e s t s )
ADD_SUBDIRECTORY( u t i l s )
Modify variables
In terminal mode : cmake -D VAR=XXX . . .
In GUI mode
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Libraries and applications commands
Compile & link commands
ADD_DEFINITIONS(−D _NDEBUG)
INCLUDE_DIRECTORIES ( $ {PROJECT_SOURCE_DIR } / s r c )
LINK_DIRECTORIES ( $ { PATH_TO_SOME_LIBRARIES } )
LINK_LIBRARIES ( $ { OpenCV_LIBS }
TARGET_LINK_LIBRARIES ( myTarget $ { MyLIB } )
Target commands
#The f o l l o w i n g commands depends on CMAKE_CXX_FLAGS, CMAKE_CXX_DEBUG_FLAGS,
#CMAKE_CXX_RELEASE_FLAGS, e t c .
ADD_LIBRARY ( myLib $ {SOURCES} )
# The l i b r a r y w i l l be shared o r s t a t i c depending on BUILD_SHARED_LIBS v a r i a b l e
ADD_EXECUTABLE( myApp $ {SOURCES} )
Verbose compiling
make VERBOSE=1
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Libraries and applications commands
Install commands
# I n s t a l l headers f i l e s o f t h e l i b r a r y
INSTALL ( FILES $ {HEADERS}
DESTINATION i n c l u d e / $ {PROJECT_NAME } /
COMPONENT main )
# I n s t a l l l i b r a r y f i l e s of the l i b r a r y
INSTALL (TARGETS $ {PROJECT_NAME}
RUNTIME DESTINATION b i n COMPONENT main
LIBRARY DESTINATION l i b PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
COMPONENT main
ARCHIVE DESTINATION l i b / s t a t i c COMPONENT main )
# Dynamic l i b r a r y : DLLs
# Dynamic l i b r a r y : so
# Static library
# I n s t a l l application
INSTALL (TARGETS myApp RUNTIME DESTINATION b i n COMPONENT main )
#These commands generates i n s t a l l a t i o n r u l e s f o r a p r o j e c t .
#DESTINATION i s r e l a t i v e t o CMAKE_INSTALL_PREFIX u n l e s s you s p e c i f y a a b s o l u t e path
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Advanced commands
Find libraries
# I n / u s r / share / cmake−2.8/ Modules o r C : \ ProgramFiles \ cmake \ Modules \ are t h e Find f i l e s
FIND_PACKAGE( Qt4 4 . 4 . 3
REQUIRED QUIET COMPONENTS QtCore QtGui )
FIND_PACKAGE(OpenCV
REQUIRED)
FIND_PACKAGE( ZLIB
REQUIRED)
FIND_PACKAGE( GTest )
...
# To s p e c i f y o t h e r p l a c e s where t o f i n d Find f i l e s
SET(CMAKE_MODULE_PATH $ {CMAKE_MODULE_PATH} $ { CMAKE_INSTALL_PREFIX } / l i b / cmake / )
...
LINK_LIBRARIES ( $ { OpenCV_LIBS } $ {QT_QTCORE_LIBRARY } )
TARGET_LINK_LIBRARIES ( myApp $ { QT_LIBRARIES } ) # V a r i a b l e s d e f i n e s i n Find f i l e s
...
FIND_PACKAGE( PkgConfig
REQUIRED)
I F (PKG_CONFIG_FOUND)
PKG_CHECK_MODULES(AVCODEC
REQUIRED l i b a v c o d e c > = 5 3 . 3 5 . 0 )
ELSE ( )
MESSAGE(FATAL_ERROR " pkg−c o n f i g command n o t found " )
ENDIF ( )
...
FIND_LIBRARY (ARGTABLE a r g t a b l e 2 PATHS $ {ARGTABLE_ROOT } / l i b )
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Advanced commands
Tunning compiling options
SET(EXTRA_C_FLAGS " " )
SET(EXTRA_C_FLAGS_RELEASE " " )
SET(EXTRA_C_FLAGS_DEBUG " " )
SET( EXTRA_EXE_LINKER_FLAGS " " )
SET(EXTRA_EXE_LINKER_FLAGS_RELEASE " " )
SET(EXTRA_EXE_LINKER_FLAGS_DEBUG " " )
I F ( WARNINGS_ANSI_ISO )
a d d _ e x t r a _ c o m p i l e r _ o p t i o n(−a n s i )
a d d _ e x t r a _ c o m p i l e r _ o p t i o n(−Wcast−a l i g n )
a d d _ e x t r a _ c o m p i l e r _ o p t i o n(− W s t r i c t−a l i a s i n g =2)
ELSE ( )
a d d _ e x t r a _ c o m p i l e r _ o p t i o n(−Wno−n a r r o w i n g )
a d d _ e x t r a _ c o m p i l e r _ o p t i o n(−Wno−d e l e t e−non−v i r t u a l −d t o r )
a d d _ e x t r a _ c o m p i l e r _ o p t i o n(−Wno−unnamed−type−template−args )
ENDIF ( )
I F (WARNINGS_ARE_ERRORS)
a d d _ e x t r a _ c o m p i l e r _ o p t i o n(−Werror )
ENDIF ( )
SET(CMAKE_C_FLAGS " $ {CMAKE_C_FLAGS} $ {EXTRA_C_FLAGS } " )
SET(CMAKE_CXX_FLAGS " $ {CMAKE_CXX_FLAGS} $ {EXTRA_C_FLAGS } " )
SET(CMAKE_CXX_FLAGS_RELEASE " $ {CMAKE_CXX_FLAGS_RELEASE} $ {EXTRA_C_FLAGS_RELEASE } " )
SET(CMAKE_C_FLAGS_RELEASE " $ {CMAKE_C_FLAGS_RELEASE} $ {EXTRA_C_FLAGS_RELEASE } " )
SET(CMAKE_CXX_FLAGS_DEBUG " $ {CMAKE_CXX_FLAGS_DEBUG} $ {EXTRA_C_FLAGS_DEBUG } " )
SET(CMAKE_C_FLAGS_DEBUG " $ {CMAKE_C_FLAGS_DEBUG} $ {EXTRA_C_FLAGS_DEBUG } " )
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Packaging the project
A packaging tool distributed with CMake.
It can be used without CMake (file CPackConfig.cmake).
To use it with CMake → INCLUDE(CPack).
Generators:
TGZ
TBZ2
TZ
ZIP
Nullsoft Installer (Windows only)
DragNDrop (OSX only)
DEB/RPM (Linux only)
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
CPack commands
I F (NOT CPACK_GENERATOR)
I F ( UNIX )
SET(CPACK_GENERATOR "DEB" )
ENDIF ( )
ENDIF ( )
SET(CPACK_PACKAGE_CONTACT " piponazo@plagatux . es " )
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "My p e r s o n a l l i b r a r y " )
SET(CPACK_PACKAGE_VENDOR " L u i s Diaz Mas " )
SET(CPACK_PACKAGE_VERSION_MAJOR $ {VERSION_MAJOR } )
SET(CPACK_PACKAGE_VERSION_MINOR $ {VERSION_MINOR } )
SET(CPACK_PACKAGE_VERSION_PATCH $ {VERSION_PATCH } )
SET(CPACK_SOURCE_GENERATOR " TBZ2 " )
SET(CPACK_SOURCE_PACKAGE_FILE_NAME $ {PROJECT_NAME } )
# Avoid m e r c u r i a l f i l e s , b u i l d s and vim t e m p o r a l f i l e s
SET(CPACK_SOURCE_IGNORE_FILES " \ \ \ \ . hg / ; / b u i l d . ∗ / ; \ \ \ \ . swp$ " )
I F (CPACK_GENERATOR STREQUAL "DEB " )
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER " piponazo@plagatux . es " )
SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
ENDIF ( )
INCLUDE ( CPack )
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Concepts
Scripting
CPack
Big project example - OpenCV
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Qt libraries
Cross-compiling
Outline
1
Introduction
What’s CMake?
Typical procedure
2
CMake Language
Concepts
Scripting
CPack
3
Specific cases
Qt libraries
Cross-compiling
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Qt libraries
Cross-compiling
Qt Overview
Figure: Image taken from http://qt-project.org/
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Qt libraries
Cross-compiling
Qt commands
Finding Qt
FIND_PACKAGE( Qt4 4 . 8 . 1
REQUIRED QUIET COMPONENTS QtCore QtGui QtNetwork )
Compiling libraries and applications
INCLUDE ( $ { QT_USE_FILE } )
I F ( BUILD_SHARED_LIBS )
ADD_DEFINITIONS(−DQT_SHARED)
ELSE ( )
ADD_DEFINITIONS(−DQT_STATIC )
ENDIF ( )
I F ( $ {CMAKE_BUILD_TYPE} STREQUAL " Release " )
ADD_DEFINITIONS(−DQT_NO_DEBUG)
ENDIF ( )
Compiling plug-ins
#Not use INCLUDE ( $ { QT_USE_FILE } )
INCLUDE_DIRECTORIES ( $ { QT_INCLUDE_DIR } $ {QT_QTCORE_INCLUDE_DIR} $ { QT_QTGUI_INCLUDE_DIR } )
ADD_DEFINITIONS(−DQT_PLUGIN −DQT_SHARED −DQT_DEBUG −D_REENTRANT)
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Qt libraries
Cross-compiling
Qt commands
Generating MOCS
SET(MOCS
mainwindow . h
connectiondialog . h)
QT4_WRAP_CPP(MOCS_GEN $ {HDRS_MOCS} )
Compiling UIs
SET( UIS
mainwindow . u i
connectiondialog . ui )
QT4_WRAP_UI( UIS_GEN $ { UIS } )
Compiling resources
QT4_ADD_RESOURCES(RSC f i l e . q r c )
Putting all together
ADD_EXECUTABLE( myApp $ {SOURCES} $ {MOCS_GEN} $ { UIS_GEN } $ {RSC} )
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Qt libraries
Cross-compiling
Qt Example
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Qt libraries
Cross-compiling
Cross-compiling
Independent files for each specific board/configuration
Use CMAKE_TOOLCHAIN_FILE variable
Example with Raspberri pi (toolchain-rpi.cmake)
INCLUDE ( CMakeForceCompiler )
SET(CMAKE_SYSTEM_NAME L i n u x ) # t h i s one i s i m p o r t a n t
SET(CMAKE_SYSTEM_VERSION 1 ) # t h i s one n o t so much
SET(RPI_ROOT / home / l u i s / r p i−t o o l c h a i n / arm−bcm2708 / arm−bcm2708hardfp−l i n u x−gnueabi )
SET(CMAKE_C_COMPILER
SET(CMAKE_CXX_COMPILER
s e t (CMAKE_AR
s e t (CMAKE_LINKER
s e t (CMAKE_NM
s e t (CMAKE_OBJCOPY
s e t (CMAKE_OBJDUMP
s e t (CMAKE_STRIP
s e t (CMAKE_RANLIB
$ {RPI_ROOT } /
$ {RPI_ROOT } /
$ {RPI_ROOT } /
$ {RPI_ROOT } /
$ {RPI_ROOT } /
$ {RPI_ROOT } /
$ {RPI_ROOT } /
$ {RPI_ROOT } /
$ {RPI_ROOT } /
SET(CMAKE_FIND_ROOT_PATH
b i n / arm−bcm2708hardfp−l i n u x−gnueabi−gcc )
b i n / arm−bcm2708hardfp−l i n u x−gnueabi−g++)
b i n / arm−bcm2708hardfp−l i n u x−gnueabi−a r )
b i n / arm−bcm2708hardfp−l i n u x−gnueabi−l d )
b i n / arm−bcm2708hardfp−l i n u x−gnueabi−nm)
b i n / arm−bcm2708hardfp−l i n u x−gnueabi−objcopy )
b i n / arm−bcm2708hardfp−l i n u x−gnueabi−objdump )
b i n / arm−bcm2708hardfp−l i n u x−gnueabi−s t r i p )
b i n / arm−bcm2708hardfp−l i n u x−gnueabi−t a n l i b )
$ {RPI_ROOT } / arm−bcm2708hardfp−l i n u x−gnueabi )
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Luis Díaz Más
CMake Tutorial
Introduction
CMake Language
Specific cases
Qt libraries
Cross-compiling
Example - hello world RPi
Luis Díaz Más
CMake Tutorial