Installing Octopus with CMake
Building with CMake
This document goes over a few ways to build Octopus using cmake, how to configure it and how to run basic tests
Requirements
cmake
>= 3.20 (Following latest Ubunutu and RHEL LTS, modern versions can be downloaded viapip install cmake
)pkgconf
- Build system:
ninja
(required for GCC) ormake
(some restrictions apply, see build backend) - Supported compilers, MPI and external libraries are documented in the top-level Octopus README
Except for the compilers and most libraries, these requirements are toolchain independent (can be compiled by GNU, Intel, etc.) and can also be installed in a virtual environment from PyPI.
tl;dr. Running cmake
The configure, build, test and install steps are all run through the cmake
command line interface (CLI). In the project root run:
$ cmake -B ./build -G Ninja --install-prefix=<installation directory>
$ cmake --build ./build
$ ctest --test-dir ./build -L short-run
$ cmake --install ./build
This will configure, build and run the tests in the ./build
directory, using the default options, i.e. compiling
without parallelization, and with optional dependencies automatically detected. (The -G Ninja
option is explained in
build-backend)
If you have any problems, see the troubleshooting section.
Easy method: Using presets
If you are using CMake >= 3.23
you can use cmake-presets
to simplify this process and use some
pre-defined options, e.g.:
$ cmake --preset default
$ cmake --build --preset default
$ ctest --preset default
$ cmake --install ./cmake-build-release
You can find a list of these presets using cmake --list-presets
. Note that some presets are customized for the Octopus
buildbot, which we use for continuous integration.
$ cmake --list-presets
Available configure presets:
"default" - Default configuration preset
...
You can further add the options defined in Manual method to further customize the build process. If you are using
CMake >= 3.25
you can simplify this to a single step (except for install
which has no presets):
$ cmake --workflow --preset default
$ cmake --install ./cmake-build-release
You cannot add manual options to workflow presets
See Testing section on how to fine-tune the testing process.
User Presets
Additionally, one can define a custom preset that contain all of these options in /CMakeUserPresets.json
, e.g. a
debug
preset might look like:
{
"version": 4,
"configurePresets": [
{
"name": "debug",
"displayName": "Debug configure",
"inherits": [
"default"
],
"binaryDir": "build",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
}
]
}
We provide commonly used “components” in /cmake/CMakePresets-components.json
,
such as _min
which makes sure no optional dependencies are used, _mpi
which enables MPI support, etc. Feel free to use them
in the inherits
field of your user preset.
In the `inherits` field, the `cacheVariables` take precedence from the first preset in the list that defined them. The `CMakePresets-components.json` are designed to be mixed in arbitrary order. If that is not the case please report it. The `cacheVariables` defined in the current `configurePresets` always take precedence.
Building Documentation
If Doxygen is available on your system, Octopus source code documentation can be built with the custom doxygen
CMake
target. Configure with the Doxygen support enabled, -DOCTOPUS_DOXYGEN=On
, and build the documentation with:
cmake --build ./build --target doxygen
Manual method: Traditional CMake workflow
Configure Step
To configure the build from Octopus root use:
$ cmake -B ./build
The option -B
specifies the build directory, which is automatically created. If not provided, the current directory is
used as build directory, which is highly discouraged. The user is encouraged to use different build directories for
different configurations.
Options, compilers, and packages are cached between subsequent configure steps (as well as build/test/install steps)
in the build directory. To remove these caches and start “fresh” use the --fresh
flag:
$ cmake -B ./build --fresh
The best place to find the available configuration options is in the Options
section of the root
/CMakeLists.txt
:
#[==============================================================================================[
# Options #
]==============================================================================================]
option(OCTOPUS_MPI "Octopus: Build with MPI support" OFF)
option(OCTOPUS_OpenMP "Octopus: Build with OpenMP support" OFF)
option(OCTOPUS_INSTALL "Octopus: Install project" ${PROJECT_IS_TOP_LEVEL})
option(OCTOPUS_CUDA "Octopus: Build with CUDA support" OFF)
...
More details about these options, as well as some common CMake-native ones are described below. These
options are set at configure time and are typically prefixed by -D
as follows:
$ cmake -B build_dir --fresh -G Ninja -DOCTOPUS_MPI=On -DCMAKE_BUILD_TYPE=release
An example how to specify more details for a custom build is:
cmake -B build --fresh -G Ninja \
-DOCTOPUS_MPI=On -DOCTOPUS_OpenMP=On \
-DOCTOPUS_TESTS=Off \
-DLibxc_ROOT="path_to_libxc" \
-DCMAKE_INSTALL_PREFIX="installation_path \
-DCMAKE_C_FLAGS="-O3 -g" \
-DCMAKE_Fortran_FLAGS="-O3 -fallow-argument-mismatch -fno-var-tracking-assignments -g" \
-DCMAKE_DISABLE_FIND_PACKAGE_CGAL=On \
-DCMAKE_BUILD_TYPE="custom"
Build backend
To specify the build backend use the -G
flag:
$ cmake -B ./build -G Ninja --fresh
The default is make
, but we highly encourage to use ninja
instead. When using GNU compilers,
ninja
is required.
As of writing this guide (cmake 3.28), `gfortran` and `make` are incompatible due to the custom Octopus pre-processing of the Fortran code. Please use `ninja` instead.
Compilers
CMake automatically detects the compilers on the system, however one can explicitly specify which compiler(s) cmake should use, by passing a cmake flag to specify the compiler (with full path):
- Fortran compiler:
-DCMAKE_Fortran_COMPILER=/path/to/gfortran
- C compiler:
-DCMAKE_C_COMPILER=/path/to/gcc
- C++ compiler:
-DCMAKE_CXX_COMPILER=/path/to/g++
External Dependencies
By default, all external dependencies are searched at the first configuration. The system installed packages take precedence. To fine-tune the optional external packages use the following options:
CMake Flag | Default | Description |
---|---|---|
CMAKE_DISABLE_FIND_PACKAGE_<Name> |
Off | Disable optional external package <Name> |
CMAKE_REQUIRE_FIND_PACKAGE_<Name> |
Off | Require optional external package <Name> |
<Name>
is case-sensitive! See External Dependencies for package names used.
Fortran libraries (and modules) are **NOT** compatible between different compilers, unlike C and to a high extent C++ libraries and headers. CMake does not have a functionality to re-build Fortran modules when a different compiler was used in the external package. This functionality might come soon given the recent support for C++ modules. This can be especially problematic when using `homebrew`.
mkl
andfftw
have a custom logic described [below][Other options].- Other external package support that drastically change the behavior of Octopus, e.g. MPI, OpenMP, etc. are
controlled by
OCTOPUS_<NAME>
flags. See [Other options][]
The required packages have fallbacks to external sources (downloaded using FetchContent
) if the system
does not contain the package. This fallback behavior can be controlled as follows:
Setting | Behavior |
---|---|
<default> |
Check for system installed, if not found download it |
CMAKE_REQUIRE_FIND_PACKAGE_<Name>=On |
Use only system installed |
CMAKE_DISABLE_FIND_PACKAGE_<Name>=On |
Do not check for system installed, use downloaded version |
FETCHCONTENT_SOURCE_DIR_<UPPER_NAME> |
Use a local path source |
Other Options
In the following table we present a comprehensive but not exhaustive list of configure time options that can be passed
to Octopus cmake. All should be prepended with -D
and appended with =<OPTION>
. For boolean flags, this corresponds
to On
/True
/1
or Off
/False
/0
. For example, to compile Octopus with MPI support, one would use
-DOCTOPUS_MPI=On
. Everything else is treated as plain string. For example, to specify the Fortran compiler, one would
use -DCMAKE_Fortran_COMPILER=/path/to/gfortran
.
CMake Flag | Default | Description | Notes |
---|---|---|---|
OCTOPUS_MPI |
Off | Compile with MPI Support | |
OCTOPUS_OpenMP |
Off | Compile with OMP Support | |
OCTOPUS_CUDA |
Off | Compile with CUDA Support | |
OCTOPUS_HIP |
Off | Compile with HIP Support | |
OCTOPUS_OpenCL |
Off | Compile with openCL Support | |
OCTOPUS_NATIVE |
Off | Build for native architecture | |
OCTOPUS_UNIT_TESTS |
Off | Build with unit-tests | |
OCTOPUS_TESTS_FULL |
On | Build with full test-suite | |
OCTOPUS_TESTS_REPORT |
Off | Export test report | |
OCTOPUS_TESTS_RUN_SERIAL |
Off | Run internal Octopus tests in Serial | |
OCTOPUS_MKL |
Off | Build with MKL support | MKL is still searched and preferred unless OCTOPUS_FFTW=On |
OCTOPUS_FFTW |
Off | Build with FFTW support | Set this option to prefer FFTW over MKL |
OCTOPUS_ScaLAPACK |
Off | Build with ScaLAPACK support |
Other useful CMake-native settings
CMake Flag | Default | Description | Notes |
---|---|---|---|
CMAKE_BUILD_TYPE |
Release |
Build Type | - See ${buildir}/CMakeCache.txt for built-in defaults - Use Custom to remove all built-in flags |
CMAKE_PREFIX_PATH |
<system default> |
Search path for external dependencies | Usually the parent folder containing bin , lib , etc. folders |
<Name>_ROOT |
<empty> |
Search the specified path for package <Name> |
|
CMAKE_INSTALL_PREFIX |
<system default> |
Path where to install Octopus | |
CMAKE_<Lang>_COMPILER |
<system default> |
<Lang> (Fortran/C/CXX) Compiler |
|
CMAKE_<Lang>_FLAGS |
<empty> |
Global <Lang> (Fortran/C/CXX) Compiler Flags |
- Whenever possible use OCTOPUS_ defined variables - CMAKE_<Lang>_FLAGS_<BuildType> are automatically appended - These flags are propagated to third-party libraries compiled by Octopus |
Additional options are found in <#external-dependencies>.
If you are using downloaded external dependencies, you can configure those packages by simply adding those options e.g.:
SPGLIB_DEBUG=On
Note these options are passed unaltered to the dependencies so be aware of name-clashes. See the
relevant upstream packages for available configure options.
You can view the defined options after the first configure run using
$ ccmake
Beware that this does not show options that have not been set and do not have a default
Build Step
Once configured, simply run cmake --build
pointing to the appropriate build directory:
$ cmake --build ./build -j $(nproc)
This command is build-backend-agnostic (it calls make
and ninja
on your behalf). Alternatively, one can call these
manually via make -j
or ninja -j 0
in the build directory.
Testing step
Simply run ctest
pointing to the appropriate build directory
$ ctest --test-dir ./build
See Testing section for more details
Install step
After you are satisfied with the build and test results, you can install Octopus for production use via
cmake --install
, pointing to the appropriate build directory
$ cmake --install ./build
⚠️ Warning
Due to octopus design you cannot currently redirect the install using
$ cmake --install ./build --prefix /new/path/to/octopus
Please make sure
CMAKE_INSTALL_PREFIX
was specified at the configure step
Testing
Regardless of CMake method you’ve used to build Octopus, you can configure and run individual tests using
ctest
, and pointing to the appropriate build directory
$ ctest --test-dir ./cmake-build-release
Make sure you run ctest
in parallel, especially when Octopus is built with MPI support. The following methods are
equivalent:
$ ctest --test-dir ./cmake-build-release -j $(nproc)
$ CTEST_PARALLEL_LEVEL="$(nproc)" ctest --test-dir ./cmake-build-release
All the MPI/OpenMP parallelization is handled by ctest
and it is configured at configure time. Just make sure your
desired OMP_NUM_THREADS
environment variable is set appropriately at the configure step.
The default ctest
will run all available tests, but you can select the tests you want using labels:
$ ctest --test-dir ./cmake-build-release --print-labels
Test project /octopus/cmake-build-release
All Labels:
components
errors
long-run
short-run
...
$ ctest --test-dir ./cmake-build-release -L short-run
Test project /octopus/cmake-build-release
Test #1: components/01-derivatives_1d
Test #2: components/02-derivatives_2d
Test #3: components/03-derivatives_3d
...
or regex of the specific test name, e.g. to run only the tests for dftbplus
:
$ ctest --test-dir ./cmake-build-release -R "-dftbplus_"
Test project /octopus/cmake-build-release
Test #150: multisystem/10-dftbplus_verlet
Test #151: multisystem/11-dftbplus_ehrenfest
...
Use -N
to simply view the tests that are meant to be run instead of running them
Troubleshooting
Here are some common problems, which might occur if you try to install on your system:
Incompatibilities
gfortran
is incompatible with the make
backend. This is a limitation of cmake, and results from the
Octopus’s reliance on the c-preprocessor.
Compilation Failure at First Macro Instance
Cmake can sometimes configure without problems, but fail early in the compilation step. If cmake fails with an error
pointing to an Octopus macro, such as ASSERT
(macros are non-standard fortran, written in all caps):
/Users/mainuser/octopus/src/basic/mpi.F90:370:32:
370 | ASSERT(not_in_openmp())
| 1
Error: Syntax error in IF-clause after (1)
this can be due to dangling files from a prior autotools build. We first recommend running:
make clean
make distclean
with autotools. This should remove the main culprit files:
src/include
config_F90.h
defaults.h
options.h
Deleting these files and reconfiguring with cmake should resolve the problem. If the problem still persists, we recommend cloning a fresh version of the repository. Additional autotools-generated files include:
build-aux
autom4te.cache
config.h
config.h.in
config.log
config.status
Makefile
Makefile.in
share/
Makefile
Makefile.in
variables
varinfo
varinfo_orig
external_libs
Makefile/
Makefile.in/
scripts/
Makefile
Makefile.in
and can all be safely removed.
Compilation Fails due to LibXC
If your system still has a system-installed libxc version 4, this would be picked up by CMake
before looking for a
different version that you might have installed manually. In order to instruct CMake
to use a specific version, add
-DLibxc_ROOT=<libxc-install-prefix>
(not the lib/
path!). If this still fails you can instead, either:
a) instruct CMake
to fetch and build libxc from source:
-DCMAKE_DISABLE_FIND_PACKAGE_Libxc=ON
or b) Use git submodule to fetch libxc, and point to this package:
# Prior running the configure step:
git submodule update --init
# Append to configure options
-DFETCHCONTENT_SOURCE_DIR_LIBXC=third_party/Libxc.
Incompatible Optional Library (e.g. BerkeleyGW)
If you have an older version of an optional library installed on your system, CMake
will automatically
detect and use it, but fail at compilation.
You can either try to upgrade the library or instruct CMake
to skip this package with -DCMAKE_DISABLE_FIND_PACKAGE_<name>=ON
.
Debugging Cmake
If there are other issues finding libraries, you can request more verbose information from CMake
by adding
--debug-find-pkg=<package-name>
to the command line.