Back
Close

Introduction to cmake

raphaelmeyer
3,679 views

Functions

If you stick to certain rules how to structure your project then the CMake files can look very similar. Like duplicated code.

Wouldn't it be nice if we could extract common code to functions?

That's exactly what we are going to do in the last exercise.

The CMake Language

But before we start, let's have a look at a few properties of the CMake language.

All CMake variables are stored as strings. But in certain contexts, a string may be treated as a list. Lists are basically strings divided into elements by splitting on ; characters. Variables are set with command set.

Examples:
set(WHO "John")
set(WHAT "Fruit")
set(${WHO}_${WHAT} "apple") # sets John_Fruit to "apple"
message(STATUS "${Who} wants an ${${WHO}_${WHAT}}") # John wants an apple

set(X a b "c;d" "e f") # X is "a;b;c;d;e f"

One of the most important command for functions is cmake_parse_arguments

A full list of all commands can be found here.

Exercise 7

Implement these functions, so that the CMake files can be written as follows:

  • add_interface()
  • add_component()
  • add_application()
[project]/CMakeLists.txt
# [project]/CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project("TimeMachine" VERSION 1.0.2 LANGUAGES CXX)

include(project_helper.cmake)

add_subdirectory(vendor)
add_subdirectory(settings)

add_subdirectory(time_travel_interface)
add_subdirectory(flux_capacitor)
add_subdirectory(time_display)
add_subdirectory(time_machine)
[project]/time_machine/CMakeLists.txt
# [project]/time_machine/CMakeLists.txt

add_application(time_machine_app PACKAGE time_machine
  SOURCES
    src/main.cc
  COMPONENTS
    time_machine::time_machine
)

add_component(time_machine PACKAGE time_machine
  SOURCES
    src/time_machine.cc
  INCLUDES include
  USING
    time_machine::flux_capacitor
    time_machine::time_display
  TESTS
    tests/time_machine.cc
)
[project]/flux_capacitor/CMakeLists.txt
# [project]/flux_capacitor/CMakeLists.txt

add_component(flux_capacitor PACKAGE time_machine
  SOURCES
    src/capacitor.cc
    src/flux.cc
    src/flux_capacitor.cc
  INCLUDES include
  SHARING
    time_machine::time_travel
  TESTS
    tests/capacitor.cc
    tests/flux_capacitor.cc
    tests/flux.cc
)
[project]/time_display/CMakeLists.txt
# [project]/time_display/CMakeLists.txt

add_component(time_display PACKAGE time_machine
  SOURCES
    src/colors.cc
    src/display.cc
    src/numbers.cc
  INCLUDES include
  USING
    time_machine::time_travel
  TESTS
    tests/colors.cc
    tests/numbers.cc
    tests/time_display.cc
)
[project]/time_travel_interface/CMakeLists.txt
# [project]/time_travel_interface/CMakeLists.txt

add_interface(time_travel PACKAGE time_machine
  INCLUDES include
)
Run CMake
# [project]/project_helper.cmake
# add_interface(<name> PACKAGE <package>
# [INCLUDES include...]
# )
#
function(add_interface NAME)
cmake_parse_arguments(IFACE "" "PACKAGE" "INCLUDES" ${ARGN})
# ...
endfunction(add_interface)
# add_component(<name> PACKAGE <package>
# SOURCES source...
# [INCLUDES include...]
# [USING dependency...]
# [SHARING dependency...]
# [TESTS test...]
# )
#
function(add_component NAME)
# cmake_parse_arguments(COMP ...)
# ...
endfunction(add_component)
# add_application(<name> PACKAGE <package>
# SOURCES source...
# [COMPONENTS component...]
# )
#
function(add_application NAME)
# ...
endfunction(add_application)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Create your playground on Tech.io
This playground was created on Tech.io, our hands-on, knowledge-sharing platform for developers.
Go to tech.io
codingame x discord
Join the CodinGame community on Discord to chat about puzzle contributions, challenges, streams, blog articles - all that good stuff!
JOIN US ON DISCORD
Online Participants