Porting deal.II to new systems

deal.II uses very few POSIX specific system features and is otherwise fairly ISO (2011) C++ Standard compliant. Consequently, there is a good chance that deal.II will run on a reasonably well behaved system besides the ones listed in the ReadMe. Nevertheless, there are cases where some adjustments are necessary.

Unknown compiler

Currently, the deal.II CMake build system recognizes gcc, clang, as well as icc, and sets up reasonable default compiler flags.

Porting to a new platform

deal.II should support almost all reasonably POSIX compliant platforms out of the box. Nevertheless, the following bits of information might help:

Cross compiling

It is possible to use the CMake toolchain to cross compile deal.II for a platform other than the one on which the compiler is running. The target platform can have a different operating system, different architecture or different set of libraries. Cross compilation is a very useful technique, for instance it can be used to compile deal.II with a compiler that is not available in the target machine. An alternative technique is to use a Docker container or a virtual machine that mimics the target machine.

You can use any compiler for cross compilation, although LLVM/clang might be more versatile because it supports multiple architecture targets in a single executable natively (see Cross-compilation using Clang). Below you can find an example toolchain file for cross compilation with clang (and another example for Windows64 using MinGW).

set(target_root /path/to/sysroot)
set(dealii_dir ${target_root}/path/to/lib/dealii)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR x86_64)

set(CMAKE_SYSROOT ${target_root})

set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)

set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN ${target_root}/path/to/gcc/toolchain)
set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN ${target_root}/path/to/gcc/toolchain)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
If you use LLVM/clang you can use the gcc toolchain of the target with the option CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN, this is equivalent to the clang option --gcc-toolchain. You should place all the relevant libraries of the target in $target_root. ldd is a great tool figure out the libraries that you need. You can use the C libraries of the target such as Blas, HDF5 and MPI. On the other hand C++ libraries can be problematic because different C++ compilers (or even different versions of the same compiler, or the same compiler on different platforms) mangle public symbols in radically different ways. For this reason C++ libraries such as Trilinos should be cross compiled by the same compiler as deal.II.

If the host and the target have a different architecture, you have to set up a native deal.II build directory first and run make expand_instantiations_exe in it. The executable is needed for the build system (the cross compiled version cannot be used if the architecture of the target and the host are not the same). Locate the expand_instantiations executable (it usually resides under ${CMAKE_BINARY_DIR}/bin) and export its location with the PATH environment variable. Below you can find a minimal cmake script for the configuration of deal.II.

mkdir $dealii_build
cd $dealii_build
export LD_LIBRARY_PATH=$target_root/lib/directories
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
        -DDEAL_II_FORCE_BUNDLED_BOOST=ON \
        -DDEAL_II_ALLOW_AUTODETECTION=OFF \
        -DDEAL_II_WITH_MPI=ON \
        -DMPI_CXX_INCLUDE_PATH:STRING=$target_root'/path/to/mpi/include' \
        -DMPI_CXX_LIBRARIES:STRING=$target_root'/path/to/mpi/lib/libmpi_1.so;'$target_root'/path/to/mpi/lib/libmpi_2.so' \
        -DDEAL_II_WITH_TRILINOS=ON \
        -DTRILINOS_DIR=$target_root/path/to/trilinos \
        -DDEAL_II_WITH_P4EST=ON \
        -DP4EST_DIR=$target_root/path/to/p4est \
        -DCMAKE_INSTALL_PREFIX=$target_root/path/to/dealii \
        /path/to/dealii/repository
make expand_instantiations_exe
export PATH=$dealii_build/bin/:$PATH
make -jN install
If the target uses LD_LIBRARY_PATH to set up some libraries, you may need to export LD_PRELOAD_PATH with those libraries before you call CMake. Note that CMake might not be able to guess the MPI configuration, therefore you may have to give all the MPI flags to CMake. There are two ways to obtain the MPI flags, you can compile another program at the target and then inspect CMakeCache.txt or you can obtain the flags using mpic++ --showme:compile and mpic++ --showme:link. The remaining configuration can be adjusted at will, see the documentation. Note that the rpaths of the examples might not be correct, this can be fixed using LD_LIBRARY_PATH or chrpath.


Valid HTML 4.01! Valid CSS!