Platform independent builds with Cmake

A wide variety of programming languages are used by engineers and scientists. Tie them all together (C, C++, C#, Cuda, Fortran, etc.) in a platform-independent and simple way using CMake or Meson. These high-level build systems generate low-level build system backend files for Ninja (strongly recommended) or Make.

Basic CMake example

Assume a single-file C++ program that uses the Math library and Boost for flexible command-line input of numerous parameters. Turn on additional compiler warnings to help avoid common coding pitfalls. Consider an example CMakeLists.txt for a C++ and Fortran project, line by line.

Minimum version

cmake_minimum_required(VERSION 3.14)

CMake ≥ 3.14 should be used for contemporary projects, as so many new features were added by this release.

Language(s) selection

project(zakharov CXX)

Naming your project can help auto-install if you decide to someday. CXX is required to enable the hooks for the language(s) you used. The most frequently used include

taglanguage
CC
C#C#
CXXC++
CUDACUDA
FortranFortran

Languages that aren’t built into Cmake such as Pascal can be added via custom Cmake modules.

compiler options

if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
  add_compile_options(-mtune=native -Wall -Wextra -Wpedantic -fexceptions -Warray-bounds)
endif()
-mtune=native
use specialized optimizations for your particular CPU
-Wall -Wextra -Wpedantic -Warray-bounds
turn on warnings for common programming mistakes
-fexceptions
more detailed debug info with no speed penalty–enabled by default on Clang.
find_package(Boost REQUIRED COMPONENTS filesystem program_options)

We use Boost:

filesystem
directory manipulation
program-options
advanced command-line parsing
add_executable(zakh zakh.cpp)
target_link_libraries(zakh PRIVATE Boost::filesystem Boost::program_options)
target_compile_features(modules PRIVATE cxx_std_1)

This project requires C++11 features, so if someone has an extremely old compiler not supporting C++11 they’ll get an error.

zakh
the exe file that will be created on compile, run with ./zakh.
zakh.cpp
the files making up “zakh”

Compiling a simple project with Cmake

It’s convenient to create a separate directory, typically build/ under your main code directory. Let’s say your main code directory is ~/code/zakharov, then do

# configure
cmake -B build/`

# build program
cmake --build build/ --parallel

# run program
./zakh

Let’s say you edit the code–rebuild and run by:

cmake --build build/ --parallel

./zakh

Normally you do not need to reconfigure CMake if just editing source code.

Notes

CMake alternatives include:

  • Meson (faster than CMake and recommended for new / updated projects)
  • SCONS (very slow builds, not recommended)
  • Autotools (very slow builds, difficult to implement, not recommended)