cmake - introduction and best practices
TRANSCRIPT
![Page 2: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/2.jpg)
interest over time
2005 2007 2009 2011 2013 2015
autoconfautomakebjamcmakescons
0https://www.google.com/trends/explore#q=autoconf,automake,bjam,cmake,scons1
![Page 3: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/3.jpg)
what is cmake?
![Page 4: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/4.jpg)
according to its website
Welcome to CMake, the cross-platform, open-source build system.
CMake is a family of tools designed to build, test and packagesoftware. CMake is used to control the software compilation processusing simple platform and compiler independent configuration files.
CMake generates native makefiles and workspaces that can be usedin the compiler environment of your choice.1
1http://www.cmake.org/3
![Page 5: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/5.jpg)
cmake’s position among build systems
standalone Make, NMake, SCons, Jom, BJam, Ninjaintegrated Visual Studio, Xcode, Eclipsegenerators Autotools, CMake, GYP
4
![Page 6: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/6.jpg)
cmake is simple
> ls zlib-1.2.8amiga/ as400/ contrib/ doc/examples/ msdos/ nintendods/ old/qnx/ test/ watcom/ win32/adler32.c ChangeLog CMakeLists.txt compress.cconfigure crc32.c crc32.h deflate.cdeflate.h FAQ gzclose.c gzguts.hgzlib.c gzread.c gzwrite.c INDEXinfback.c inffast.c inffast.h inffixed.hinflate.c inflate.h inftrees.c inftrees.hmake_vms.com Makefile Makefile.in READMEtreebuild.xml trees.c trees.h uncompr.czconf.h zconf.h.in zlib.3 zlib.3.pdfzlib.h zlib.map zlib.pc.in zlib2ansizutil.c zutil.h
5
![Page 7: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/7.jpg)
reduce your maintenance ...
You write a single configuration that CMake understands.CMake takes care that it works on all compilers and platforms.
6
![Page 8: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/8.jpg)
... unless you break it!
Don’t make any assumption about the platform or compiler!
7
![Page 9: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/9.jpg)
cmake is fast!
I was quite surprised with the speed of building Quantum GIScodebase in comparison to Autotools.2
Task CMake Autotools
Configure 0:08 0:61Make 12:15 21:16Install 0:20 0:36
Total 12:43 22:43
2http://blog.qgis.org/node/16.html8
![Page 10: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/10.jpg)
the cmake cache
∙ Compiler and platform test results are cached inCMakeCache.txt.
∙ You can modify this file and re-run CMake.∙ CMake also provides graphical cache editors.
9
![Page 11: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/11.jpg)
cmake’s graphical cache editor
10
![Page 12: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/12.jpg)
cmake’s position on the time axis
past CMake generates build systems.today CMake is integrated into IDEs.future IDEs run CMake as a background process.3
3http://public.kitware.com/pipermail/cmake-developers/2015-April/025012.html11
![Page 13: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/13.jpg)
modes of operation
![Page 14: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/14.jpg)
cmake as a build system generator
1 > cmake [<options>] <path>
∙ If the specified path contains a CMakeCache.txt, it is treated as abuild directory where the build system is reconfigured andregenerated.
∙ Otherwise the specified path is treated as the source directoryand the current working directory is treated as build directory.
1 > mkdir build2 > cd build3 > time cmake ..4 > time cmake .5 > time make
13
![Page 15: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/15.jpg)
cmake as a build system generator
Issues:
∙ The commands mkdir and time are not portable.∙ With cmake . you may accidentally perform an in-sourceconfigure.
∙ Who said that make is the right build command?
1 > mkdir build2 > cd build3 > time cmake ..4 > time cmake .5 > time make mylibrary
14
![Page 16: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/16.jpg)
cmake’s command-line tool mode
1 > cmake -E <command> [<options>...]
Run cmake -E help for a summary of commands.
1 > cmake -E make_directory build2 > cmake -E chdir cmake -E time cmake ..3 > cmake -E time cmake build
15
![Page 17: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/17.jpg)
use cmake to run the build system
1 > cmake --build build \2 --target mylibrary \3 --config Release \4 --clean-first
Just don’t:
1 > ‘grep ’CMAKE_MAKE_PROGRAM:’ CMakeCache.txt \2 | awk -F= ’{print $2}’‘ mylibrary
16
![Page 18: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/18.jpg)
cmake as a scripting language
1 > cat hello_world.cmake2 foreach(greet Hello Goodbye)3 message(”${greet}, World!”)4 endforeach()5
6 > cmake -P hello\_world.cmake7 Hello, World!8 Goodbye, World!
No configure or generate step is performed and the cache is notmodified.
17
![Page 19: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/19.jpg)
Resist the bash/perl/python temptation!
18
![Page 20: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/20.jpg)
commands for projects
![Page 21: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/21.jpg)
cmake_minimum_required()
Sets the mimimum required version of CMake.
1 cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
∙ Prefer the latest version of CMake.∙ Please don’t set 2.8 as the minimum.∙ If you use 2.6 or 2.4, God kills a kitten.
20
![Page 22: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/22.jpg)
project()
Set the name and version; enable languages.
1 project(<name> VERSION <version> LANGUAGES CXX)
∙ CMake sets several variables based on project().∙ Call to project() must be direct, not through afunction/macro/include.
∙ CMake will add a call to project() if not found on the top level.
21
![Page 23: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/23.jpg)
add_subdirectory()
Embed projects as sub-projects.
1 add_subdirectory(<sourcedir> [<binarydir>])
∙ CMake creates a Makefile/Solution for each subproject.∙ The subproject does not have to reside in a subfolder.
22
![Page 24: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/24.jpg)
hint!
Make sure that all your projects can be built both standalone and asa subproject of another project:
∙ Don’t assume that your project root is the build root.∙ Don’t modify global compile/link flags.∙ Don’t make any global changes!
23
![Page 25: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/25.jpg)
find_package()
Finds preinstalled dependencies
1 find_package(Qt5 REQUIRED COMPONENTS Widgets)
∙ Can set some variables and define imported targets.∙ Supports components.
24
![Page 26: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/26.jpg)
add_executable()
Add an executable target.
1 add_executable(tool2 main.cpp3 another_file.cpp4 )5 add_executable(my::tool ALIAS tool)
25
![Page 27: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/27.jpg)
add_library()
Add a library target.
1 add_library(foo STATIC2 foo1.cpp3 foo2.cpp4 )5 add_library(my::foo ALIAS foo)
∙ Libraries can be STATIC, SHARED, MODULE, or INTERFACE.∙ Default can be controlled with BUILD_SHARED_LIBS.
26
![Page 28: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/28.jpg)
things to remember
∙ Always add namespaced aliases for libraries.∙ Dont’t make libraries STATIC/SHARED unless they cannot be builtotherwise.
∙ Leave the control of BUILD_SHARED_LIBS to your clients!
27
![Page 29: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/29.jpg)
usage requirements
![Page 30: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/30.jpg)
usage requirements signature
1 target_<usage requirement>(<target>2 <PRIVATE|PUBLIC|INTERFACE> <lib> ...3 [<PRIVATE|PUBLIC|INTERFACE> <lib> ... ] ...]4 )
PRIVATE Only used for this target.PUBLIC Used for this target and all targets that link against it.
INTERFACE Only used for targets that link against this library.
29
![Page 31: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/31.jpg)
target_link_libraries()
Set libraries as dependency.
1 target_link_libraries(foobar2 PUBLIC my::foo3 PRIVATE my::bar4 )
30
![Page 32: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/32.jpg)
things to remember
∙ Prefer to link against namespaced targets.∙ Specify the dependencies are private or public.∙ Avoid the link_libraries() command.∙ Avoid the link_directories() command.∙ No need to call add_dependencies().
31
![Page 33: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/33.jpg)
target_include_directories()
Set include directories.
1 target_include_directories(foo2 PUBLIC include3 PRIVATE src4 )
32
![Page 34: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/34.jpg)
things to remember
∙ Avoid the include_directories() command.
33
![Page 35: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/35.jpg)
target_compile_definitions()
Set compile definitions (preprocessor constants).
1 target_compile_definitions(foo2 PRIVATE SRC_DIR=${Foo_SOURCE_DIR}3 )
34
![Page 36: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/36.jpg)
things to remember
∙ Avoid the add_definitions() command.∙ Avoid adding definitions to CMAKE_<LANG>_FLAGS.
35
![Page 37: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/37.jpg)
target_compile_options()
Set compile options/flags.
1 if(CMAKE_COMPILER_IS_GNUCXX)2 target_compile_options(foo3 PUBLIC -fno-elide-constructors4 )5 endif()
36
![Page 38: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/38.jpg)
things to remember
∙ Wrap compiler specific options in an appropriate condition.∙ Avoid the add_compile_options() command.∙ Avoid adding options to CMAKE_<LANG>_FLAGS.
37
![Page 39: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/39.jpg)
target_compile_features()
Set required compiler features.
1 target_compile_features(foo2 PUBLIC3 cxx_auto_type4 cxx_range_for5 PRIVATE6 cxx_variadic_templates7 )
∙ CMake will add required compile flags.∙ Errors if the compiler is not supported.
38
![Page 40: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/40.jpg)
things to remember
∙ Don’t add -std=c++11 to CMAKE_<LANG>_FLAGS.∙ Don’t pass -std=c++11 to target_compile_options().
39
![Page 41: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/41.jpg)
best practices
![Page 42: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/42.jpg)
goal: no custom variables
![Page 43: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/43.jpg)
variables are fragile
Hard to diagnose:
bar links against foo! But only on Windows!
1 set(PROJECT foobar)2 set(LIBRARIES foo)3
4 if(WIN32)5 list(APPEND LIBRARIES bar)6 endif()7
8 target_link_libraries(${Project}9 ${LIBRARIES}
10 )
42
![Page 44: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/44.jpg)
variables are fragile
Hard to diagnose:
bar links against foo! But only on Windows!
1 set(PROJECT foobar)2 set(LIBRARIES foo)3
4 if(WIN32)5 list(APPEND LIBRARIES bar)6 endif()7
8 target_link_libraries(${Project}9 ${LIBRARIES}
10 )
42
![Page 45: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/45.jpg)
variables are fragile
This is better:
Without variables the code is more robust and easier to read.
1 target_link_libraries(foobar PRIVATE my::foo)2
3 if(WIN32)4 target_link_libraries(foobar PRIVATE my::bar)5 endif()
43
![Page 46: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/46.jpg)
don’t use file(glob)!
Not recommended:
1 file(GLOB sources ”*.cpp”)2 add_library(mylib ${sources})
∙ file(GLOB) is useful in scripting mode.∙ Don’t use it in configure mode!
44
![Page 47: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/47.jpg)
list all sources explicitly
1 add_library(mylib2 main.cpp3 file1.cpp4 file2.cpp5 )
45
![Page 48: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/48.jpg)
Explicit is better than implicit
46
![Page 49: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/49.jpg)
goal: no custom functions
![Page 50: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/50.jpg)
picking on myself
∙ I wrote many custom functions.∙ Experience tought me: Most of the time it is a bad idea.
48
![Page 51: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/51.jpg)
just don’t
1 magic_project(<name> ...)
49
![Page 52: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/52.jpg)
why no custom functions?
∙ Remember what I said about the project() command?∙ The signature of project() was extended recently.
50
![Page 53: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/53.jpg)
just don’t
1 magic_add_library(<name>2 SOURCES3 <list of sources>4 LIBRARIES5 <list of libraries>6 )
51
![Page 54: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/54.jpg)
why no custom functions?
∙ How to add platform specific libraries?∙ Harder to get started for contributors.∙ Maintenance!
52
![Page 55: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/55.jpg)
so you wrote a custom function ...
∙ Contribute it to CMake!∙ If it is accepted, it is no longer a custom function.∙ Otherwise, the reason for rejection should give you a hint.∙ The maintainers are very helpful and experienced.
53
![Page 56: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/56.jpg)
summary
![Page 57: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/57.jpg)
summary
∙ CMake is widely used, fast, cross-platform.∙ Build system generator plus platform abstraction.∙ Manage build targets with usage requirements.∙ Goal: No custom variables.∙ Goal: No custom functions.
55
![Page 58: CMake - Introduction and best practices](https://reader034.vdocument.in/reader034/viewer/2022042504/55b6e373bb61eb75268b48ec/html5/thumbnails/58.jpg)
Thank you!
56