Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions BUILD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# MAPL Build System

This directory contains simplified build and test scripts for MAPL development.

## Quick Start

### Building MAPL

```bash
./build.sh [compiler] [build_type]
```

**Examples:**
```bash
# Build with NAG compiler (Debug mode, default)
./build.sh nag

# Build with GFortran compiler (Debug mode)
./build.sh gfortran

# Build with NAG compiler (Release mode)
./build.sh nag Release
```

### Running Tests

```bash
./test.sh [compiler] [test_pattern]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We’ll need build type, unless we assume that we are testing only the Debug build for that compiler

```

**Examples:**
```bash
# Run all tests with NAG compiler
./test.sh nag

# Run all tests with GFortran compiler
./test.sh gfortran

# Run specific test(s) matching pattern
./test.sh nag ConservationAspect
```

## How It Works

The build system uses **meta-modules** (compiler stacks) and **wrapper scripts** to simplify the workflow:

### Meta-Modules

- `nag-stack` - Loads NAG compiler + OpenMPI + baselibs
- `gfortran-stack` - Loads GFortran compiler + OpenMPI + baselibs
- `ifort-stack` - Loads Intel Fortran compiler + OpenMPI + baselibs

These meta-modules automatically handle:
- `module purge` and `module load` sequences
- Compiler dependencies (e.g., NAG requires clang)
- MPI configuration
- Baselibs setup

### Wrapper Scripts

**`build.sh`**:
- Loads the appropriate compiler stack module
- Creates build directory (`build-<compiler>`)
- Configures CMake with appropriate settings
- Builds the project

**`test.sh`**:
- Loads the appropriate compiler stack module
- Uses `ctest` to run tests (automatically handles DYLD_LIBRARY_PATH on macOS)
- Supports test filtering with regex patterns

## Build Directories

By convention, builds are organized by compiler:
- `build-nag/` - NAG compiler builds
- `build-gfortran/` - GFortran compiler builds
- `build-ifort/` - Intel compiler builds

## Manual Module Loading

If you need more control, you can still use modules manually:

```bash
module purge
module load nag-stack
cmake -B build-nag -DCMAKE_BUILD_TYPE=Debug
cmake --build build-nag -j8
```

## Supported Compilers

- **nag** - NAG Fortran compiler (default: 7.2.41)
- **gfortran** - GNU Fortran compiler (default: 15.2.0)
- **ifort** - Intel Fortran compiler

## System Requirements

- Lmod module system
- CMake 3.24+
- Appropriate compiler stack modules installed

## Troubleshooting

**"Module not found" errors:**
- Ensure you have the meta-modules installed in `~/modulefiles/core/`
- Check `module avail` to see available modules

**Build failures:**
- Check that all dependencies are loaded: `module list`
- Verify the build directory is clean or rebuild from scratch

**Test failures on macOS:**
- The `test.sh` script uses `ctest` which automatically handles DYLD_LIBRARY_PATH
- If running tests manually, ensure proper library paths are set

## For AI Agents

The simplified workflow is designed to reduce cognitive load:

1. **To build**: `./build.sh <compiler>`
2. **To test**: `./test.sh <compiler>`

No need to remember:
- Module loading sequences
- DYLD_LIBRARY_PATH settings
- CMake configuration options
- Build directory naming conventions
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add simplified build system with wrapper scripts (`build.sh` and `test.sh`) for easier compilation with different compilers
- Uses modern CMake syntax (`-B`, `-S`, `--install-prefix`, `--test-dir`)
- Supports NAG, gfortran, and Intel compilers via meta-module stacks
- Compiler-specific build and install directories
- Full path handling for improved safety

### Changed

- Update `components.yaml` to match GEOSgcm v12
Expand Down
69 changes: 69 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/bash
# MAPL build wrapper script
# Simplifies building with different compilers by handling module loading

set -e

# Default values
COMPILER="${1:-nag}"
BUILD_TYPE="${2:-Debug}"
INSTALL_PREFIX="${3:-}"

# Use full paths for safety
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_DIR="${SOURCE_DIR}/build-${COMPILER}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use something like
BUILD_DIR="${SOURCE_DIR}/build/${COMPILER}/${BUILD_TYPE}”
Might be cleaner - you will need to gitignore only the build directory.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, at the moment we ignore:

/build*
/install*

so if it's a directory called that, we ignore it. Plus our CMake adds a .gitignore file to all build and install directories regardless of names.

if [[ -z "$INSTALL_PREFIX" ]]; then
INSTALL_DIR="${SOURCE_DIR}/install-${COMPILER}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to BUILD_DIR

else
INSTALL_DIR="$INSTALL_PREFIX"
fi

# Supported compilers
SUPPORTED_COMPILERS="nag gfortran ifort"

# Check if compiler is supported
if [[ ! " $SUPPORTED_COMPILERS " =~ " $COMPILER " ]]; then
echo "Error: Unsupported compiler '$COMPILER'"
echo "Supported compilers: $SUPPORTED_COMPILERS"
exit 1
fi

echo "========================================="
echo "MAPL Build Configuration"
echo "========================================="
echo "Compiler: $COMPILER"
echo "Build Type: $BUILD_TYPE"
echo "Build Dir: $BUILD_DIR"
echo "Install Dir: $INSTALL_DIR"
echo "========================================="

# Load the appropriate compiler stack
echo "Loading ${COMPILER}-stack module..."
module purge
module load ${COMPILER}-stack

echo ""
echo "Loaded modules:"
module list

# Configure with CMake (modern syntax)
echo ""
echo "Configuring with CMake..."
cmake -B "${BUILD_DIR}" \
-S "${SOURCE_DIR}" \
--install-prefix="${INSTALL_DIR}" \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}"

# Build
echo ""
echo "Building..."
cmake --build "${BUILD_DIR}" --parallel 8

echo ""
echo "========================================="
echo "Build completed successfully!"
echo "========================================="
echo "Build directory: $BUILD_DIR"
echo "Install directory: $INSTALL_DIR"
echo "To run tests: ./test.sh $COMPILER"
echo "To install: cmake --build ${BUILD_DIR} --target install"
63 changes: 63 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/bash
# MAPL test wrapper script
# Simplifies running tests with different compilers

set -e

# Default values
COMPILER="${1:-nag}"
TEST_PATTERN="${2:-}"

# Use full paths for safety
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_DIR="${SOURCE_DIR}/build-${COMPILER}"

# Supported compilers
SUPPORTED_COMPILERS="nag gfortran ifort"

# Check if compiler is supported
if [[ ! " $SUPPORTED_COMPILERS " =~ " $COMPILER " ]]; then
echo "Error: Unsupported compiler '$COMPILER'"
echo "Supported compilers: $SUPPORTED_COMPILERS"
exit 1
fi

# Check if build directory exists
if [[ ! -d "$BUILD_DIR" ]]; then
echo "Error: Build directory '$BUILD_DIR' does not exist"
echo "Please run './build.sh $COMPILER' first"
exit 1
fi

echo "========================================="
echo "MAPL Test Configuration"
echo "========================================="
echo "Compiler: $COMPILER"
echo "Build Dir: $BUILD_DIR"
if [[ -n "$TEST_PATTERN" ]]; then
echo "Test Pattern: $TEST_PATTERN"
fi
echo "========================================="

# Load the appropriate compiler stack
echo "Loading ${COMPILER}-stack module..."
module purge
module load ${COMPILER}-stack

echo ""
echo "Loaded modules:"
module list

# Run tests using ctest (modern syntax with --test-dir)
echo ""
echo "Running tests..."
if [[ -n "$TEST_PATTERN" ]]; then
ctest --test-dir "${BUILD_DIR}" --output-on-failure -R "$TEST_PATTERN"
else
ctest --test-dir "${BUILD_DIR}" --output-on-failure
fi

echo ""
echo "========================================="
echo "Tests completed!"
echo "========================================="
Loading