Skip to content

CMake Refactoring Migration Guide

Summary of Changes

This refactoring reduces the CMake codebase from ~2000 lines to ~500 lines while maintaining all essential functionality.

What Was Removed

  • ❌ Intel, PGI, Clang compiler support (keeping only GCC/GFortran)
  • ❌ FortranOverride.cmake (800+ lines of unnecessary compiler detection)
  • ❌ Complex preprocessor handling
  • ❌ CPack packaging support (can be re-added if needed)
  • ❌ Static linking options
  • ❌ Coverage/profiling code (commented for now, easy to restore)
  • ❌ AFM support option
  • ❌ CUDA support
  • ❌ Verbose debugging options

What Was Kept

  • ✅ GCC/GFortran support (Linux & macOS)
  • ✅ OpenMP parallelization
  • ✅ OpenACC GPU support
  • ✅ Fortran coarray support
  • ✅ MPI support
  • ✅ FFTW3 integration
  • ✅ TIFF library support
  • ✅ Shared library building
  • ✅ Test building
  • ✅ Installation support
  • ✅ GUI/NICE installation
  • ✅ Script generation

What Was Modernized

  • ✨ Modern CMake 3.25+ syntax
  • ✨ Generator expressions for compile flags
  • ✨ Target-based linking (not directory-based)
  • ✨ Proper dependency propagation
  • ✨ Clean separation of concerns

File Structure

Before

CMakeLists.txt (200+ lines, messy)
cmake/
├── FortranOverride.cmake (800+ lines!)
├── SimpleFortranOptions.cmake (600+ lines!)
├── SimplePackage.cmake
├── Modules/
│   ├── FindFFTW.cmake
│   └── ...
└── PostInstall/

After

CMakeLists.txt (100 lines, clean)
cmake/
├── CompilerOptions.cmake (120 lines)
├── Dependencies.cmake (130 lines)
└── Modules/
    └── FindFFTW.cmake (if needed)
src/CMakeLists.txt (90 lines)
production/CMakeLists.txt (80 lines)

Migration Steps

1. Backup Current Setup

git checkout -b cmake-refactor
cp -r cmake cmake.old
cp CMakeLists.txt CMakeLists.txt.old

2. Replace Files

Replace the following files with the refactored versions: - CMakeLists.txt (root) - cmake/CompilerOptions.cmake (new) - cmake/Dependencies.cmake (new) - src/CMakeLists.txt - production/CMakeLists.txt

3. Remove Old Files

rm cmake/FortranOverride.cmake
rm cmake/SimpleFortranOptions.cmake
rm cmake/SimplePackage.cmake
# Keep other cmake/ files that might be needed

4. Update Build Commands

Old way:

mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=RELEASE -DUSE_OPENMP=ON
make -j4
make install

New way (same, but cleaner):

mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DUSE_OPENMP=ON
cmake --build . --parallel 4
cmake --install .

5. Environment Variables

You no longer need to set compiler environment variables manually. CMake will find them automatically. If you need specific compilers:

cmake .. \
  -DCMAKE_Fortran_COMPILER=gfortran-13 \
  -DCMAKE_C_COMPILER=gcc-13 \
  -DCMAKE_CXX_COMPILER=g++-13

Build Options

Option Default Description
CMAKE_BUILD_TYPE Release Debug, Release, RelWithDebInfo
USE_OPENMP ON OpenMP parallelization
USE_OPENACC OFF OpenACC GPU support
USE_COARRAYS OFF Fortran coarrays
USE_MPI OFF MPI support
BUILD_TESTS ON Build test executables
BUILD_DOCS OFF Build documentation
NICE ON Install GUI components

Testing the Build

Quick Test

cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . --parallel
ctest  # Run tests

Full Test

# Clean build
rm -rf build
mkdir build && cd build

# Configure with all options
cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DUSE_OPENMP=ON \
  -DUSE_MPI=OFF \
  -DBUILD_TESTS=ON \
  -DCMAKE_INSTALL_PREFIX=../install

# Build
cmake --build . --parallel

# Test
ctest

# Install
cmake --install .

Troubleshooting

"Cannot find gfortran"

CMake will automatically find gfortran. If you have multiple versions:

cmake .. -DCMAKE_Fortran_COMPILER=/usr/local/bin/gfortran-13

"FFTW not found"

Install FFTW3 development files:

# Ubuntu/Debian
sudo apt-get install libfftw3-dev

# macOS with Homebrew
brew install fftw

# Or set manually:
cmake .. -DFFTW_DIR=/path/to/fftw

"TIFF not found"

# Ubuntu/Debian
sudo apt-get install libtiff-dev libjpeg-dev zlib1g-dev

# macOS
brew install libtiff jpeg zlib

Build warnings about unused variables

This is normal - the refactored CMake is cleaner and doesn't set unnecessary variables.

If You Need Coverage/Profiling

Add this to cmake/CompilerOptions.cmake:

option(USE_CODE_COVERAGE "Enable code coverage" OFF)
if(USE_CODE_COVERAGE)
    add_compile_options(-g -O0 --coverage)
    add_link_options(--coverage)
endif()