Platform independent builds with Cmake

Related: Easy install Cmake

A wide variety of programming languages are used by engineers and scientists. You can tie them all together (C, C++, C#, Cuda, Fortran, etc.) in a platform-independent and simple way using Cmake. Alternatives to Cmake include SCONS and Autotools.

Basic CMake example

Let’s take a single-file C++ program, like a science/engineering researcher might use. You will probably be linking the Math library at least, and Boost for flexible command-line input of numerous parameters. You might like to turn on additional compiler warnings to help avoid common coding pitfalls. Finally, you want to allow your colleagues on a wide variety of computers and operating systems to compile easily.

To do all of the above easily, Cmake has a simple syntax. Let’s consider the example file https://github.com/scivision/zakharov/blob/master/CMakeLists.txt line by line.

Explanation of simple Cmake file line-by-line

cmake_minimum_required (VERSION 2.8.12)

This line is required; version 2.8.12 is included in Ubuntu 14.04 and other systems of the past few years. Cmake 2.8.12 is new enough for most small projects.

Distro CMake default
Ubuntu 14.04 2.8.12
Ubuntu 16.04 3.5.1

CMake language(s) selection

project(zakharov CXX)

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

tag language
C C
C# C#
CXX C++
CUDA CUDA
Fortran Fortran

CMake compiler options

add_compile_options(-mtune=native -Wall -Wextra -Wpedantic -fexceptions -Warray-bounds)

Look to your compiler documentation for detailed description of these commands.

-mtune=native says to use specialized optimizations for your particular CPU

-Wall -Wextra -Wpedantic -Warray-bounds turn on warnings for common programming mistakes

-fexceptions gives more detailed debug info with no speed penalty–enabled by default on Clang.

add_executable(zakh zakh.cpp)

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

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

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

find_package(Boost REQUIRED COMPONENTS system filesystem program_options)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(zakh ${Boost_LIBRARIES})

The last two Boost lines are boiler-plate. The first line reflects that I use

module description
boost-filesystem directory manipulation
boost-program-options advanced command-line parsing
boost-system typically included when using Boost.

Compiling a simple project with Cmake

It’s convenient to create a separate directory, typically bin/ under your main code directory. You can certainly use options to use a single directory for everything, but it can be cleaner to use the defaults. Let’s say your main code directory is ~/code/zakharov, then do

mkdir bin
cd bin
cmake ..
make
./zakh

Let’s say you edit the code. All you do from the bin/ directory is

make
./zakh

for almost any subsequent changes

Leave a Comment