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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Default build directory
_build/
build/

# Virtual environment
.venv/
Expand Down
111 changes: 111 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# ------------------------------------------------------------------------------
# (c) Crown copyright Met Office. All rights reserved.
# The file LICENCE, distributed with this code, contains details of the terms
# under which the code may be used.
# ------------------------------------------------------------------------------
#
# This is the top-level CMake build file for the Shared Unified Model
# Library
#
cmake_minimum_required(VERSION 3.20 FATAL_ERROR)

# Shumlib version numbers are the 4-digit year followed by 2-digit
# month and an additional digit signifying the release count within
# that specified month. This should be specified in major.minor.patch
# format used by CMake and then recombined to allow it to be passed to
# shumlib via a pre-processor definition
project(shumlib LANGUAGES C Fortran
VERSION 2026.01.1
DESCRIPTION "Met Office Shared Unifed Model Library"
HOMEPAGE_URL "https://github.com/MetOffice/shumlib")

string(CONCAT SHUMLIB_VERSION
${PROJECT_VERSION_MAJOR}
${PROJECT_VERSION_MINOR}
${PROJECT_VERSION_PATCH})

set(CMAKE_C_STANDARD 99)
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules)

# Include helper and setup routines
include(GNUInstallDirs)
include(cmake/PreventInSourceBuilds.cmake)
include(cmake/ShumAddSublibrary.cmake)
include(cmake/ShumFruit.cmake)
include(cmake/ShumOptions.cmake)
include(cmake/ShumVersions.cmake)


# Build rules for shumlib
add_library(shum)

add_shum_sublibraries(shum
TARGETS
shum_byteswap
shum_constants
shum_data_conv
shum_fieldsfile
shum_fieldsfile_class
shum_horizontal_field_interp
shum_kinds
shum_latlon_eq_grids
shum_number_tools
shum_spiral_search
shum_string_conv
shum_thread_utils
shum_wgdos_packing)

configure_shum_versions()

target_compile_definitions(shum
PUBLIC
${SHUM_DEFINES})

# Install shumlib and the C header files for the sub-libraries that
# have them
install(TARGETS shum
FILE_SET byteswap_headers
FILE_SET data_conv_headers
FILE_SET spiral_search_headers
FILE_SET thread_utils_headers
FILE_SET wgdos_packing_headers
)

# Install the Fortran module files
install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

# Unit tests and framework
if(BUILD_TESTS)
enable_testing()
add_library(fruit)

# Set a relative RPATH to ensure that the unit tests continue to
# work even after being installed
list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN")
list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
add_executable(shumlib-tests)

target_compile_definitions(shumlib-tests
PUBLIC
${SHUM_DEFINES})

target_include_directories(shumlib-tests
PUBLIC ${CMAKE_Fortran_MODULE_DIRECTORY})
target_link_libraries(shumlib-tests PUBLIC fruit shum)

add_subdirectory(fruit)
setup_shum_fruit()

install(TARGETS fruit)
install(TARGETS shumlib-tests)

add_test(NAME shumlib-tests
COMMAND $<TARGET_FILE:shumlib-tests>)

# Always set the shumlib directory to /tmp
set_property(TEST shumlib-tests
APPEND PROPERTY
ENVIRONMENT SHUM_TMPDIR=/tmp)

endif()
70 changes: 70 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"version": 2,
"configurePresets": [
{
"name": "debug",
"displayName": "Debug",
"generator": "Unix Makefiles",
"binaryDir": "build/debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "debug-gcc",
"displayName": "GCC Debug",
"inherits": "debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_COMPILER": "gcc",
"CMAKE_Fortran_COMPILER": "gfortran",
"CMAKE_C_FLAGS_INIT": "-g -Wall -Wextra -Werror -Wformat=2 -Winit-self -Wfloat-equal -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wconversion -Wlogical-op -Wstrict-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Woverlength-strings -Wshadow -Wall -Wextra -Wpedantic -fdiagnostics-show-option",
"CMAKE_Fortran_FLAGS_INIT": "-g -std=f2018 -pedantic -pedantic-errors -fno-range-check -Wall -Wextra -Werror -Wno-compare-reals -Wconversion -Wno-unused-dummy-argument -Wno-c-binding-type -fdiagnostics-show-option"
}
},
{
"name": "debug-cce",
"displayName": "Cray CCE Debug",
"inherits": "debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_COMPILER": "cc",
"CMAKE_Fortran_COMPILER": "ftn",
"CMAKE_C_FLAGS_INIT": "-g -Weverything -Wno-vla -Wno-padded -Wno-missing-noreturn -Wno-declaration-after-statement -Werror -pedantic -pedantic-errors -fdiagnostics-show-option -DSHUM_X86_INTRINSIC",
"CMAKE_Fortran_FLAGS_INIT": "-g -M E287,E5001,1077"
}
},
{
"name": "debug-nvhpc",
"displayName": "nvidia HPC Debug",
"inherits": "debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_COMPILER": "nvcc",
"CMAKE_Fortran_COMPILER": "nvfortran",
"CMAKE_C_FLAGS_INIT": "-g",
"CMAKE_Fortran_FLAGS_INIT": "-g"
}
}
],
"buildPresets": [
{
"name": "debug-gcc",
"displayName": "GCC Debug Build",
"configurePreset": "debug",
"configuration": "Debug"
},
{
"name": "debug-cce",
"displayName": "Cray CCE Debug Build",
"configurePreset": "debug",
"configuration": "Debug"
},
{
"name": "debug-nvhpc",
"displayName": "nvidia HPC Debug Build",
"configurePreset": "debug",
"configuration": "Debug"
}
]
}
23 changes: 23 additions & 0 deletions cmake/PreventInSourceBuilds.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# ------------------------------------------------------------------------------
# (c) Crown copyright Met Office. All rights reserved.
# The file LICENCE, distributed with this code, contains details of the terms
# under which the code may be used.
# ------------------------------------------------------------------------------
# This function will prevent in-source builds
function(AssureOutOfSourceBuilds)
# Make sure the user doesn't perform in-source builds by tricking
# the build system through the use of symlinks
get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH)

# Disallow in-source builds
if ("${srcdir}" STREQUAL "${bindir}")
message("######################################################")
message("Warning: in-source builds are disabled")
message("Please create a separate build directory and run cmake from there")
message("######################################################")
message(FATAL_ERROR "Quitting configuration")
endif ()
endfunction()

AssureOutOfSourceBuilds()
29 changes: 29 additions & 0 deletions cmake/ShumAddSublibrary.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Add shumlib sublibraries
#
# Each section of shumlib is in its own subdiretory with its own
# CMakeLists.txt file in its src/ directory. Add each src directory
# and add the name of the sublibrary to a list for subsequnt use with
# the regression testing framework.
macro(add_shum_sublibraries libname)

set(multiValueArgs TARGETS)
cmake_parse_arguments(arg_sublibs
"" "" "${multiValueArgs}"
${ARGN})

set(CMAKE_SHUM_SUBLIBS "")

message(STATUS "Adding shublib sub-libraries to ${libname}")

foreach(sublib IN LISTS arg_sublibs_TARGETS)
if(EXISTS ${sublib}/src/CMakeLists.txt)
message(VERBOSE "Including ${sublib}")
add_subdirectory(${sublib}/src)
list(APPEND CMAKE_SHUM_SUBLIBS ${sublib})
else()
message(FATAL_ERROR "Unaable to add ${sublib}")
endif()

endforeach()

endmacro()
41 changes: 41 additions & 0 deletions cmake/ShumFruit.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Setup fruit unit testing for shumlib
#
# Take the accumluted list of shumlib subdirectories and use it to
# generate the top-level driver for the regression suite.
#
macro(setup_shum_fruit)

message(STATUS "Creating shumlib regression tests")

list(LENGTH CMAKE_SHUM_SUBLIBS fruit_count)
if(${fruit_count} EQUAL 0)
message(FATAL_ERROR "No regression tests set")
endif()
unset(fruit_count)

set(SHUM_FRUIT_USE "! Use shumlib modules")
set(SHUM_FRUIT_CALLS "! Call shumlib unit tests")

foreach(SHUM_LIBNAME IN LISTS CMAKE_SHUM_SUBLIBS)
# Build the variables that pull in each of the test modules ready
# to process the driver template

if(EXISTS ${SHUM_LIBNAME}/test/CMakeLists.txt)
message(VERBOSE "Adding ${SHUM_LIBNAME} unit tests")

set(SHUM_FRUIT_USE "${SHUM_FRUIT_USE}\nUSE fruit_test_${SHUM_LIBNAME}_mod")
set(SHUM_FRUIT_CALLS "${SHUM_FRUIT_CALLS}\nCALL fruit_test_${SHUM_LIBNAME}")

# FIXME: deal with relative path
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does this want fixing here?

add_subdirectory(${SHUM_LIBNAME}/test)
endif()

endforeach()

configure_file(fruit/fruit_driver.f90.in
fruit_driver.f90)

target_sources(shumlib-tests PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}/fruit_driver.f90")

endmacro()
42 changes: 42 additions & 0 deletions cmake/ShumOptions.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Library type options
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

# Data options
option(IEEE_ARITHMETIC "Use Fortran intrinsic IEEE features" OFF)
option(NAN_BY_BITS "Check NaNs by bitwise inspection" OFF)
option(DENORMAL_BY_BITS "Check denormals by bitwise inspect" OFF)

# Build options
option(BUILD_OPENMP "Build with OpenMP parallelisation" ON)
option(BUILD_FTHREADS "Build with Fortran OpenMP everywhere" OFF)
option(BUILD_TESTS "Build fruit unit tests" ON)

# Build a list of preprocessor settings based on options
set(SHUM_DEFINES "SHUMLIB_VERSION=${SHUMLIB_VERSION}")

if(IEEE_ARITHMETIC)
message(VERBOSE "Enabling shumlib IEEE arithmetic")
list(APPEND SHUM_DEFINES "HAS_IEEE_ARITHMETIC")
endif()

if(NAN_BY_BITS)
message(VERBOSE "Enabling shumlib evaluate NaNs by bits")
list(APPEND SHUM_DEFINES "EVAL_NAN_BY_BITS")
endif()

if(DENORMAL_BY_BITS)
message(VERBOSE "Enabling shumlib evaluate denormals by bits")
list(APPEND SHUM_DEFINES "EVAL_DENORMAL_BY_BITS")
endif()

if(BUILD_OPENMP)
# FIXME: this probably needs newer version of cmake on the Cray
find_package(OpenMP 3.0 REQUIRED)

if(BUILD_FTHREADS)
message(VERBOSE "Using shumlib with Fortran OpenMP threading")
list(APPEND SHUM_DEFINES
SHUM_USE_C_OPENMP_VIA_THREAD_UTILS="shum_use_c_openmp_via_thread_util")
endif()

endif()
30 changes: 30 additions & 0 deletions cmake/ShumVersions.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Create shumlib version files from templates
#
# Replace the previous versioning which used preprocessor macros and
# pure Makefiles with templating of the module file.
macro(configure_shum_versions)

message(STATUS "Creating shumlib version functions")

foreach(SHUM_LIBNAME IN LISTS CMAKE_SHUM_SUBLIBS)
message(VERBOSE "Versioning ${SHUM_LIBNAME}")
configure_file(common/src/f_version_mod.f90.in
"f_${SHUM_LIBNAME}_version_mod.f90")

target_sources(shum PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}/f_${SHUM_LIBNAME}_version_mod.f90")

endforeach()

# FIXME: remove hardwiring?
target_include_directories(shum
PUBLIC
common/src)

target_sources(shum PRIVATE
common/src/shumlib_version.c)

unset(SHUM_LIBNAME)
unset(SHUM_VERSION_DEFINES)

endmacro()
12 changes: 12 additions & 0 deletions common/src/f_version_mod.f90.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
MODULE f_@SHUM_LIBNAME@_version_mod
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
INTERFACE
FUNCTION get_@SHUM_LIBNAME@_version() RESULT(version) &
BIND(C, name='GET_SHUMLIB_VERSION')
IMPORT :: C_INT64_T
IMPLICIT NONE
INTEGER(KIND=C_INT64_T) :: version
END FUNCTION get_@SHUM_LIBNAME@_version
END INTERFACE
END MODULE f_@SHUM_LIBNAME@_version_mod
5 changes: 3 additions & 2 deletions common/src/shumlib_version.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@
#include "precision_bomb.h"
#include "shumlib_version.h"

int64_t GET_SHUMLIB_VERSION(SHUMLIB_LIBNAME) {
return SHUMLIB_VERSION;}
int64_t GET_SHUMLIB_VERSION(void) {
return SHUMLIB_VERSION;
}
Loading
Loading