CMake version recommendations and install

CMake ≥ 3.19 is strongly recommended for general users for more robust and easy syntax. For project developers, we recommend CMake >= 3.22 as the new features make debugging CMake and setting up CI considerably easier.

Downloading the latest release of CMake is usually easy. For Linux and Mac, admin/sudo is NOT required.

There is an unofficial PyPI CMake package:

python -m pip install cmake

For platforms where CMake binaries aren’t easily available, use build_cmake.cmake.

Key features added

The priority of these features is subjective–we write from the scientific computing perspective.

CMake 3.22 adds several CMake Environment Variables that are generally useful. CMAKE_BUILD_TYPE default for single configuration build systems. CMAKE_CONFIGURATION_TYPES defaults available configurations for multi-config build systems like Ninja Multi-Config. CMAKE_INSTALL_MODE makes symlinks with copy fallback a good choice for installing programs from CMake. For CTest, the new ENVIRONMENT_MODIFICATION test property makes modifying environment variables for test(s) much easier.

CMake 3.21 adds more preset features, including making “generator” optional–the default CMake behavior will be used to determine generator. The cmake --install-prefix option can be used instead of the cumbersome cmake -DCMAKE_INSTALL_PREFIX=. PROJECT_IS_TOP_LEVEL and <PROJECT-NAME>_IS_TOP_LEVEL identify if a project is at the top of the project hierarchy. ctest --output-junit gives test output in standard tooling format.

CMake 3.20 adds support for Intel NextGen LLVM compiler and NVIDIA HPC compiler. ExternalProject_Add() learned CONFIGURE_HANDLED_BY_BUILD which avoids CMake commanding a reconfigure on each build. try_compiler(WORKING_DIRECTORY) was added. CMake presets in CMakePresets.json now covers configure, build and test, allowing many parameters to be declared with inheritance in JSON. CMake presets are a key feature for CI, as well as user configurations. ctest --test-dir build option avoids the need to manually cd build. cmake_path allows path manipulation and introspection without actually touching the filesystem.

CMake 3.19 added support for ISPC language. string(JSON GET|SET) parsing is very useful to avoid hard-coding parameters. FindPython/find_package accepts version ranges. Intel oneAPI works with CMake >= 3.19.6. Emits deprecation warning for cmake_minimum_required VERSION less than 2.8.12. CMakePresets.json enables configure parameter declarations in JSON.

CMake 3.18 adds CMake Profiler

cmake -B build --profiling-output=perf.json --profiling-format=google-trace

Adds REQUIRED parameter to find_program. Adds file(ARCHIVE_CREATE) and file(ARCHIVE_EXTRACT)

CMake 3.17 adds Ninja Multi-Config generator. cmake –debug-find shows what find_*() is doing. Eliminates Windows “sh.exe is on PATH” error. Recognizes that **Ninja 1.10 correctly works with Fortran**.

CMake 3.16 adds precompiled headers, unity builds, many advanced project features.

CMake 3.15 adds CMAKE_GENERATOR environment variable that works like global -G option. Enhances Python interpreter finding. Adds cmake --install command instead of “cmake –build build –target install”. Added Zstd compression.

CMake 3.14 is where we added check_fortran_source_runs(). FetchContent was enhanced with simpler syntax. The transitive link resolution was considerably enhanced in CMake 3.14. Projects just work in CMake >= 3.14 that fail at link-time with CMake < 3.14.


We don’t recommend use of the older CMake versions below as they take significantly more effort to support.

CMake 3.13 adds ctest --progress and better Matlab compiler support. Lots of new linking options are added, fixes to Fortran submodule bugs. The very convenient cmake -B build incantation, target_sources() with absolute path are also added. It’s significantly more difficult to use CMake older than 3.13 with medium to large projects.

CMake 3.12 adds transitive library specification (out of same directory) and full Fortran Submodule support. get_property(_test_names DIRECTORY . TESTS) retrieves test names in current directory.

CMake 3.11 allows specify targets initially w/o sources. FetchContent is added, allowing fast hierarchies of CMake and non-CMake projects.


The versions of CMake below have been deprecated as of CMake 3.19.

CMake 3.10 added Fortran Flang (LLVM) compiler and extensive MPI features.

CMake 3.9 added further C# and Cuda support, that was originally added in CMake 3.8.

CMake 3.8 added initial Cuda support

CMake 3.7 added comparing ≤ ≥ and version comparisons. Initial Fortran submodule support was added.

CMake 3.6 gave better OpenBLAS support.

CMake 3.5 enhanced FindBoost target with auto Boost prereqs.

CMake 3.4 added if(TEST) to see if a test name exists.

CMake 3.3 added list operations such as IN_LIST.