Brain Dump

CMake

Tags
language

Is a cross-platform build tool for the C language with it's own domain-specific configuration language.

CMake is configured using a CMakeLists.txt file (also referred to as CML files). This file is written in the CMake build language. You can hierarchically construct build configurations be placing CML files in different directories depending on how you layer out your project.

# Declare CMake version to use and project name
cmake_minimum_required(VERSION 3.12)
project(program LANGUAGES C CXX) # Languages is optional

# Include CMakeLists.txt from src and libprogram directory
add_subdirectory(src)
add_subdirectory(libprogram)

###############################################################################
#                              src/CMakeLists.txt                             #
###############################################################################

# Declare an executable depending on main.cpp
add_executable(program.out main.cpp)
# Include a dependency for program on libprogram
target_link_libraries(program.out PRIVATE libprogram)

###############################################################################
#                          libprogram/CMakeLists.txt                          #
###############################################################################

# Declare a static library depending on {foo,bar,baz}.cpp
add_library(libprogram STATIC foo.cpp bar.cpp baz.cpp)
Code Snippet 1: Example CMakeLists.txt file.

CMake reads CMakeLists.txt files and then generates build configurations in another language (often GNU make or Ninja) which you then run to actually perform the build. Note: By convention you should generate CMake build files in a separate directory to the root of your source directory. CMake will perform all compilations and linking within the build directory and you can cleanup by simply deleting it. Having a single build directory also simplifies repository management (just gitignore ./build).

Relevent Options

-64

Run for 64 bit machine architecture.

-DCMAKE_BUILD_TYPE=RelWithDebInfo

Produce a release build with debug information.

-GNinja

Using ninja to build/compile instead of Make.

-DCMAKE_EXPORT_COMPILE_COMMANDS=ON

Enable generation of a compile_commands.json JSON database.

You can also enable this by setting the variable in your CML files.

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

Testing with CMake

To enable testing with CMake you must first declare a test target.

enable_testing()

After this you just compile your test cases into an executable and then run it.

# https://cmake.org/cmake/help/latest/command/add_test.html
# To run the test invoke the executable as follows:
#  GTEST_OUTPUT=xml:xunit/ mylib
add_test(
    NAME mylib.u.t
    COMMAND mylib.u.t
)

find_package(CompilerHelpers REQUIRED)

configure_compile_options(
    COMPILER_ID GNU
    LANGUAGES CXX
    OPTIONS -pedantic
)

ctest

Is the test driver program for CMake. It's the preferred way to run tests. Simply run ctest from within your CMake build directory.

GTest

For convenience gtest provides its own helper to automatically discover test cases.

include(GoogleTest)

# Discovers tests in executable at build time.
gtest_discover_tests("my_target")