Note: we have been moving our projects to Meson, which is generally fast and robust.
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. These programs generate Makefiles for the program. Some choose to use a manually-created Makefile alone, but I prefer the platform-independent nature of Makefile generators such as Cmake.
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 an example CMakeLists.txt for a C++ and Fortran project, line by line.
Cmake 3.3 is new enough for many small projects, with features such as
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
Languages that aren’t built into Cmake such as Pascal can be added via custom Cmake modules.
if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU) add_compile_options(-mtune=native -Wall -Wextra -Wpedantic -fexceptions -Warray-bounds) endif()
- use specialized optimizations for your particular CPU
-Wall -Wextra -Wpedantic -Warray-bounds
- turn on warnings for common programming mistakes
- more detailed debug info with no speed penalty–enabled by default on Clang.
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 filesystem program_options)
The last two Boost lines are boiler-plate. The first line reflects that I use
- directory manipulation
- advanced command-line parsing
add_executable(zakh zakh.cpp) target_link_libraries(zakh PRIVATE Boost::filesystem Boost::program_options)
- the exe file that will be created on compile, run with
- the files making up “zakh”
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
for almost any subsequent changes