From b95462c6c4b2f6faeb5b8338b76d9f101ff819f9 Mon Sep 17 00:00:00 2001 From: Sean Bryan Date: Tue, 23 Jan 2024 14:35:04 +1100 Subject: [PATCH] Update build system documentation --- .../other_resources/build_system.md | 32 ++++++++ documentation/docs/user_guide/installation.md | 77 +++++++------------ .../docs/user_guide/uber_quick_guide.md | 6 +- documentation/mkdocs.yml | 1 + 4 files changed, 65 insertions(+), 51 deletions(-) create mode 100644 documentation/docs/developer_guide/other_resources/build_system.md diff --git a/documentation/docs/developer_guide/other_resources/build_system.md b/documentation/docs/developer_guide/other_resources/build_system.md new file mode 100644 index 000000000..b14407d3d --- /dev/null +++ b/documentation/docs/developer_guide/other_resources/build_system.md @@ -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__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=` 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 + CMake's `find_package` should be used in **Config** mode and only in **Module** mode only 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 \ No newline at end of file diff --git a/documentation/docs/user_guide/installation.md b/documentation/docs/user_guide/installation.md index 22bb5b927..c5ee860f8 100644 --- a/documentation/docs/user_guide/installation.md +++ b/documentation/docs/user_guide/installation.md @@ -2,7 +2,9 @@ To install CABLE you need to have the following already installed on your system: -- git +- `git` +- `cmake` +- `pkg-config` - a Fortran compiler - the netCDF library @@ -11,20 +13,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; @@ -74,58 +76,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 `/build` directory. Once built successfully, they are then installed in the `/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 \ No newline at end of file diff --git a/documentation/docs/user_guide/uber_quick_guide.md b/documentation/docs/user_guide/uber_quick_guide.md index 9530ad176..8f0aea573 100644 --- a/documentation/docs/user_guide/uber_quick_guide.md +++ b/documentation/docs/user_guide/uber_quick_guide.md @@ -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 diff --git a/documentation/mkdocs.yml b/documentation/mkdocs.yml index d1cde8d11..cbc5aaab0 100644 --- a/documentation/mkdocs.yml +++ b/documentation/mkdocs.yml @@ -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