Skip to content

Commit

Permalink
Update build system documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
SeanBryan51 committed Feb 27, 2024
1 parent 09aabbf commit 4e67658
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 51 deletions.
32 changes: 32 additions & 0 deletions documentation/docs/developer_guide/other_resources/build_system.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
For CABLE offline applications, the underlying build system is [CMake](https://cmake.org) based. CMake is widely used in the C, C++ and Fortran communities and there are many great resources out there on the web, in particular:

- [Mastering CMake](https://cmake.org/cmake/help/book/mastering-cmake/index.html)
- [Effective Modern CMake](https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1)
- [Creating a CMake project (with Fortran)](https://fortran-lang.org/learn/building_programs/build_tools/#creating-a-cmake-project)
- [An Introduction to Modern CMake](https://cliutils.gitlab.io/modern-cmake/)

## Adding source files

Source files can be added easily by adding to the list of source files in [CMakeLists.txt][CMakeLists.txt].

## Setting compiler flags

The recommended compiler flags for debug and release builds are set in the [CMakeLists.txt][CMakeLists.txt] file via [`target_compile_options`](https://cmake.org/cmake/help/latest/command/target_compile_options.html). These can be modified if required.

???+ warning
Compiler flags should be guarded by a check on the compiler ID as they are generally compiler specific. See [`CMAKE_<LANG>_COMPILER_ID`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html) for a list of supported compiler IDs.

Alternatively, compiler flags can be specified when invoking `cmake` by specifying `-DCMAKE_Fortran_FLAGS=<flags>` when generating the project, however the per configuration default flags may take precedence (see [CMAKE_LANG_FLAGS](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html) for more details).

## Adding external dependencies (libraries)

When linking against external third-party libraries, we strongly recommend not to hard code library paths, include paths, link flags or compiler flags in the CMakeLists.txt file. This is ensures that the build system is portable and insulated from changes to library versions and dependencies.

Instead, CMake should query the required flags for a given library from the library itself. To do this, we recommend using either CMake's [`find_package` mechanism](https://cmake.org/cmake/help/book/mastering-cmake/chapter/Finding%20Packages.html) or a tool such as [`pkg-config`](https://en.wikipedia.org/wiki/Pkg-config) (see the [FindPkgConfig](https://cmake.org/cmake/help/latest/module/FindPkgConfig.html) module for using `pkg-config` with CMake.). The dependencies should provide exported targets which can be used via [`target_link_libraries`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html).

If these approaches are not supported by the external library, please report this as a bug to its maintainers. If the library is an open-source project, consider sending a patch.

???+ warning
For most cases, CMake's `find_package` should be used in **Config** mode. `find_package` in **Module** mode should only be used if the library is part of the [CMake module distribution](https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html#manual:cmake-modules(7)).

[CMakeLists.txt]: https://github.com/CABLE-LSM/CABLE/blob/main/CMakeLists.txt
78 changes: 30 additions & 48 deletions documentation/docs/user_guide/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

To install CABLE you need to have the following already installed on your system:

- git
- `git`
- `cmake`
- `pkg-config`
- MPI (for parallel applications)
- a Fortran compiler
- the netCDF library

Expand All @@ -11,20 +14,20 @@ To install CABLE you need to have the following already installed on your system
``` mermaid
graph TD
A(Clone CABLE with git):::UserAction -->|Serial?| B(Run `offline/build3.sh`):::UserAction;
B --> D[load modules, set compiler flags, create .tmp/ directory];
D -->|Serial?| E[Run `make`];
E --> G[executable `cable`]:::Output;
A -->|Parallel?| C(Run `offline/build3.sh mpi`):::UserAction;
A(Clone CABLE with git):::UserAction -->|Serial?| B(Run `./build.bash`):::UserAction;
B --> D[load modules and invoke `cmake`];
D -->|Serial?| E;
E[executable `cable`]:::Output;
A -->|Parallel?| C(Run `./build.bash --mpi`):::UserAction;
C --> D;
D -->|Parallel?| F[Run `make mpi`];
F --> H[executable `cable_mpi`]:::Output;
click A "http://cable.readthedocs.io/en/latest/user_guide/installation/#getting-the-cable-source-code"
click B "http://cable.readthedocs.io/en/latest/user_guide/installation/#launching-the-build"
click C "http://cable.readthedocs.io/en/latest/user_guide/installation/#launching-the-build"
click D "http://cable.readthedocs.io/en/latest/user_guide/installation/#description-of-the-build-process"
click E "http://cable.readthedocs.io/en/latest/user_guide/installation/#description-of-the-build-process"
click F "http://cable.readthedocs.io/en/latest/user_guide/installation/#description-of-the-build-process"
D -->|Parallel?| F;
F[executable `cable-mpi`]:::Output;
click A "#getting-the-cable-source-code"
click B "#launching-the-build"
click C "#launching-the-build"
click D "#description-of-the-build-process"
click E "#description-of-the-build-process"
click F "#description-of-the-build-process"
UserAction ---- Automatic ---- Output;
Expand Down Expand Up @@ -74,58 +77,37 @@ CABLE supports both serial and parallel applications.
???+ tip "Multiprocessor for global simulations"
For global (or regional) offline simulations, CABLE can still be run in serial mode (about 15 minutes/year for GSWP global run at 1x1 degree resolution). However, running on multiple processors speeds up the simulation considerably.

CABLE can be built using the BASH script [build3.sh][build3] in the **offline/** directory.
CABLE can be built using the BASH script [build.bash][build.bash] in the project root directory.

???+ tip "Build on other HPC"
The function *host_gadi* in the build script shows the appropriate configuration to build on Gadi.
This may be of use as a template building CABLE on another Linux/HPC system.
Gadi specific configuration is guarded by a check on the current hostname (see [here][build.bash-hostname-check]). This may be of use as a template for building CABLE on another Linux/HPC system.

Both the serial and parallel executable for CABLE offline are built in the `offline/` directory by executing
the build script.
Executables are built in the `<project_root>/build` directory. Once built successfully, they are then installed in the `<project_root>/bin` directory.

To build the serial model execute:

./build3.sh
./build.bash

To build the parallel model execute the same build script but with the argument **mpi**.
To build the parallel model execute the same build script but with the `--mpi` flag.

./build3.sh mpi
./build.bash --mpi

Run `./build.bash --help` to see all supported options provided by the build script.

???+ warning
If you need to switch between a serial compilation and a parallel compilation, you need to completely [clean the previous build][clean-build] first.

### Description of the build process

The build script:

1. loads modules for the Fortran compiler and the netCDF library
2. sets the compiler flags
3. creates a hidden temporary directory (`.tmp/`) in which it then compiles CABLE.
4. executes `make` in the hidden temporary directory

The [Makefile][makefile] compiles the serial executable by default (via `make`) and compiles the MPI executable via the `mpi` target (via `make mpi`).

The hidden `.tmp/` directory is really only needed for technical reasons and you should never need to go
into the `.tmp/` directory. However, if for some reason you want the **.o** object files created by the compiler, they persist in this directory. Alternatively, it is sometimes useful to verify that the files you want to compile are actually making it into this directory. This is particularly relevant if you are adding new files to CABLE.

???+ warning "Do not change files under `.tmp/`"
If you change the files in `.tmp/` directly, the next build will not pick up these changes and will overwrite them.

One of the features of the build process is that only source files which are
modified are re-built, followed by their dependents. This is possible because the `.tmp/` directory is
overwritten by the build script, preserving timestamps of the source files from their original location.

### Cleaning the build

From time to time, it might be useful to clean a previous build completely and restart the build from scratch. This is required when switching between serial and parallel builds.

To clean the build, you need to run:
To clean the previous build prior to compiling, specify the `--clean` flag to `build.bash`.

./build3.sh clean
./build.bash --clean

[cable-github]: https://github.com/CABLE-LSM/cable.git
[NCI]: https://nci.org.au
[registration]: https://trac.nci.org.au/trac/cable/wiki/CABLE_Registration
[build3]: https://github.com/CABLE-LSM/CABLE/blob/main/src/offline/build3.sh
[makefile]: https://github.com/CABLE-LSM/CABLE/blob/main/src/offline/Makefile
[clean-build]: installation.md/#cleaning-the-build
[build.bash]: https://github.com/CABLE-LSM/CABLE/blob/main/build.bash
[build.bash-hostname-check]: https://github.com/CABLE-LSM/CABLE/blob/main/build.bash#L45-L55
[clean-build]: installation.md/#cleaning-the-build
6 changes: 3 additions & 3 deletions documentation/docs/user_guide/uber_quick_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ Assuming you have computing resources on gadi@NCI, installing and running CABLE
1. Clone the source code:

git clone https://github.com/CABLE-LSM/CABLE.git
cd CABLE/offline
cd CABLE

1. Build a serial version of CABLE

./build3.sh
./build.bash

1. Execute this serial version of CABLE

./cable
./bin/cable

## In slightly more detail

Expand Down
1 change: 1 addition & 0 deletions documentation/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ nav:
- Scientific documentation: developer_guide/documentation_guidelines/science_doc.md
- Other resources:
- Coding standards: developer_guide/other_resources/coding_standards.md
- Build System: developer_guide/other_resources/build_system.md
- Cheat Sheets: developer_guide/other_resources/cheat_sheets.md
- CABLE's release process: developer_guide/other_resources/release_process.md
- API documentation: developer_guide/other_resources/api.md
Expand Down

0 comments on commit 4e67658

Please sign in to comment.