diff --git a/.github/actions/ngen-build/action.yaml b/.github/actions/ngen-build/action.yaml index b1df107c2b..b97ed79268 100644 --- a/.github/actions/ngen-build/action.yaml +++ b/.github/actions/ngen-build/action.yaml @@ -1,4 +1,5 @@ name: 'Checkout and build tests' + description: 'This action checks out the commit, sets up Ngen environemnt.' author: 'hellkite500' inputs: @@ -165,6 +166,11 @@ runs: deactivate shell: bash + - name: Setup Fortran Compiler + if: ${{ inputs.bmi_fortran == 'ON' && runner.os == 'macOS' }} + run: echo "FC=gfortran-13" >> $GITHUB_ENV + shell: bash + - name: Cmake Initialization id: cmake_init run: | diff --git a/.github/workflows/Example_model_run.yml b/.github/workflows/Example_model_run.yml index f5c4851487..b67e5cf1a1 100644 --- a/.github/workflows/Example_model_run.yml +++ b/.github/workflows/Example_model_run.yml @@ -8,11 +8,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the code - uses: actions/checkout@v3 + uses: actions/checkout@v4 + - name: Build the NGEN image - run: docker build . --file ./docker/CENTOS_NGEN_RUN.dockerfile --tag localbuild/ngen:latest + run: docker build --file ./docker/ngen.dockerfile --tag localbuild/ngen:latest . + - name: Run the NGEN model on example data - run: docker run --rm -i localbuild/ngen:latest - #Internal command has hardcoded paths to repo-local data - #When running command manually from container use below: - #./ngen data/catchment_data.geojson "" data/nexus_data.geojson "" data/refactored_example_realization_config.json + run: | + docker run --rm -i --mount type=bind,source="$(pwd)"/data,target=/ngen_build/data,readonly \ + localbuild/ngen:latest \ + ./ngen data/catchment_data.geojson '' data/nexus_data.geojson '' data/example_realization_config.json diff --git a/.github/workflows/module_integration.yml b/.github/workflows/module_integration.yml index e9b06cf04c..8142a45e08 100644 --- a/.github/workflows/module_integration.yml +++ b/.github/workflows/module_integration.yml @@ -31,46 +31,11 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 - - name: Build Surfacebmi - id: submod_build_1 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: " extern/noah-owp-modular/" - targets: "surfacebmi" - - - name: Build ISO C Fortran BMI - id: submod_build_2 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/iso_c_fortran_bmi/" - - - name: Build CFE - id: submod_build_3 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/cfe/" - targets: "cfebmi" - - - name: Build PET - id: submod_build_5 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/evapotranspiration/evapotranspiration" - targets: "petbmi" - - - name: Build SLoTH - id: submod_build_6 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/sloth/" - targets: "slothmodel" - - - name: Build Ngen + - name: Build NGen uses: ./.github/actions/ngen-build with: targets: "ngen" build-cores: ${{ env.LINUX_NUM_PROC_CORES }} - #is this required for this test? bmi_c: 'ON' bmi_fortran: 'ON' timeout-minutes: 15 diff --git a/.github/workflows/test_and_validate.yml b/.github/workflows/test_and_validate.yml index acccc9d6d4..733ea1fca4 100644 --- a/.github/workflows/test_and_validate.yml +++ b/.github/workflows/test_and_validate.yml @@ -68,17 +68,11 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 - - name: Build PET Submodule - id: submod_build_5 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/evapotranspiration/evapotranspiration" - targets: "petbmi" - - name: Build PET Tests uses: ./.github/actions/ngen-build with: targets: "compare_pet" + bmi_c: on build-cores: ${{ env.LINUX_NUM_PROC_CORES }} - name: Run Tests @@ -136,13 +130,6 @@ jobs: with: mod-dir: "extern/bmi-cxx/" - - name: Build Submodules - id: submod_build - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/test_bmi_cpp/" - targets: "testbmicppmodel" - - name: Build Unit Tests uses: ./.github/actions/ngen-build with: @@ -159,11 +146,6 @@ jobs: - name: Clean Up Unit Test Build uses: ./.github/actions/clean-build - - name: Clean Up Submodule Build - uses: ./.github/actions/clean-build - with: - build-dir: ${{ steps.submod_build.outputs.build-dir }} - # Run BMI C tests in linux environment, and separating to isolate test_bmi_c: # The type of runner that the job will run on @@ -178,13 +160,6 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 - - name: Build Submodules - id: submod_build - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/test_bmi_c" - targets: "testbmicmodel" - - name: Build Unit Tests uses: ./.github/actions/ngen-build with: @@ -204,11 +179,6 @@ jobs: - name: Clean Up Unit Test Build uses: ./.github/actions/clean-build - - name: Clean Up Submodule Build - uses: ./.github/actions/clean-build - with: - build-dir: ${{ steps.submod_build.outputs.build-dir }} - # As with the BMI C ubuntu job, separate Fortran in linux tests to keep setups clean and cause of failures clear. test_bmi_fortran: # The type of runner that the job will run on @@ -223,18 +193,6 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 - - name: Build Submodules - id: submod_build_1 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/test_bmi_fortran/" - - - name: Build Submodules - id: submod_build_2 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/iso_c_fortran_bmi/" - - name: Build Unit Tests uses: ./.github/actions/ngen-build with: @@ -254,15 +212,6 @@ jobs: - name: Clean Up Unit Test Build uses: ./.github/actions/clean-build - - name: Clean Up Submodule Build - uses: ./.github/actions/clean-build - with: - build-dir: ${{ steps.submod_build_1.outputs.build-dir }} - - - uses: ./.github/actions/clean-build - with: - build-dir: ${{ steps.submod_build_2.outputs.build-dir }} - # As with the BMI C ubuntu job, separate Python in linux tests to keep setups clean and cause of failures clear. test_bmi_python: # The type of runner that the job will run on @@ -312,37 +261,6 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 - - name: Build Submodules - id: submod_build_1 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/test_bmi_fortran/" - - - name: Build Submodules - id: submod_build_2 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/iso_c_fortran_bmi/" - - - name: Build Submodules - id: submod_build_3 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/test_bmi_c/" - targets: "testbmicmodel" - - #make sure cxx bmi is initialized/ready - - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/bmi-cxx/" - - - name: Build Submodules - id: submod_build_4 - uses: ./.github/actions/ngen-submod-build - with: - mod-dir: "extern/test_bmi_cpp/" - targets: "testbmicppmodel" - - name: Build Unit Tests uses: ./.github/actions/ngen-build with: @@ -362,20 +280,6 @@ jobs: - name: Clean Up Unit Test Build uses: ./.github/actions/clean-build - - name: Clean Up Submodule Build - uses: ./.github/actions/clean-build - with: - build-dir: ${{ steps.submod_build_1.outputs.build-dir }} - - uses: ./.github/actions/clean-build - with: - build-dir: ${{ steps.submod_build_2.outputs.build-dir }} - - uses: ./.github/actions/clean-build - with: - build-dir: ${{ steps.submod_build_3.outputs.build-dir }} - - uses: ./.github/actions/clean-build - with: - build-dir: ${{ steps.submod_build_4.outputs.build-dir }} - # TODO: fails due to compilation error, at least in large part due to use of POSIX functions not supported on Windows. # TODO: Need to determine whether Windows support (in particular, development environment support) is necessary. diff --git a/CMakeLists.txt b/CMakeLists.txt index eb5895c6f6..359d411080 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,11 @@ list(APPEND CMAKE_MODULE_PATH "${NGEN_MOD_DIR}") # (3) Function `git_update_submodule` which updates a given submodule include(GitUpdateSubmodules) +# NGen CMake module for automating external subdirectory builds (i.e. testbmicpp) +# Provides: +# (1) add_external_subdirectory() +include(ExternalSubdirectory) + # Options ===================================================================== include(CMakeDependentOption) @@ -64,7 +69,41 @@ deprecated_option(OLD NETCDF_ACTIVE NEW NGEN_WITH_NETCDF) deprecated_option(OLD BMI_C_LIB_ACTIVE NEW NGEN_WITH_BMI_C) deprecated_option(OLD BMI_FORTRAN_ACTIVE NEW NGEN_WITH_BMI_FORTRAN) deprecated_option(OLD QUIET NEW NGEN_QUIET) -deprecated_option(OLD PACKAGE_TESTS NEW NGEN_WITH_TESTS) + +# Options to automate building of extern-distributed models +option(NGEN_WITH_EXTERN_SLOTH "Build with extern-distributed SLoTH" ON) +cmake_dependent_option(NGEN_WITH_EXTERN_TOPMODEL "Build with extern-distributed TOPMODEL" ON "NGEN_WITH_BMI_C" OFF) +cmake_dependent_option(NGEN_WITH_EXTERN_CFE "Build with extern-distributed CFE" ON "NGEN_WITH_BMI_C" OFF) +cmake_dependent_option(NGEN_WITH_EXTERN_PET "Build with extern-distributed PET" ON "NGEN_WITH_BMI_C" OFF) +cmake_dependent_option(NGEN_WITH_EXTERN_NOAH_OWP_MODULAR "Build with extern-distributed Noah-OWP-Modular" ON "NGEN_WITH_BMI_FORTRAN" OFF) + +# Allow enabling of all extern models dependent on NGen options given. +option(NGEN_WITH_EXTERN_ALL OFF) +if(NGEN_WITH_EXTERN_ALL) + set(NGEN_WITH_EXTERN_SLOTH ON) + + # Ensure C support is enabled + if(NGEN_WITH_BMI_C) + set(NGEN_WITH_EXTERN_TOPMODEL ON) + set(NGEN_WITH_EXTERN_CFE ON) + set(NGEN_WITH_EXTERN_PET ON) + else() + message(FATAL_ERROR "NGEN_WITH_EXTERN_ALL set to ${NGEN_WITH_EXTERN_ALL}, but NGEN_WITH_BMI_C set to ${NGEN_WITH_BMI_C}") + endif() + + # Ensure Fortran support is enabled + if(NGEN_WITH_BMI_FORTRAN) + set(NGEN_WITH_EXTERN_NOAH_OWP_MODULAR ON) + else() + message(FATAL_ERROR "NGEN_WITH_EXTERN_ALL set to ${NGEN_WITH_EXTERN_ALL}, but NGEN_WITH_BMI_FORTRAN set to ${NGEN_WITH_BMI_FORTRAN}") + endif() + + # Ensure Python support is enabled + if(NOT NGEN_WITH_PYTHON) + message(FATAL_ERROR "NGEN_WITH_EXTERN_ALL set to ${NGEN_WITH_EXTERN_ALL}, but NGEN_WITH_PYTHON set to ${NGEN_WITH_PYTHON}") + endif() +endif() + # Project ===================================================================== # ----------------------------------------------------------------------------- @@ -150,17 +189,71 @@ if(NGEN_WITH_NETCDF) add_compile_definitions(NETCDF_ACTIVE) endif() +if(NGEN_WITH_EXTERN_SLOTH) + # This is set because SLOTH will link to gtest by default, + # which causes a configure error. + set(PACKAGE_TESTS OFF CACHE BOOL "SLoTH testing") + add_external_subdirectory( + SOURCE "${NGEN_EXT_DIR}/sloth" + OUTPUT "${NGEN_EXT_DIR}/sloth/cmake_build" + GIT_UPDATE "${NGEN_EXT_DIR}/sloth" + IMPORTS slothmodel + ) + set_target_properties(slothmodel PROPERTIES CXX_VISIBILITY_PRESET default) +endif() + # ----------------------------------------------------------------------------- # Handle several steps for BMI C library logic and dependencies, at top level, if functionality is turned on if(NGEN_WITH_BMI_C) add_compile_definitions(NGEN_BMI_C_LIB_ACTIVE) + + if(NGEN_WITH_EXTERN_TOPMODEL) + add_external_subdirectory( + SOURCE "${NGEN_EXT_DIR}/topmodel" + OUTPUT "${NGEN_EXT_DIR}/topmodel/cmake_build" + GIT_UPDATE "${NGEN_EXT_DIR}/topmodel/topmodel" + IMPORTS topmodelbmi + ) + endif() + + if(NGEN_WITH_EXTERN_CFE) + add_external_subdirectory( + SOURCE "${NGEN_EXT_DIR}/cfe" + OUTPUT "${NGEN_EXT_DIR}/cfe/cmake_build" + GIT_UPDATE "${NGEN_EXT_DIR}/cfe/cfe" + IMPORTS cfebmi + ) + endif() + + if(NGEN_WITH_EXTERN_PET) + add_external_subdirectory( + SOURCE "${NGEN_EXT_DIR}/evapotranspiration/evapotranspiration" + OUTPUT "${NGEN_EXT_DIR}/evapotranspiration/evapotranspiration/cmake_build" + GIT_UPDATE "${NGEN_EXT_DIR}/evapotranspiration/evapotranspiration" + IMPORTS petbmi + ) + endif() endif() # ----------------------------------------------------------------------------- # Configure whether Fortran BMI functionality is active if(NGEN_WITH_BMI_FORTRAN) add_compile_definitions(NGEN_BMI_FORTRAN_ACTIVE) - find_package(BMI_FORTRAN_ISO_C REQUIRED) + + add_external_subdirectory( + SOURCE "${NGEN_EXT_DIR}/iso_c_fortran_bmi" + OUTPUT "${NGEN_EXT_DIR}/iso_c_fortran_bmi/cmake_build" + IMPORTS iso_c_bmi + ) + + if(NGEN_WITH_EXTERN_NOAH_OWP_MODULAR) + add_external_subdirectory( + SOURCE "${NGEN_EXT_DIR}/noah-owp-modular" + OUTPUT "${NGEN_EXT_DIR}/noah-owp-modular/cmake_build" + GIT_UPDATE "${NGEN_EXT_DIR}/noah-owp-modular/noah-owp-modular" + IMPORTS surfacebmi + ) + endif() endif() # ----------------------------------------------------------------------------- @@ -196,6 +289,26 @@ add_library(ngen_config_header INTERFACE) add_library(NGen::config_header ALIAS ngen_config_header) target_include_directories(ngen_config_header INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/include") +if(NGEN_WITH_EXTERN_SLOTH) + add_dependencies(ngen slothmodel) +endif() + +if(NGEN_WITH_EXTERN_TOPMODEL) + add_dependencies(ngen topmodelbmi) +endif() + +if(NGEN_WITH_EXTERN_CFE) + add_dependencies(ngen cfebmi) +endif() + +if(NGEN_WITH_EXTERN_PET) + add_dependencies(ngen petbmi) +endif() + +if(NGEN_WITH_EXTERN_NOAH_OWP_MODULAR) + add_dependencies(ngen surfacebmi) +endif() + target_include_directories(ngen PUBLIC "${NGEN_INC_DIR}") add_subdirectory("src/core") @@ -290,7 +403,9 @@ ngen_multiline_message( " Build type: ${CMAKE_BUILD_TYPE}" " System: ${CMAKE_SYSTEM_NAME}" " C Compiler: ${CMAKE_C_COMPILER}" +" C Flags: ${CMAKE_C_FLAGS}" " CXX Compiler: ${CMAKE_CXX_COMPILER}" +" CXX Flags: ${CMAKE_CXX_FLAGS}" " Flags:" " NGEN_WITH_MPI: ${NGEN_WITH_MPI}" " NGEN_WITH_NETCDF: ${NGEN_WITH_NETCDF}" @@ -301,7 +416,15 @@ ngen_multiline_message( " NGEN_WITH_PYTHON: ${NGEN_WITH_PYTHON}" " NGEN_WITH_ROUTING: ${NGEN_WITH_ROUTING}" " NGEN_WITH_TESTS: ${NGEN_WITH_TESTS}" +" NGEN_WITH_COVERAGE: ${NGEN_WITH_COVERAGE}" " NGEN_QUIET: ${NGEN_QUIET}" +" Extern Models:" +" NGEN_WITH_EXTERN_ALL: ${NGEN_WITH_EXTERN_ALL}" +" NGEN_WITH_EXTERN_SLOTH: ${NGEN_WITH_EXTERN_SLOTH}" +" NGEN_WITH_EXTERN_TOPMODEL: ${NGEN_WITH_EXTERN_TOPMODEL}" +" NGEN_WITH_EXTERN_CFE: ${NGEN_WITH_EXTERN_CFE}" +" NGEN_WITH_EXTERN_PET: ${NGEN_WITH_EXTERN_PET}" +" NGEN_WITH_EXTERN_NOAH_OWP_MODULAR: ${NGEN_WITH_EXTERN_NOAH_OWP_MODULAR}" "Environment summary:" " Boost:" " Version: ${Boost_VERSION}" diff --git a/cmake/ExternalSubdirectory.cmake b/cmake/ExternalSubdirectory.cmake new file mode 100644 index 0000000000..9e16c3aa84 --- /dev/null +++ b/cmake/ExternalSubdirectory.cmake @@ -0,0 +1,27 @@ +include(GitUpdateSubmodules) + +# Add an external subdirectory to build +function(add_external_subdirectory) + set(options "") + set(oneValueArgs SOURCE OUTPUT GIT_UPDATE IMPORTS) + set(multiValueArgs "") + cmake_parse_arguments(EXTERNAL_TARGET + "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN}) + + if(NGEN_UPDATE_GIT_SUBMODULES AND EXTERNAL_TARGET_GIT_UPDATE) + git_update_submodule("${EXTERNAL_TARGET_GIT_UPDATE}") + endif() + + if(EXTERNAL_TARGET_OUTPUT STREQUAL "") + add_subdirectory("${EXTERNAL_TARGET_SOURCE}") + else() + add_subdirectory("${EXTERNAL_TARGET_SOURCE}" "${EXTERNAL_TARGET_OUTPUT}") + endif() + + if(EXTERNAL_TARGET_IMPORTS STREQUAL "") + if(NOT TARGET ${EXTERNAL_TARGET_IMPORTS}) + message(FATAL_ERROR "Target `${EXTERNAL_TARGET_IMPORTS}` could not be found from subdirectory ${EXTERNAL_TARGET_SOURCE}") + endif() + endif() +endfunction() diff --git a/cmake/FindBMI_FORTRAN_ISO_C.cmake b/cmake/FindBMI_FORTRAN_ISO_C.cmake deleted file mode 100644 index 48d2a0e435..0000000000 --- a/cmake/FindBMI_FORTRAN_ISO_C.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# Searches for ISO C BMI library, defaults to -# known development directories in the event the BMI_FORTRAN_ISO_C_* -# variables are not set. -find_library(BMI_FORTRAN_ISO_C_LIB_PATH - NAMES - "${BMI_FORTRAN_ISO_C_LIB_NAME}" - "iso_c_bmi" - HINTS # Searched before paths - "${BMI_FORTRAN_ISO_C_LIB_DIR}" - PATHS - ENV BMI_FORTRAN_ISO_C_LIB_DIR - "${NGEN_ROOT_DIR}/extern/iso_c_fortran_bmi/cmake_build" - "${NGEN_ROOT_DIR}/extern/iso_c_fortran_bmi/build" - DOC "Path to middleware Fortran shared lib handling iso_c_binding" -) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(BMI_FORTRAN_ISO_C DEFAULT_MSG BMI_FORTRAN_ISO_C_LIB_PATH) - -if(BMI_FORTRAN_ISO_C_FOUND) - add_library(bmi_fortran_iso_c SHARED IMPORTED) - set_target_properties(bmi_fortran_iso_c PROPERTIES IMPORTED_LOCATION "${BMI_FORTRAN_ISO_C_LIB_PATH}") -endif() diff --git a/cmake/GitUpdateSubmodules.cmake b/cmake/GitUpdateSubmodules.cmake index d9ec78f38f..9bc833c9c0 100644 --- a/cmake/GitUpdateSubmodules.cmake +++ b/cmake/GitUpdateSubmodules.cmake @@ -9,7 +9,7 @@ endif() function(git_update_submodule PATH) if(NGEN_UPDATE_GIT_SUBMODULES) message(STATUS "Updating submodule ${PATH}") - execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init -- ${PATH} + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive -- ${PATH} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE GIT_SUBMOD_RESULT ) diff --git a/cmake/NGenModules.cmake b/cmake/NGenModules.cmake new file mode 100644 index 0000000000..3c69e37c35 --- /dev/null +++ b/cmake/NGenModules.cmake @@ -0,0 +1,19 @@ +# Add a fortran library to the project. Exhibits same behavior of `add_library()`, +# with the exception of setting the Fortran module directory, and including it +# on the target with an INTERFACE scope. +# +# add_fortran_library( [STATIC | SHARED | MODULE] +# [EXCLUDE_FROM_ALL] [...]) +# +# A target ```` is created after calling this function, and +# normal target functions, i.e. `target_sources()`, can be used on it. +function(add_fortran_library libname) + add_library(${libname} ${ARGN}) + get_target_property(_binary_dir ${libname} BINARY_DIR) + set_target_properties(${libname} + PROPERTIES + Fortran_MODULE_DIRECTORY ${_binary_dir}/mod) + target_include_directories(${libname} + INTERFACE + "${_binary_dir}/mod") +endfunction() diff --git a/docker/ngen.dockerfile b/docker/ngen.dockerfile new file mode 100644 index 0000000000..88d880b98f --- /dev/null +++ b/docker/ngen.dockerfile @@ -0,0 +1,44 @@ +ARG ROCKYLINUX_TAG=8 +FROM rockylinux:${ROCKYLINUX_TAG} + +RUN dnf update -y \ + && dnf install -y dnf-plugins-core epel-release \ + && dnf repolist \ + && dnf install -y --allowerasing tar git gcc-c++ gcc make cmake udunits2-devel coreutils \ + && dnf clean all + +ARG BOOST_VERSION="1.79.0" +RUN export BOOST_ARCHIVE="boost_$(echo ${BOOST_VERSION} | tr '\.' '_').tar.gz" \ + && export BOOST_URL="https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/${BOOST_ARCHIVE}/download" \ + && cd / \ + && curl -L -o "${BOOST_ARCHIVE}" "${BOOST_URL}" \ + && tar -xzf "${BOOST_ARCHIVE}" \ + && rm ${BOOST_ARCHIVE} + +COPY . /ngen +WORKDIR /ngen +RUN git submodule update --init --recursive -- test/googletest +RUN git submodule update --init --recursive -- extern/pybind11 + +RUN cmake -S . \ + -B /ngen_build \ + -DBOOST_ROOT="/boost_$(echo ${BOOST_VERSION} | tr '\.' '_')" \ + -DBoost_NO_BOOST_CMAKE:BOOL=TRUE \ + -DNGEN_WITH_MPI:BOOL=OFF \ + -DNGEN_WITH_NETCDF:BOOL=OFF \ + -DNGEN_WITH_SQLITE:BOOL=OFF \ + -DNGEN_WITH_UDUNITS:BOOL=ON \ + -DNGEN_WITH_BMI_FORTRAN:BOOL=OFF \ + -DNGEN_WITH_BMI_C:BOOL=OFF \ + -DNGEN_WITH_PYTHON:BOOL=OFF \ + -DNGEN_WITH_TESTS:BOOL=ON \ + -DNGEN_QUIET:BOOL=ON \ + -DNGEN_WITH_EXTERN_SLOTH:BOOL=ON + +RUN cmake --build /ngen_build \ + --target testbmicppmodel ngen \ + -- \ + -j $(nproc) + +WORKDIR /ngen_build +CMD ["./ngen"] diff --git a/docker/ngen.dockerfile.dockerignore b/docker/ngen.dockerfile.dockerignore new file mode 100644 index 0000000000..ba108a1d72 --- /dev/null +++ b/docker/ngen.dockerfile.dockerignore @@ -0,0 +1,10 @@ +* +!.git/ +!.gitmodules +!cmake/ +!extern/ +!include/ +!src/ +!test/ +test/data +!CMakeLists.txt diff --git a/extern/iso_c_fortran_bmi/CMakeLists.txt b/extern/iso_c_fortran_bmi/CMakeLists.txt index 55c6ca1b30..b55642e83f 100644 --- a/extern/iso_c_fortran_bmi/CMakeLists.txt +++ b/extern/iso_c_fortran_bmi/CMakeLists.txt @@ -1,49 +1,37 @@ -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.12...3.26) -project(iso_c_fortran_bmi VERSION 1.0.0 DESCRIPTION "Shared library for ISO_C_BINDING Fortran Libraries implementing BMI") +# NGen iso_c_fortran_bmi listfile shim +# +# Requires: +# - NGEN_WITH_BMI_FORTRAN=ON +# +# Output Targets: +# - `iso_c_bmi` -enable_language( Fortran ) +project(iso_c_fortran_bmi VERSION 1.0.0 LANGUAGES Fortran) -# https://www.intel.com/content/www/us/en/develop/documentation/oneapi-dpcpp-cpp-compiler-dev-guide-and-reference/top/compiler-setup/use-the-command-line/use-cmake-with-the-compiler.html -if (INTEL_DPCPP) - cmake_minimum_required(VERSION 3.20) - find_package(IntelDPCPP REQUIRED) -endif() +set(_source_dir "${CMAKE_CURRENT_LIST_DIR}") -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../cmake/") -# Uncomment this and rebuild artifacts to enable debugging -#set(CMAKE_BUILD_TYPE Debug) -add_compile_options( - "-Wall" - "$<$:-g;-fbacktrace;-fbounds-check>" -) +add_library(iso_c_bmi SHARED) +file(GLOB _ISO_C_BMI_OBJECTS CONFIGURE_DEPENDS "${_source_dir}/src/*.f90") +get_target_property(_ISO_C_BMI_BINARY_DIR iso_c_bmi BINARY_DIR) +set_target_properties(iso_c_bmi + PROPERTIES + Fortran_MODULE_DIRECTORY "${_ISO_C_BMI_BINARY_DIR}/mod") -set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran) -#### Add variables for individual libraries that are used withing the *.pc.in files -set(SOURCE_DIR src/) -file( GLOB SOURCES ${SOURCE_DIR}*.f90) +target_sources(iso_c_bmi PRIVATE ${_ISO_C_BMI_OBJECTS}) +target_compile_options(iso_c_bmi PRIVATE -cpp -ffree-line-length-none) +target_include_directories(iso_c_bmi INTERFACE "${_ISO_C_BMI_BINARY_DIR}/mod") -if(WIN32) - add_library(iso_c_bmi ${SOURCES} ) -else() - add_library(iso_c_bmi SHARED ${SOURCES} ) - #add_library(iso_c_bmi_a STATIC ${SOURCES} ) -endif() - -target_compile_options(iso_c_bmi PUBLIC -cpp -ffree-line-length-none) -#ensure relocatable object -set_property(TARGET iso_c_bmi PROPERTY POSITION_INDEPENDENT_CODE ON) - -set_target_properties(iso_c_bmi PROPERTIES VERSION ${PROJECT_VERSION}) +unset(_ISO_C_BMI_BINARY_DIR) +unset(_ISO_C_BMI_OBJECTS) include(GNUInstallDirs) - install(TARGETS iso_c_bmi LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - -install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - +install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) configure_file(iso_c_bmi.pc.in iso_c_bmi.pc @ONLY) - -install(FILES ${CMAKE_BINARY_DIR}/iso_c_bmi.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig) +install(FILES ${CMAKE_BINARY_DIR}/iso_c_bmi.pc + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig) diff --git a/extern/noah-owp-modular/CMakeLists.txt b/extern/noah-owp-modular/CMakeLists.txt index 161f4e8a5a..c4515f23ff 100644 --- a/extern/noah-owp-modular/CMakeLists.txt +++ b/extern/noah-owp-modular/CMakeLists.txt @@ -1,105 +1,66 @@ -cmake_minimum_required(VERSION 3.12) -enable_language( Fortran ) -add_subdirectory(../iso_c_fortran_bmi ${CMAKE_BINARY_DIR}/iso_c_bmi) +cmake_minimum_required(VERSION 3.12...3.26) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../cmake/") -# Uncomment this and rebuild artifacts to enable debugging -#set(CMAKE_BUILD_TYPE Debug) -add_compile_options( - "-Wall" - "$<$:-g;-fbacktrace;-fbounds-check>" -) -project(noah-owp-modular VERSION 1.0.0 DESCRIPTION "External BMI Models Shared Libraries") - -# https://www.intel.com/content/www/us/en/develop/documentation/oneapi-dpcpp-cpp-compiler-dev-guide-and-reference/top/compiler-setup/use-the-command-line/use-cmake-with-the-compiler.html -if (INTEL_DPCPP) - cmake_minimum_required(VERSION 3.20) - find_package(IntelDPCPP REQUIRED) -endif() - -set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran) - -#### Add variables for individual libraries that are used withing the *.pc.in files -# Surface -set(SURFACE_LIB_NAME_CMAKE surfacebmi) -set(SURFACE_LIB_DESC_CMAKE "External Noah-OWP-Modular Surface Shared Library") - -# Make sure these are compiled with this directive -add_compile_definitions(BMI_ACTIVE NGEN_FORCING_ACTIVE NGEN_OUTPUT_ACTIVE NGEN_ACTIVE) - -#Use ../../../FindNetCDF.cmake, which looks for config package, pkgconfig, and standard file locations -#in that order -###### -# Updates to noah-owp-modular allow a build of the bmi module that does not require netcdf -# The NGEN_OUTPUT_ACTIVE compiler directive disables all netcdf related code, hence no need -# to link the netcdf library. If at some point this becomes required, the following section -# can be uncommented to provide mechanics to look for and/or define netcdf requirements. -# Also, the target link library line will need uncommeted below. -###### -###### NETCDF ###### -# find_package (NetCDF COMPONENTS F90) -# set(netCDF_INCLUDE_DIR ${NetCDF_INCLUDE_DIRS} CACHE PATH "NetCDF Include Directory" ) -# set(netCDF_C_LIB ${NetCDF_LIBRARIES} CACHE PATH -# "The path to the C shared object library file, libnetcdf.so or the library name if it can be found by the linker, i.e. netcdf" ) -# if(NetCDF_FOUND) -# #This provides a little diagnostic output, but most importantly, gives cache varabiles -# #for each piece of the netcdf puzzle that a user might need to directly override -# #if netcdf isn't configured correctly or cannot be found using the known methods. -# message("Found netCDF package") -# message("NetCDF inc: " ${NetCDF_INCLUDE_DIR}) -# message("NetCDF lib: " ${NetCDF_LIBRARIES}) -# else() -# message(SEND_ERROR "Could not find NetCDF, install the depdency or\n 1) Set the NetCDF_DIR to a source build\n 2) set the netCDF* cache variables as appropriate") -# endif() -# # Ensure we can find the netcdf.mod file, leave a cache var that can be set if we can't -# find_path(_netCDF_MOD_PATH "netcdf.mod" ${netCDF_INCLUDE_DIR} REQUIRED NO_CACHE) -# set(netCDF_MOD_PATH ${_netCDF_MOD_PATH} CACHE PATH "Directory containing the netcdf.mod fortran module") +# NGen NOAH-OWP-MODULAR listfile shim # -# # For some reason the netcdf config.cmake doesn't set the netcdff lib correctly in -# # ${netCDF_Libararies}, so it only links the C lib (netcdf) and not the fortran lib (netcdff) -# # So find that library explicitly and make sure we link with it. -# # also, the FindNetCDF.cmake doesn't seem to do it correctly either. -# find_library(_netCDF_FORTRAN_LIB netcdff REQUIRED NO_CACHE) -# set(netCDF_FORTRAN_LIB ${_netCDF_FORTRAN_LIB} CACHE PATH -# "The path to the C shared object library file, libnetcdff.so or the library name if it can be found by the linker, i.e. netcdff") -##### END NETCDF ##### - -set(MODEL_SOURCE_DIR noah-owp-modular/src/) -set(BMI_SOURCE_DIR noah-owp-modular/bmi/) - -file(GLOB BMI_SOURCE ${BMI_SOURCE_DIR}*.f90) -file( GLOB MODEL_SOURCES ${MODEL_SOURCE_DIR}*.f90) - -list(APPEND MODEL_SOURCES noah-owp-modular/driver/AsciiReadModule.f90 - noah-owp-modular/driver/OutputModule.f90) - -if(WIN32) - add_library(surfacebmi ${BMI_SOURCE} ) +# Requires: +# - NGEN_WITH_BMI_FORTRAN=ON +# +# Output Targets: +# - `surfacebmi` + +project(noah-owp-modular VERSION 1.0.0 LANGUAGES Fortran) + +set(_source_dir "${CMAKE_CURRENT_LIST_DIR}/noah-owp-modular") + +add_library(surfacebmi SHARED) +file(GLOB _SURFACEBMI_OBJECTS CONFIGURE_DEPENDS + "${_source_dir}/src/*.f90" + "${_source_dir}/bmi/*.f90" + "${_source_dir}/driver/*.f90") +get_target_property(_SURFACEBMI_BINARY_DIR surfacebmi BINARY_DIR) +set_target_properties(surfacebmi + PROPERTIES + Fortran_MODULE_DIRECTORY "${_SURFACEBMI_BINARY_DIR}/mod") + +target_sources(surfacebmi PRIVATE ${_SURFACEBMI_OBJECTS}) +target_compile_options(surfacebmi PRIVATE -cpp -ffree-line-length-none) +target_include_directories(surfacebmi INTERFACE "${_SURFACEBMI_BINARY_DIR}/mod") +target_compile_definitions(surfacebmi PRIVATE BMI_ACTIVE) + +if(NGEN_IS_MAIN_PROJECT) + target_link_libraries(surfacebmi PUBLIC iso_c_bmi) + target_compile_definitions(surfacebmi PRIVATE NGEN_FORCING_ACTIVE NGEN_OUTPUT_ACTIVE NGEN_ACTIVE) else() - add_library(surfacebmi SHARED ${BMI_SOURCE} ${MODEL_SOURCES} ) - #add_library(surfacebmi_a STATIC ${BMI_SOURCE}) + find_path(NETCDF_MODULE_DIR netcdf.mod + PATHS "${NETCDF_ROOT}/include" + REQUIRED) + mark_as_advanced(NETCDF_MODULE_DIR) + + find_library(NETCDF_LIBRARY NAMES netcdff + PATHS "${NETCDF_ROOT}/lib" + REQUIRED) + mark_as_advanced(NETCDF_LIBRARY) + + find_program(_NFCONFIG nf-config) + if(_NFCONFIG) + execute_process( + COMMAND ${_NFCONFIG} "--version" + OUTPUT_VARIABLE _NFVERSION) + string(STRIP "${_NFVERSION}" NETCDF_VERSION) + message(${NETCDF_VERSION}) + endif() + + target_include_directories(surfacebmi PUBLIC "${NETCDF_MODULE_DIR}") + target_link_libraries(surfacebmi PUBLIC "${NETCDF_LIBRARY}") endif() -target_include_directories(surfacebmi PUBLIC ${netCDF_INCLUDE_DIR} ${netCDF_MOD_PATH}) -#We know we are building this for NGEN support, so define the preprocessor directive in the compile options -#Not sure why the global -target_compile_options(surfacebmi PUBLIC -cpp -ffree-line-length-none) - -##### NETCDF ##### -#target_link_libraries( surfacebmi iso_c_bmi ${netCDF_C_LIB} ${netCDF_FORTRAN_LIB}) -##### END NETCDF ##### -target_link_libraries( surfacebmi PUBLIC iso_c_bmi ) -set_target_properties(surfacebmi PROPERTIES VERSION ${PROJECT_VERSION}) - -#TODO is this needed for fortran? -#set_target_properties(surfacebmi PROPERTIES PUBLIC_HEADER ${BMI_SOURCE}) +unset(_SURFACEBMI_BINARY_DIR) +unset(_SURFACEBMI_OBJECTS) include(GNUInstallDirs) - install(TARGETS surfacebmi LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - configure_file(surfacebmi.pc.in surfacebmi.pc @ONLY) - -install(FILES ${CMAKE_BINARY_DIR}/surfacebmi.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig) +install(FILES ${CMAKE_BINARY_DIR}/surfacebmi.pc + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig) diff --git a/extern/test_bmi_fortran/CMakeLists.txt b/extern/test_bmi_fortran/CMakeLists.txt index 0afa4e7232..ff8a02681e 100644 --- a/extern/test_bmi_fortran/CMakeLists.txt +++ b/extern/test_bmi_fortran/CMakeLists.txt @@ -1,50 +1,30 @@ -cmake_minimum_required(VERSION 3.10) - -project(testbmifortranmodel VERSION 1.0.0 DESCRIPTION "BMI Fortran Testing Model Shared Library") - -enable_language( Fortran ) - -# https://www.intel.com/content/www/us/en/develop/documentation/oneapi-dpcpp-cpp-compiler-dev-guide-and-reference/top/compiler-setup/use-the-command-line/use-cmake-with-the-compiler.html -if (INTEL_DPCPP) - cmake_minimum_required(VERSION 3.20) - find_package(IntelDPCPP REQUIRED) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -traceback -check all -debug all -mcmodel=medium -shared-intel") -else() - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -fbacktrace -fbounds-check -Wall") -endif() - - -add_subdirectory(../iso_c_fortran_bmi ${CMAKE_BINARY_DIR}/iso_c_bmi) -#Get the iso_c_fortran binding module to build as part of this build -#add_subdirectory(../iso_c_fortran_bmi ${CMAKE_BINARY_DIR}/iso_c_bmi) - -# Uncomment this and rebuild artifacts to enable debugging -set(CMAKE_BUILD_TYPE Debug) - -set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran) - -file(GLOB SOURCES src/*.f90) #TODO why does this not pick up new modules/src files after initial configuration? - -if(WIN32) - add_library(testbmifortranmodel ${SOURCES}) -else() - add_library(testbmifortranmodel SHARED ${SOURCES} ) -endif() - +cmake_minimum_required(VERSION 3.12...3.26) + +project(testbmifortranmodel + VERSION 1.0.0 + DESCRIPTION "BMI Fortran Testing Model Shared Library" + LANGUAGES Fortran) + +add_library(testbmifortranmodel SHARED) +file(GLOB _TESTBMIFORTRAN_OBJECTS CONFIGURE_DEPENDS "${CMAKE_CURRENT_LIST_DIR}/src/*.f90") +get_target_property(_TESTBMIFORTRAN_BINARY_DIR testbmifortranmodel BINARY_DIR) +set_target_properties(testbmifortranmodel + PROPERTIES + Fortran_MODULE_DIRECTORY "${_TESTBMIFORTRAN_BINARY_DIR}/mod") + +target_sources(testbmifortranmodel PRIVATE ${_TESTBMIFORTRAN_OBJECTS}) +target_compile_options(testbmifortranmodel PRIVATE -cpp -ffree-line-length-none) +target_compile_definitions(testbmifortranmodel PRIVATE NGEN_ACTIVE) +target_include_directories(testbmifortranmodel INTERFACE "${_TESTBMIFORTRAN_BINARY_DIR}/mod") target_link_libraries(testbmifortranmodel PUBLIC iso_c_bmi) -target_compile_options(testbmifortranmodel PUBLIC -cpp -DNGEN_ACTIVE) -#target_include_directories(testbmifortranmodel PRIVATE include) - -set_target_properties(testbmifortranmodel PROPERTIES VERSION ${PROJECT_VERSION}) -#set_target_properties(testbmifortranmodel PROPERTIES PUBLIC_HEADER include/bmi_test_bmi_c.h) +unset(_TESTBMIFORTRAN_BINARY_DIR) +unset(_TESTBMIFORTRAN_OBJECTS) include(GNUInstallDirs) - install(TARGETS testbmifortranmodel LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - configure_file(testbmifortranmodel.pc.in testbmifortranmodel.pc @ONLY) - -install(FILES ${CMAKE_BINARY_DIR}/testbmifortranmodel.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig) +install(FILES ${CMAKE_BINARY_DIR}/testbmifortranmodel.pc + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig) diff --git a/src/bmi/CMakeLists.txt b/src/bmi/CMakeLists.txt index 04975c041d..823a54cd3f 100644 --- a/src/bmi/CMakeLists.txt +++ b/src/bmi/CMakeLists.txt @@ -21,5 +21,5 @@ if(NGEN_WITH_PYTHON) endif() if(NGEN_WITH_BMI_FORTRAN) - target_link_libraries(ngen_bmi PUBLIC bmi_fortran_iso_c) + target_link_libraries(ngen_bmi PUBLIC iso_c_bmi) endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 57d06ff500..a6aed84bf0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,12 +1,6 @@ add_subdirectory(googletest) add_compile_definitions(NGEN_BMI_CPP_LIB_TESTS_ACTIVE) -# Natively support BMI C++ modules and pre-compile in the test_bmi_cpp mock/example. -set(TEST_BMI_CPP_DIR ${NGEN_EXT_DIR}/test_bmi_cpp) -git_update_submodule(${NGEN_EXT_DIR}/bmi-cxx) -add_subdirectory(${TEST_BMI_CPP_DIR} ${TEST_BMI_CPP_DIR}/cmake_build) -add_dependencies(ngen testbmicppmodel) - # ============================================================================= # If ${NGEN_ROOT_DIR} and ${PROJECT_BINARY_DIR} are the same, then we have an in-source build @@ -25,6 +19,14 @@ endif() # ============================================================================= +git_update_submodule("${NGEN_EXT_DIR}/bmi-cxx") + +add_external_subdirectory( + SOURCE "${NGEN_EXT_DIR}/test_bmi_cpp" + OUTPUT "${NGEN_EXT_DIR}/test_bmi_cpp/cmake_build" + IMPORTS testbmicppmodel +) + if (NGEN_WITH_PYTHON) add_compile_definitions(NGEN_BMI_PY_TESTS_ACTIVE) endif() @@ -35,10 +37,20 @@ endif() if(NGEN_WITH_BMI_C) add_compile_definitions(NGEN_BMI_C_LIB_TESTS_ACTIVE) + add_external_subdirectory( + SOURCE "${NGEN_EXT_DIR}/test_bmi_c" + OUTPUT "${NGEN_EXT_DIR}/test_bmi_c/cmake_build" + IMPORTS testbmicmodel + ) endif() if(NGEN_WITH_BMI_FORTRAN) add_compile_definitions(NGEN_BMI_FORTRAN_LIB_TESTS_ACTIVE) + add_external_subdirectory( + SOURCE "${NGEN_EXT_DIR}/test_bmi_fortran" + OUTPUT "${NGEN_EXT_DIR}/test_bmi_fortran/cmake_build" + IMPORTS testbmifortranmodel + ) endif() if(NGEN_WITH_ROUTING) @@ -77,7 +89,7 @@ Adds an executable test (i.e. a target) called . the corresponding target is not created. #]==] function(ngen_add_test TESTNAME) - set(multiValueArgs OBJECTS LIBRARIES REQUIRES) + set(multiValueArgs OBJECTS LIBRARIES REQUIRES DEPENDS) cmake_parse_arguments(NGEN_TEST "" "" "${multiValueArgs}" ${ARGN}) list(REMOVE_DUPLICATES NGEN_TEST_LIBRARIES) @@ -95,6 +107,15 @@ function(ngen_add_test TESTNAME) target_include_directories(${TESTNAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/bmi) target_link_libraries(${TESTNAME} PRIVATE gtest gtest_main ${NGEN_TEST_LIBRARIES}) set_target_properties(${TESTNAME} PROPERTIES FOLDER test) + + # Iterate over each dependency, and add as a dependency for the test + # IF the dependency is a target. + foreach(dependency IN LISTS NGEN_TEST_DEPENDS) + if(TARGET ${dependency}) + add_dependencies(${TESTNAME} ${dependency}) + endif() + endforeach() + gtest_discover_tests( ${TESTNAME} WORKING_DIRECTORY ${PROJECT_BINARY_DIR} @@ -147,8 +168,8 @@ ngen_add_test( NGen::core_mediator NGen::forcing NGen::ngen_bmi + DEPENDS testbmicppmodel - ) ########################## Series Unit Tests @@ -236,6 +257,8 @@ ngen_add_test( NGen::core_mediator NGen::forcing NGen::ngen_bmi + DEPENDS + testbmicppmodel ) ########################## BMI C Tests @@ -253,6 +276,8 @@ ngen_add_test( NGen::ngen_bmi REQUIRES NGEN_WITH_BMI_C + DEPENDS + testbmicmodel ) ########################## BMI Fortran Tests @@ -269,6 +294,8 @@ ngen_add_test( NGen::ngen_bmi REQUIRES NGEN_WITH_BMI_FORTRAN + DEPENDS + testbmifortranmodel ) ########################## BMI Python Tests @@ -299,6 +326,14 @@ ngen_add_test( NGen::core_mediator NGen::forcing NGen::ngen_bmi + REQUIRES + NGEN_WITH_BMI_C + NGEN_WITH_BMI_FORTRAN + NGEN_WITH_PYTHON + DEPENDS + testbmicppmodel + testbmicmodel + testbmifortranmodel ) ########################## All BMI Unit Tests @@ -337,6 +372,8 @@ ngen_add_test( NGen::core_mediator NGen::forcing NGen::ngen_bmi + DEPENDS + petbmi ) ########################## Routing Tests