diff --git a/.github/ci-config.yml b/.github/ci-config.yml new file mode 100644 index 00000000..5deb8046 --- /dev/null +++ b/.github/ci-config.yml @@ -0,0 +1,2 @@ +dependency_branch: develop +parallelism_factor: 8 diff --git a/.github/ci-hpc-config.yml b/.github/ci-hpc-config.yml new file mode 100644 index 00000000..777b62e7 --- /dev/null +++ b/.github/ci-hpc-config.yml @@ -0,0 +1,5 @@ +build: + modules: + - ninja + parallel: 64 + diff --git a/.github/workflows/check-release-version.yml b/.github/workflows/check-release-version.yml new file mode 100644 index 00000000..9cff1a75 --- /dev/null +++ b/.github/workflows/check-release-version.yml @@ -0,0 +1,11 @@ +name: Check VERSION file + +on: + push: + branches: + - "release/**" + - "hotfix/**" + +jobs: + check_version: + uses: ecmwf-actions/reusable-workflows/.github/workflows/check-release-version.yml@v2 diff --git a/.github/workflows/ci-single.yml b/.github/workflows/ci-single.yml new file mode 100644 index 00000000..fb6d2c38 --- /dev/null +++ b/.github/workflows/ci-single.yml @@ -0,0 +1,28 @@ +name: ci-single + +# Controls when the workflow will run +on: + + # Trigger the workflow on all pushes, except on tag creation + push: + branches: + - '**' + tags-ignore: + - '**' + + # Trigger the workflow on all pull requests + pull_request: ~ + + # Allow workflow to be dispatched on demand + workflow_dispatch: ~ + +jobs: + + # Calls a reusable CI workflow to build & test the current repository. + # We skip jobs that will result in duplicate artifacts, since the code does not depend on the compiler. + ci: + name: ci + uses: ecmwf-actions/reusable-workflows/.github/workflows/ci.yml@v2 + with: + skip_matrix_jobs: | + clang@rocky-8.6 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45aebfd9..876aefb6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,30 +1,97 @@ name: ci -# Controls when the workflow will run on: - - # Trigger the workflow on all pushes, except on tag creation + # Trigger the workflow on push to master or develop, except tag creation push: branches: - - '**' + - "master" + - "develop" tags-ignore: - - '**' + - "**" + paths-ignore: + - "docs/**" + - "bamboo/**" + - "README.rst" - # Trigger the workflow on all pull requests + # Trigger the workflow on pull request pull_request: ~ - # Allow workflow to be dispatched on demand + # Trigger the workflow manually workflow_dispatch: ~ + # Trigger after public PR approved for CI + pull_request_target: + types: [labeled] + + jobs: + # Run CI including downstream packages on self-hosted runners + downstream-ci: + name: downstream-ci + if: ${{ !github.event.pull_request.head.repo.fork && github.event.action != 'labeled' || github.event.label.name == 'approved-for-ci' }} + uses: ecmwf-actions/downstream-ci/.github/workflows/downstream-ci.yml@main + with: + ecbuild: ecmwf/ecbuild@${{ github.event.pull_request.head.sha || github.sha }} + codecov_upload: false + secrets: inherit - # Calls a reusable CI workflow to build & test the current repository. - # We skip jobs that will result in duplicate artifacts, since the code does not depend on the compiler. - ci: - name: ci - uses: ecmwf-actions/reusable-workflows/.github/workflows/ci.yml@v1 + # Run CI of private downstream packages on self-hosted runners + private-downstream-ci: + name: private-downstream-ci + needs: [downstream-ci] + if: (success() || failure()) && ${{ !github.event.pull_request.head.repo.fork && github.event.action != 'labeled' || github.event.label.name == 'approved-for-ci' }} + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Dispatch private downstream CI + uses: ecmwf-actions/dispatch-private-downstream-ci@v1 + with: + token: ${{ secrets.GH_REPO_READ_TOKEN }} + owner: ecmwf-actions + repository: private-downstream-ci + event_type: downstream-ci + payload: '{"ecbuild": "ecmwf/ecbuild@${{ github.event.pull_request.head.sha || github.sha }}"}' + + # Build downstream packages on HPC + downstream-ci-hpc: + name: downstream-ci-hpc + if: ${{ !github.event.pull_request.head.repo.fork && github.event.action != 'labeled' || github.event.label.name == 'approved-for-ci' }} + uses: ecmwf-actions/downstream-ci/.github/workflows/downstream-ci-hpc.yml@main with: - skip_matrix_jobs: | - clang-12@ubuntu-20.04 - clang-9@ubuntu-18.04 - clang-12@macos-10.15 + ecbuild: ecmwf/ecbuild@${{ github.event.pull_request.head.sha || github.sha }} + secrets: inherit + + # Run CI of private downstream packages on HPC + private-downstream-ci-hpc: + name: private-downstream-ci-hpc + needs: [downstream-ci-hpc] + if: (success() || failure()) && ${{ !github.event.pull_request.head.repo.fork && github.event.action != 'labeled' || github.event.label.name == 'approved-for-ci' }} + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Dispatch private downstream CI + uses: ecmwf-actions/dispatch-private-downstream-ci@v1 + with: + token: ${{ secrets.GH_REPO_READ_TOKEN }} + owner: ecmwf-actions + repository: private-downstream-ci + event_type: downstream-ci-hpc + payload: '{"ecbuild": "ecmwf/ecbuild@${{ github.event.pull_request.head.sha || github.sha }}","skip_matrix_jobs": "nvidia-22.11"}' + +# DISABLED FOR NOW UNTIL REPO IS SET UP FOR THIS +# notify: +# runs-on: ubuntu-latest +# needs: +# - downstream-ci +# - private-downstream-ci +# - downstream-ci-hpc +# - private-downstream-ci-hpc +# if: ${{ always() && !github.event.pull_request.head.repo.fork && github.event.action != 'labeled' || github.event.label.name == 'approved-for-ci' }} +# steps: +# - name: Trigger Teams notification +# uses: ecmwf-actions/notify-teams@v1 +# with: +# incoming_webhook: ${{ secrets.MS_TEAMS_INCOMING_WEBHOOK }} +# needs_context: ${{ toJSON(needs) }} diff --git a/cmake/VERSION b/cmake/VERSION index 0cbfaed0..a5c4c763 100644 --- a/cmake/VERSION +++ b/cmake/VERSION @@ -1 +1 @@ -3.8.5 +3.9.0 diff --git a/cmake/ecbuild_add_option.cmake b/cmake/ecbuild_add_option.cmake index ed3de7fb..9900d3de 100644 --- a/cmake/ecbuild_add_option.cmake +++ b/cmake/ecbuild_add_option.cmake @@ -109,7 +109,7 @@ macro( ecbuild_add_option ) set( _p_DEFAULT ON ) else() if( NOT _p_DEFAULT MATCHES "[Oo][Nn]" AND NOT _p_DEFAULT MATCHES "[Oo][Ff][Ff]" ) - ecbuild_critical("In macro ecbuild_add_option(), DEFAULT is either ON or OFF: \"${_p_DEFAULT}\"") + ecbuild_critical("In macro ecbuild_add_option(), DEFAULT must be either ON or OFF, but found: \"${_p_DEFAULT}\"") endif() endif() ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): defaults to ${_p_DEFAULT}") @@ -153,12 +153,6 @@ macro( ecbuild_add_option ) # define the option -- for cmake GUI option( ENABLE_${_p_FEATURE} "${_p_DESCRIPTION}" ${_p_DEFAULT} ) - get_property( _feature_desc GLOBAL PROPERTY _CMAKE_${_p_FEATURE}_DESCRIPTION ) - if( _feature_desc ) - add_feature_info( ${_p_FEATURE} ENABLE_${_p_FEATURE} "${_feature_desc}, ${PROJECT_NAME}: ${_p_DESCRIPTION}" ) - else() - add_feature_info( ${_p_FEATURE} ENABLE_${_p_FEATURE} "${PROJECT_NAME}: ${_p_DESCRIPTION}" ) - endif() ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): defining option ENABLE_${_p_FEATURE} '${_p_DESCRIPTION}' ${_p_DEFAULT}") ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): ENABLE_${_p_FEATURE}=${ENABLE_${_p_FEATURE}}") @@ -176,6 +170,26 @@ macro( ecbuild_add_option ) set( ENABLE_${_p_FEATURE} ${${PNAME}_ENABLE_${_p_FEATURE}} ) endif() + ## Update the description of the feature summary + # Choose the correct tick + if (ENABLE_${_p_FEATURE}) + set ( _tick "✔") + else() + set ( _tick "✘") + endif() + set(_enabled "${ENABLE_${_p_FEATURE}}") + get_property( _enabled_features GLOBAL PROPERTY ENABLED_FEATURES ) + if( "${_p_FEATURE}" IN_LIST _enabled_features ) + set(_enabled ON) + endif() + # Retrieve any existing description (n.b. occurs when the same feature is added at multiple projects) + get_property( _feature_desc GLOBAL PROPERTY _CMAKE_${_p_FEATURE}_DESCRIPTION ) + # Append the new description + if( _feature_desc ) + add_feature_info( ${_p_FEATURE} ${_enabled} "${_feature_desc}, ${PROJECT_NAME}(${_tick}): '${_p_DESCRIPTION}'" ) + else() + add_feature_info( ${_p_FEATURE} ${_enabled} "${PROJECT_NAME}(${_tick}): '${_p_DESCRIPTION}'" ) + endif() set( ${PROJECT_NAME}_HAVE_${_p_FEATURE} 0 ) @@ -250,7 +264,7 @@ macro( ecbuild_add_option ) else() # if user provided input and we cannot satisfy FAIL otherwise WARN - ecbuild_disable_feature( ${_p_FEATURE} ) + ecbuild_disable_unused_feature( ${_p_FEATURE} ) if( ${_p_FEATURE}_user_provided_input ) if( NOT _${_p_FEATURE}_condition ) @@ -267,16 +281,16 @@ macro( ecbuild_add_option ) ecbuild_info( "Feature ${_p_FEATURE} was not enabled (also not requested) -- following required packages weren't found: ${_failed_to_find_packages}" ) endif() set( ENABLE_${_p_FEATURE} OFF ) - ecbuild_disable_feature( ${_p_FEATURE} ) + ecbuild_disable_unused_feature( ${_p_FEATURE} ) endif() endif() else() - ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): feature disabled") + ecbuild_info( "Feature ${_p_FEATURE} disabled" ) set( ${PROJECT_NAME}_HAVE_${_p_FEATURE} 0 ) - ecbuild_disable_feature( ${_p_FEATURE} ) + ecbuild_disable_unused_feature( ${_p_FEATURE} ) endif() diff --git a/cmake/ecbuild_compiler_flags.cmake b/cmake/ecbuild_compiler_flags.cmake index 594a49cf..77c62f33 100644 --- a/cmake/ecbuild_compiler_flags.cmake +++ b/cmake/ecbuild_compiler_flags.cmake @@ -72,6 +72,142 @@ macro( ecbuild_compiler_flags _lang ) endmacro() +############################################################################## +#.rst: +# +# ecbuild_purge_compiler_flags +# ====================== +# +# Purge compiler flags for a given language :: +# +# ecbuild_purge_compiler_flags( ) +# +############################################################################## + +macro( ecbuild_purge_compiler_flags _lang ) + + set( options WARN ) + set( oneValueArgs "" ) + set( multiValueArgs "" ) + + cmake_parse_arguments( _PAR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + if( CMAKE_${_lang}_COMPILER_LOADED ) + + # Clear default compilation flags potentially inherited from parent scope + # when using custom compilation flags + if( ECBUILD_SOURCE_FLAGS OR ECBUILD_COMPILE_FLAGS ) + set(CMAKE_${_lang}_FLAGS "") + foreach(_btype ALL RELEASE RELWITHDEBINFO PRODUCTION BIT DEBUG) + set(CMAKE_${_lang}_FLAGS_${_btype} "") + endforeach() + endif() + + endif() + + if( ${_PAR_WARN} ) + ecbuild_warn( "Purging compiler flags set for ${_lang}" ) + endif() + +endmacro() + +############################################################################## +#.rst: +# +# ecbuild_linker_flags +# ==================== +# +# Apply user or toolchain specified linker flag overrides per object type (NOT written to cache) +# +# ecbuild_linker_flags() +# +############################################################################## + +macro( ecbuild_linker_flags ) + foreach( _obj EXE SHARED MODULE ) + if( ECBUILD_${_obj}_LINKER_FLAGS ) + set( CMAKE_${_obj}_LINKER_FLAGS ${ECBUILD_${_obj}_LINKER_FLAGS} ) + endif() + + if( NOT "$ENV{LD_RUN_PATH}" EQUAL "" ) + set( LD_RUN_PATH "$ENV{LD_RUN_PATH}" ) + string( REPLACE ":" ";" LD_RUN_PATH "$ENV{LD_RUN_PATH}" ) + foreach( rpath ${LD_RUN_PATH} ) + ecbuild_regex_escape( "${rpath}" rpath_escaped ) + if( NOT CMAKE_${_obj}_LINKER_FLAGS MATCHES ".*-Wl,-rpath,${rpath_escaped}.*") + set( CMAKE_${_obj}_LINKER_FLAGS "${CMAKE_${_obj}_LINKER_FLAGS} -Wl,-rpath,${rpath}" ) + endif() + endforeach() + endif() + endforeach() + + foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO ) + + foreach( _obj EXE SHARED MODULE ) + if( ECBUILD_${_obj}_LINKER_FLAGS_${_btype} ) + set( CMAKE_${_obj}_LINKER_FLAGS_${_btype} ${ECBUILD_${_obj}_LINKER_FLAGS_${_btype}} ) + endif() + endforeach() + + endforeach() +endmacro() + +############################################################################## +#.rst: +# +# ecbuild_override_compiler_flags +# ====================== +# +# Purge existing CMAKE__FLAGS flags and trigger the use of per source +# file overrideable flags (see ``Using custom compilation flags`` for an +# explanation). +# +# ecbuild_override_compiler_flags() +# +############################################################################## + +macro( ecbuild_override_compiler_flags ) + + set( options "" ) + set( oneValueArgs SOURCE_FLAGS COMPILE_FLAGS ) + set( multiValueArgs "" ) + + cmake_parse_arguments( _PAR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Ensure COMPILE/SOURCE_FLAGS is a valid file path + if( DEFINED _PAR_COMPILE_FLAGS AND NOT EXISTS ${_PAR_COMPILE_FLAGS} ) + ecbuild_warn( "COMPILE_FLAGS points to non-existent file ${_PAR_COMPILE_FLAGS} and will be ignored" ) + unset( ECBUILD_COMPILE_FLAGS ) + unset( ECBUILD_COMPILE_FLAGS CACHE ) + elseif( DEFINED _PAR_SOURCE_FLAGS AND NOT EXISTS ${_PAR_SOURCE_FLAGS} ) + ecbuild_warn( "SOURCE_FLAGS points to non-existent file ${_PAR_SOURCE_FLAGS} and will be ignored" ) + unset( ECBUILD_SOURCE_FLAGS ) + unset( ECBUILD_SOURCE_FLAGS CACHE ) + elseif( DEFINED _PAR_SOURCE_FLAGS OR DEFINED _PAR_COMPILE_FLAGS ) + foreach( _lang C CXX Fortran ) + if( CMAKE_${_lang}_COMPILER_LOADED ) + ecbuild_purge_compiler_flags( ${_lang} WARN ) + endif() + endforeach() + + if( DEFINED _PAR_COMPILE_FLAGS ) + if( DEFINED ECBUILD_COMPILE_FLAGS) + ecbuild_debug( "Override ECBUILD_COMPILE_FLAGS (${ECBUILD_COMPILE_FLAGS}) with ${_PAR_COMPILE_FLAGS}" ) + endif() + set( ECBUILD_COMPILE_FLAGS ${_PAR_COMPILE_FLAGS} ) + include( ${ECBUILD_COMPILE_FLAGS} ) + elseif( DEFINED _PAR_SOURCE_FLAGS ) + if( DEFINED ECBUILD_SOURCE_FLAGS) + ecbuild_debug( "Override ECBUILD_SOURCE_FLAGS (${ECBUILD_SOURCE_FLAGS}) with ${_PAR_SOURCE_FLAGS}" ) + endif() + set( ECBUILD_SOURCE_FLAGS ${_PAR_SOURCE_FLAGS} ) + endif() + + ecbuild_linker_flags() + endif() + +endmacro() + ############################################################################## #.rst: # @@ -172,59 +308,25 @@ foreach( _flags COMPILE SOURCE ) endif() set( ECBUILD_${_flags}_FLAGS ${${PROJECT_NAME_CAPS}_ECBUILD_${_flags}_FLAGS} ) endif() - # Ensure ECBUILD_${_flags}_FLAGS is a valid file path - if( DEFINED ECBUILD_${_flags}_FLAGS AND NOT EXISTS ${ECBUILD_${_flags}_FLAGS} ) - ecbuild_warn( "ECBUILD_${_flags}_FLAGS points to non-existent file ${ECBUILD_${_flags}_FLAGS} and will be ignored" ) - unset( ECBUILD_${_flags}_FLAGS ) - unset( ECBUILD_${_flags}_FLAGS CACHE ) - endif() endforeach() -if( ECBUILD_COMPILE_FLAGS ) - include( "${ECBUILD_COMPILE_FLAGS}" ) +if( DEFINED ECBUILD_COMPILE_FLAGS ) + ecbuild_override_compiler_flags( COMPILE_FLAGS ${ECBUILD_COMPILE_FLAGS} ) +elseif( DEFINED ECBUILD_SOURCE_FLAGS ) + ecbuild_override_compiler_flags( SOURCE_FLAGS ${ECBUILD_SOURCE_FLAGS} ) endif() foreach( _lang C CXX Fortran ) if( CMAKE_${_lang}_COMPILER_LOADED ) - # Clear default compilation flags potentially inherited from parent scope - # when using custom compilation flags - if( ECBUILD_SOURCE_FLAGS OR ECBUILD_COMPILE_FLAGS ) - set(CMAKE_${_lang}_FLAGS "") - foreach(_btype ALL RELEASE RELWITHDEBINFO PRODUCTION BIT DEBUG) - set(CMAKE_${_lang}_FLAGS_${_btype} "") - endforeach() # Load default compilation flags only if custom compilation flags not enabled - else() + if( NOT (DEFINED ECBUILD_SOURCE_FLAGS OR DEFINED ECBUILD_COMPILE_FLAGS) ) ecbuild_compiler_flags( ${_lang} ) endif() endif() endforeach() -# Apply user or toolchain specified linker flag overrides per object type (NOT written to cache) -foreach( _obj EXE SHARED MODULE ) - if( ECBUILD_${_obj}_LINKER_FLAGS ) - set( CMAKE_${_obj}_LINKER_FLAGS ${ECBUILD_${_obj}_LINKER_FLAGS} ) - endif() - - if( NOT "$ENV{LD_RUN_PATH}" EQUAL "" ) - set( LD_RUN_PATH "$ENV{LD_RUN_PATH}" ) - string( REPLACE ":" ";" LD_RUN_PATH "$ENV{LD_RUN_PATH}" ) - foreach( rpath ${LD_RUN_PATH} ) - ecbuild_regex_escape( "${rpath}" rpath_escaped ) - if( NOT CMAKE_${_obj}_LINKER_FLAGS MATCHES ".*-Wl,-rpath,${rpath_escaped}.*") - set( CMAKE_${_obj}_LINKER_FLAGS "${CMAKE_${_obj}_LINKER_FLAGS} -Wl,-rpath,${rpath}" ) - endif() - endforeach() - endif() -endforeach() - -foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO ) - - foreach( _obj EXE SHARED MODULE ) - if( ECBUILD_${_obj}_LINKER_FLAGS_${_btype} ) - set( CMAKE_${_obj}_LINKER_FLAGS_${_btype} ${ECBUILD_${_obj}_LINKER_FLAGS_${_btype}} ) - endif() - endforeach() +if( NOT DEFINED ECBUILD_COMPILE_FLAGS AND NOT DEFINED ECBUILD_SOURCE_FLAGS ) + ecbuild_linker_flags() +endif() -endforeach() diff --git a/cmake/ecbuild_features.cmake b/cmake/ecbuild_features.cmake index 6c049486..f4e66a7a 100644 --- a/cmake/ecbuild_features.cmake +++ b/cmake/ecbuild_features.cmake @@ -55,3 +55,11 @@ function( ecbuild_disable_feature _name ) set_property(GLOBAL PROPERTY DISABLED_FEATURES "${_disabled_features}" ) endfunction() + +# Disable the feature ${_name} globally (if it has not been enabled in any subproject) +function( ecbuild_disable_unused_feature _name ) + get_property( _enabled GLOBAL PROPERTY ENABLED_FEATURES ) + if ( _name IN_LIST _enabled ) # if not already disabled + ecbuild_disable_feature( ${_name} ) + endif() +endfunction() diff --git a/cmake/fortran_features/CheckFortranFeatures.cmake b/cmake/fortran_features/CheckFortranFeatures.cmake index 43ed42c6..bd24bf4f 100644 --- a/cmake/fortran_features/CheckFortranFeatures.cmake +++ b/cmake/fortran_features/CheckFortranFeatures.cmake @@ -116,7 +116,7 @@ macro(_figure_out_fortran_feature current_feature) # Find set of files that match current_feature, excepting _fail and _fail_compile. file(GLOB ALL_FEATURE_FILES "${Fortran_FEATURE_CHECK_DIR}/${current_feature}*.F90") foreach(filename ${ALL_FEATURE_FILES}) - if(filename MATCHES "_fail") + if(filename MATCHES "(_fail|_fail_compile).F90$") list(REMOVE_ITEM ALL_FEATURE_FILES ${filename}) endif() endforeach() diff --git a/cmake/fortran_features/finalization.F90 b/cmake/fortran_features/finalization.F90 index 98705523..b6fbe8ef 100644 --- a/cmake/fortran_features/finalization.F90 +++ b/cmake/fortran_features/finalization.F90 @@ -53,14 +53,18 @@ function AnimalType__ctor(animaltype_) result(self) type(AnimalType) :: self character(len=*) :: animaltype_ self%m_kind = animaltype_ +#ifndef NAGFOR write(0,'(3A,I0)') "Constructing animal ",self%m_kind, " -- address = ",loc(self) +#endif self%constructed = .true. end function subroutine AnimalType__assignment(animal_out,animal_in) type(AnimalType), intent(out) :: animal_out class(AnimalType), intent(in) :: animal_in +#ifndef NAGFOR write(0,'(3A,I0,A,I0)') ' Copying ',animal_in%m_kind, " -- from address ", loc(animal_in), " to address ", loc(animal_out) +#endif animal_out%m_kind = animal_in%m_kind animal_out%constructed = animal_in%constructed end subroutine diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 472c97c3..b68b2781 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,6 +7,8 @@ add_subdirectory( ecbuild_find_package ) add_subdirectory( ecbuild_add_option ) add_subdirectory( ecbuild_add_flags ) add_subdirectory( find_ecbuild ) -add_subdirectory( project_import ) add_subdirectory( ecbuild_shared_libs ) add_subdirectory( interface_library ) +add_subdirectory( project_import ) +add_subdirectory( project_summary ) +add_subdirectory( ecbuild_override_compiler_flags ) diff --git a/tests/ecbuild_override_compiler_flags/CMakeLists.txt b/tests/ecbuild_override_compiler_flags/CMakeLists.txt new file mode 100644 index 00000000..676fe2e7 --- /dev/null +++ b/tests/ecbuild_override_compiler_flags/CMakeLists.txt @@ -0,0 +1,13 @@ +set(_dir ${CMAKE_CURRENT_BINARY_DIR}) +configure_file(run-test.sh.in ${_dir}/run-test.sh @ONLY) +configure_file(test_ecbuild_override_compiler_flags.cmake ${_dir}/CMakeLists.txt COPYONLY) +configure_file(emptyfile.c ${_dir}/emptyfile.c COPYONLY) +configure_file(emptyfile.cxx ${_dir}/emptyfile.cxx COPYONLY) +configure_file(emptyfile.F90 ${_dir}/emptyfile.F90 COPYONLY) +configure_file(compiler_flags.cmake ${_dir}/compiler_flags.cmake COPYONLY) + +ecbuild_add_test( + TARGET test_ecbuild_override_compiler_flags + TYPE SCRIPT + COMMAND run-test.sh +) diff --git a/tests/ecbuild_override_compiler_flags/compiler_flags.cmake b/tests/ecbuild_override_compiler_flags/compiler_flags.cmake new file mode 100644 index 00000000..5b3834b5 --- /dev/null +++ b/tests/ecbuild_override_compiler_flags/compiler_flags.cmake @@ -0,0 +1,9 @@ +set( OVERRIDECOMPILERFLAGS_C_FLAGS "-g -fPIC" ) +set( OVERRIDECOMPILERFLAGS_CXX_FLAGS "-g -fPIC" ) +set( OVERRIDECOMPILERFLAGS_Fortran_FLAGS "-g -fortran_only_flag" ) + +set( OVERRIDECOMPILERFLAGS_C_FLAGS_DEBUG "-O0" ) +set( OVERRIDECOMPILERFLAGS_CXX_FLAGS_DEBUG "-O0" ) + +set( OVERRIDECOMPILERFLAGS_C_FLAGS_BIT "-O2" ) +set( OVERRIDECOMPILERFLAGS_CXX_FLAGS_BIT "-O2" ) diff --git a/tests/ecbuild_override_compiler_flags/emptyfile.F90 b/tests/ecbuild_override_compiler_flags/emptyfile.F90 new file mode 100644 index 00000000..199bc971 --- /dev/null +++ b/tests/ecbuild_override_compiler_flags/emptyfile.F90 @@ -0,0 +1 @@ +! An empty file diff --git a/tests/ecbuild_override_compiler_flags/emptyfile.c b/tests/ecbuild_override_compiler_flags/emptyfile.c new file mode 100644 index 00000000..4d4d8bb5 --- /dev/null +++ b/tests/ecbuild_override_compiler_flags/emptyfile.c @@ -0,0 +1 @@ +// An empty file diff --git a/tests/ecbuild_override_compiler_flags/emptyfile.cxx b/tests/ecbuild_override_compiler_flags/emptyfile.cxx new file mode 100644 index 00000000..4d4d8bb5 --- /dev/null +++ b/tests/ecbuild_override_compiler_flags/emptyfile.cxx @@ -0,0 +1 @@ +// An empty file diff --git a/tests/ecbuild_override_compiler_flags/run-test.sh.in b/tests/ecbuild_override_compiler_flags/run-test.sh.in new file mode 100755 index 00000000..ee9c4197 --- /dev/null +++ b/tests/ecbuild_override_compiler_flags/run-test.sh.in @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -e + +HERE="$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd -P )" + +cd $HERE + +rm -rf build # cleanup +mkdir build +cd build + +cmake -DCMAKE_MODULE_PATH=@ECBUILD_MACROS_DIR@ -DECBUILD_LOG_LEVEL=DEBUG -DCMAKE_BUILD_TYPE=BIT -DECBUILD_SOURCE_FLAGS=@CMAKE_CURRENT_SOURCE_DIR@/flags-sourceflags.json .. + +cd .. + +rm -rf build # cleanup +mkdir build +cd build + +cmake -DCMAKE_MODULE_PATH=@ECBUILD_MACROS_DIR@ -DECBUILD_LOG_LEVEL=DEBUG -DCMAKE_BUILD_TYPE=DEBUG -DECBUILD_SOURCE_FLAGS=@CMAKE_CURRENT_SOURCE_DIR@/flags-sourceflags.json .. + diff --git a/tests/ecbuild_override_compiler_flags/test_ecbuild_override_compiler_flags.cmake b/tests/ecbuild_override_compiler_flags/test_ecbuild_override_compiler_flags.cmake new file mode 100644 index 00000000..d7d6fb20 --- /dev/null +++ b/tests/ecbuild_override_compiler_flags/test_ecbuild_override_compiler_flags.cmake @@ -0,0 +1,45 @@ +cmake_minimum_required( VERSION 3.12 FATAL_ERROR ) + +find_package( ecbuild 3.6 REQUIRED ) + +project(OverrideCompilerFlags VERSION 1.0 LANGUAGES C CXX Fortran) + +ecbuild_override_compiler_flags( COMPILE_FLAGS compiler_flags.cmake ) + +ecbuild_add_library( + TARGET overrideflags + SOURCES emptyfile.c emptyfile.cxx emptyfile.F90 +) + +get_property( _flags SOURCE emptyfile.c PROPERTY COMPILE_FLAGS ) +if( CMAKE_BUILD_TYPE MATCHES BIT ) + if( NOT ${_flags} MATCHES "-g -fPIC -O2" ) + message(${_flags}) + message(FATAL_ERROR "Incorrect BIT flags for emptyfile.c") + endif() +elseif( CMAKE_BUILD_TYPE MATCHES DEBUG ) + if( NOT ${_flags} MATCHES "-g -fPIC -O0" ) + message(${_flags}) + message(FATAL_ERROR "Incorrect DEBUG flags for emptyfile.c") + endif() +endif() + +get_property( _flags SOURCE emptyfile.cxx PROPERTY COMPILE_FLAGS ) +if( CMAKE_BUILD_TYPE MATCHES BIT ) + if( NOT ${_flags} MATCHES "-g -fPIC -O2" ) + message(${_flags}) + message(FATAL_ERROR "Incorrect BIT flags for emptyfile.cxx") + endif() +elseif( CMAKE_BUILD_TYPE MATCHES DEBUG ) + if( NOT ${_flags} MATCHES "-g -fPIC -O0" ) + message(${_flags}) + message(FATAL_ERROR "Incorrect DEBUG flags for emptyfile.cxx") + endif() +endif() + +get_property( _flags SOURCE emptyfile.F90 PROPERTY COMPILE_FLAGS ) +if( NOT ${_flags} MATCHES "-g -fortran_only_flag" ) + message(${_flags}) + message(FATAL_ERROR "Incorrect flags for emptyfile.F90") +endif() + diff --git a/tests/project_summary/CMakeLists.txt b/tests/project_summary/CMakeLists.txt new file mode 100644 index 00000000..d6c558ae --- /dev/null +++ b/tests/project_summary/CMakeLists.txt @@ -0,0 +1,7 @@ + +ecbuild_add_test( + TARGET test_ecbuild_project_summary + TYPE SCRIPT + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/configure.sh + ENVIRONMENT CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR} +) diff --git a/tests/project_summary/clean.sh b/tests/project_summary/clean.sh new file mode 100755 index 00000000..3d88a017 --- /dev/null +++ b/tests/project_summary/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +HERE=${CMAKE_CURRENT_BINARY_DIR:-"$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd -P )"} + +# --------------------- cleanup ------------------------ +echo "cleaning $HERE" +rm -rf $HERE/build_* diff --git a/tests/project_summary/configure.sh b/tests/project_summary/configure.sh new file mode 100755 index 00000000..d1434e1f --- /dev/null +++ b/tests/project_summary/configure.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +set -e + +function EXPECT_ONE_OF() +{ + local file=$1 + local pattern=$2 + local found=$(cat ${file} | grep "${pattern}" | wc -l | xargs) + + if [ "$found" != "1" ]; then + echo "File ${file} does not contain exacly one of '$2'" + exit 1 + fi +} + +HERE=${CMAKE_CURRENT_BINARY_DIR:-"$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd -P )"} +SOURCE=${CMAKE_CURRENT_SOURCE_DIR:-$HERE} + +# Add ecbuild to path +export PATH=$SOURCE/../../bin:$PATH +echo $PATH +echo $SOURCE + +# --------------------- cleanup ------------------------ +$SOURCE/clean.sh + +# ----------------- configure project --------------------- + +# Options: -DENABLE_MYFEATURE=ON + +mkdir -p $HERE/build_1 +ecbuild -DENABLE_MYFEATURE=ON $SOURCE/test_project -B $HERE/build_1 | tee $HERE/build_1.log +EXPECT_ONE_OF $HERE/build_1.log "* MYFEATURE, proja(✔): '', projb(✔): ''" + +# Options: -DENABLE_MYFEATURE=ON -DPROJB_ENABLE_MYFEATURE=OFF + +mkdir -p $HERE/build_2 +ecbuild -DENABLE_MYFEATURE=ON -DPROJB_ENABLE_MYFEATURE=OFF $SOURCE/test_project -B $HERE/build_2 | tee $HERE/build_2.log +EXPECT_ONE_OF $HERE/build_2.log "* MYFEATURE, proja(✔): '', projb(✘): ''" + +# Options: -DENABLE_MYFEATURE=OFF -DPROJB_ENABLE_MYFEATURE=ON + +mkdir -p $HERE/build_3 +ecbuild -DENABLE_MYFEATURE=OFF -DPROJB_ENABLE_MYFEATURE=ON $SOURCE/test_project -B $HERE/build_3 | tee $HERE/build_3.log +EXPECT_ONE_OF $HERE/build_3.log "* MYFEATURE, proja(✘): '', projb(✔): ''" diff --git a/tests/project_summary/test_project/CMakeLists.txt b/tests/project_summary/test_project/CMakeLists.txt new file mode 100644 index 00000000..2a97a33e --- /dev/null +++ b/tests/project_summary/test_project/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required( VERSION 3.18.4 FATAL_ERROR ) +find_package( ecbuild 3.4 REQUIRED ) + +project( proja LANGUAGES NONE VERSION 0.2 ) +ecbuild_add_option( + FEATURE MYFEATURE + DEFAULT ON +) + +project( projb LANGUAGES NONE VERSION 0.1 ) +ecbuild_add_option( + FEATURE MYFEATURE + DEFAULT OFF +) + +ecbuild_print_summary() \ No newline at end of file