Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Build and Test
run: |
make -f ./make/vm-x86-gfortran-gcc.mk check
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
112 changes: 112 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# ------------------------------------------------------------------------------
# (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)
include(cmake/PkgConfig.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"
}
]
}
20 changes: 20 additions & 0 deletions cmake/PkgConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ------------------------------------------------------------------------------
# (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.
# ------------------------------------------------------------------------------

if(ENABLE_PKGCONFIG)
# Create and install a pkg-config file
#
# This will only work correctly if the --install-prefix argument is
# used when CMake is first run and the files are generated. It will
# break if a different --prefix location is passed to cmake --install
#
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/${PROJECT_NAME}.pc.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
@ONLY)

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
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()
35 changes: 35 additions & 0 deletions cmake/ShumAddSublibrary.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ------------------------------------------------------------------------------
# (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.
# ------------------------------------------------------------------------------

# 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()
46 changes: 46 additions & 0 deletions cmake/ShumFruit.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# ------------------------------------------------------------------------------
# (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.
# ------------------------------------------------------------------------------

# 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}")

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()
52 changes: 52 additions & 0 deletions cmake/ShumOptions.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# ------------------------------------------------------------------------------
# (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.
# ------------------------------------------------------------------------------

# 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}")
list(APPEND SHUM_DEFINES "SHUMLIB_CMAKE=1")

# Install options
option(ENABLE_PKGCONFIG "Install a pkg-config description" ON)

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()
Loading
Loading