diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 497cacf5a..9ebc9ed99 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,7 @@ stages: .build_script: script: #Use pre-existing allocation if any - - JOBID=$(if [[ $SYS_TYPE = toss_* ]]; then squeue -h --name=${PROJECT_ALLOC_NAME} --format=%A; fi) + - JOBID=$(if [[ "$SYS_TYPE" == "toss_4_x86_64_ib" ]]; then squeue -h --name=${PROJECT_ALLOC_NAME} --format=%A; fi) - ASSIGN_ID=$(if [[ -n "${JOBID}" ]]; then echo "--jobid=${JOBID}"; fi) #BUILD + TEST - echo -e "section_start:$(date +%s):build_and_test\r\e[0K diff --git a/.gitlab/build_lassen.yml b/.gitlab/build_lassen.yml index 5defcf49c..d5fd714b4 100644 --- a/.gitlab/build_lassen.yml +++ b/.gitlab/build_lassen.yml @@ -67,5 +67,5 @@ lassen-clang_14.0.5_with_gcc_8.3.1_nvcc_c++_only: lassen-clang_10.0.1_nvcc_cuda_clang_test: variables: ENABLED_BLT_TESTS: "cuda-arch cuda-mpi-cpp" - HOST_CONFIG: "cuda-arch/base/clang@10.0.1_nvcc_c++14_lassen.cmake" + HOST_CONFIG: "clang@10.0.1_nvcc_c++17.cmake" extends: [.run_project_integration_test_on_lassen, .with_cuda] diff --git a/.gitlab/build_quartz.yml b/.gitlab/build_quartz.yml index b646b1cf0..e1262d5c8 100644 --- a/.gitlab/build_quartz.yml +++ b/.gitlab/build_quartz.yml @@ -78,6 +78,6 @@ quartz-intel_2022_1_0_cxx17: # HIP project tests quartz_openmp_mpi_fortran_tests: variables: - HOST_CONFIG: openmp-cpp-fortran/base/clang@14.0.6.cmake ENABLED_BLT_TESTS: "mpi-cpp-fortran,openmp-cpp-fortran,openmp-mpi-cpp" + HOST_CONFIG: "clang@14.0.6.cmake" extends: [.run_project_integration_test_on_quartz] diff --git a/.gitlab/build_tioga.yml b/.gitlab/build_tioga.yml index 67856f48e..125293eb8 100644 --- a/.gitlab/build_tioga.yml +++ b/.gitlab/build_tioga.yml @@ -38,5 +38,5 @@ tioga-clang_14_0_0_hip: tioga-clang_14.0.1_hip_config_test: variables: ENABLED_BLT_TESTS: "hip-config-test" - HOST_CONFIG: "hip-config-test/base/clang@14.0.0_hip.cmake" + HOST_CONFIG: "clang@14.0.0_hip.cmake" extends: [.run_project_integration_test_on_tioga] diff --git a/.gitlab/run_project_integration_tests.sh b/.gitlab/run_project_integration_tests.sh index 87562abec..e7a385044 100755 --- a/.gitlab/run_project_integration_tests.sh +++ b/.gitlab/run_project_integration_tests.sh @@ -2,11 +2,7 @@ BLT_DIR=`pwd` RUNNER_SCRIPT=`pwd`/tests/projects/run_tests.py -cd `pwd`/tests/projects/ +HOST_CONFIG_PATH=`pwd`/host-configs/llnl/$SYS_TYPE/$HOST_CONFIG -if [[ -z $HOST_CONFIG ]]; then - HOST_CONFIG=`pwd`/tests/projects/$HOST_CONFIG - python3 $RUNNER_SCRIPT --run-test $ENABLED_BLT_TESTS --verbose --clean --blt-source-dir $BLT_DIR -else - python3 $RUNNER_SCRIPT --run-test $ENABLED_BLT_TESTS --host-config $HOST_CONFIG --verbose --clean --blt-source-dir $BLT_DIR -fi +cd `pwd`/tests/projects/ +python3 $RUNNER_SCRIPT --run-test $ENABLED_BLT_TESTS --host-config $HOST_CONFIG_PATH --verbose --clean --blt-source-dir $BLT_DIR diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index b9f74535a..395f5ce5f 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -9,6 +9,20 @@ The project release numbers follow [Semantic Versioning](http://semver.org/spec/ ## [Unreleased] - Release date yyyy-mm-dd +## [Version 0.6.2] - Release date 2024-03-15 + +### Added +- Added output for CMake's implicitly added link libraries and directories. + +### Changed +- OpenMP target now uses a generator expression for Fortran flags instead of replacing flags in + Fortran targets created with BLT macros. +- Remove setting CMP0076 to OLD which left relative paths in `target_sources()` instead of altering + them to absolute paths. +- Header-only libraries headers now show up under their own target in IDE project views instead of + under downstream targets. This only works in CMake >= 3.19, otherwise they will not show up at all. +- Raised version for base CMake version supported by BLT to 3.15 to support ALIAS targets across BLT. + ## [Version 0.6.1] - Release date 2024-01-29 ### Fixed @@ -317,7 +331,8 @@ The project release numbers follow [Semantic Versioning](http://semver.org/spec/ -[Unreleased]: https://github.com/LLNL/blt/compare/v0.6.1...develop +[Unreleased]: https://github.com/LLNL/blt/compare/v0.6.2...develop +[Version 0.6.2]: https://github.com/LLNL/blt/compare/v0.6.1...v0.6.2 [Version 0.6.1]: https://github.com/LLNL/blt/compare/v0.6.0...v0.6.1 [Version 0.6.0]: https://github.com/LLNL/blt/compare/v0.5.3...v0.6.0 [Version 0.5.3]: https://github.com/LLNL/blt/compare/v0.5.2...v0.5.3 diff --git a/SetupBLT.cmake b/SetupBLT.cmake index 3bf3c1485..7cbcc8510 100644 --- a/SetupBLT.cmake +++ b/SetupBLT.cmake @@ -4,7 +4,7 @@ # SPDX-License-Identifier: (BSD-3-Clause) if (NOT BLT_LOADED) - set(BLT_VERSION "0.6.1" CACHE STRING "") + set(BLT_VERSION "0.6.2" CACHE STRING "") mark_as_advanced(BLT_VERSION) message(STATUS "BLT Version: ${BLT_VERSION}") @@ -41,10 +41,10 @@ if (NOT BLT_LOADED) endif() unset(_is_multi_config) - if(${CMAKE_VERSION} VERSION_LESS 3.8.0) + if(${CMAKE_VERSION} VERSION_LESS 3.15.0) message("*************************************") message("* Unsupported version of CMake detected.") - message("* BLT requires CMake 3.8 or above.") + message("* BLT requires CMake 3.15 or above.") message("* Some BLT features may not work.") message("*************************************") endif() @@ -79,13 +79,12 @@ if (NOT BLT_LOADED) cmake_policy(SET CMP0074 NEW) endif() - # New turns relative target_sources() paths to absolute - # Policy added in 3.13+ - # NOTE: this will be deprecated eventually but NEW causes - # problems in header only libraries, OLD keeps current behavior - if(POLICY CMP0076) - cmake_policy(SET CMP0076 OLD) - endif() + ################################ + # Enable various find commands to look in non-default paths + ################################ + set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE) + set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE) + set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS TRUE) ################################ # Invoke CMake Fortran setup diff --git a/cmake/BLTMacros.cmake b/cmake/BLTMacros.cmake index 6f851fcaa..e31d82615 100644 --- a/cmake/BLTMacros.cmake +++ b/cmake/BLTMacros.cmake @@ -209,19 +209,13 @@ macro(blt_add_library) # # Header-only library support # - foreach (_file ${arg_HEADERS}) - # Determine build location of headers - get_filename_component(_absolute ${_file} ABSOLUTE) - list(APPEND _build_headers ${_absolute}) - endforeach() - - #Note: This only works if both libraries are handled in the same directory, - # otherwise just don't include non-header files in your source list. - set_source_files_properties(${_build_headers} PROPERTIES HEADER_FILE_ONLY ON) - - add_library( ${arg_NAME} INTERFACE ) - target_sources( ${arg_NAME} INTERFACE - $) + if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0" ) + # Adding headers here allows them to show up in IDE projects but is not + # necessary for building + add_library( ${arg_NAME} INTERFACE ${arg_HEADERS} ) + else() + add_library( ${arg_NAME} INTERFACE ) + endif() endif() # Clear value of _have_fortran from previous calls @@ -348,12 +342,6 @@ macro(blt_add_executable) set_target_properties(${arg_NAME} PROPERTIES LINKER_LANGUAGE ${_blt_link_lang}) endif() - # fix the openmp flags for fortran if needed - # NOTE: this needs to be called after blt_setup_target() - if (_lang STREQUAL Fortran) - blt_fix_fortran_openmp_flags( ${arg_NAME} ) - endif() - if ( arg_INCLUDES ) target_include_directories(${arg_NAME} PUBLIC ${arg_INCLUDES}) endif() diff --git a/cmake/BLTPrivateMacros.cmake b/cmake/BLTPrivateMacros.cmake index e0b408754..3c9543164 100644 --- a/cmake/BLTPrivateMacros.cmake +++ b/cmake/BLTPrivateMacros.cmake @@ -20,83 +20,6 @@ function(blt_error_if_target_exists target_name error_msg) endif() endfunction() -##----------------------------------------------------------------------------- -## blt_fix_fortran_openmp_flags() -## -## Fixes the openmp flags for a Fortran target if they are different from the -## corresponding C/C++ OpenMP flags. -##----------------------------------------------------------------------------- -function(blt_fix_fortran_openmp_flags target_name) - - if (ENABLE_FORTRAN AND ENABLE_OPENMP AND BLT_OPENMP_FLAGS_DIFFER) - - # The OpenMP interface library will have been added as a direct - # link dependency instead of via flags - get_target_property(target_link_libs ${target_name} LINK_LIBRARIES) - if ( target_link_libs ) - # Since this is only called on executable targets we can safely convert - # from a "real" target back to a "fake" one as this is a sink vertex in - # the DAG. Only the link flags need to be modified. - list(FIND target_link_libs "openmp" _omp_index) - list(FIND target_link_libs "blt::openmp" _blt_omp_index) - if(${_omp_index} GREATER -1 OR ${_blt_omp_index} GREATER -1) - message(STATUS "Fixing OpenMP Flags for target[${target_name}]") - - # Remove openmp from libraries - list(REMOVE_ITEM target_link_libs "openmp") - list(REMOVE_ITEM target_link_libs "blt::openmp") - set_target_properties( ${target_name} PROPERTIES - LINK_LIBRARIES "${target_link_libs}" ) - - # Add openmp compile flags verbatim w/ generator expression - get_target_property(omp_compile_flags openmp INTERFACE_COMPILE_OPTIONS) - target_compile_options(${target_name} PUBLIC ${omp_compile_flags}) - - # Change CXX flags to Fortran flags - - # These are set through blt_add_target_link_flags which needs to use - # the link_libraries for interface libraries in CMake < 3.13 - if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0" ) - get_target_property(omp_link_flags openmp INTERFACE_LINK_OPTIONS) - else() - get_target_property(omp_link_flags openmp INTERFACE_LINK_LIBRARIES) - endif() - - string( REPLACE "${OpenMP_CXX_FLAGS}" "${OpenMP_Fortran_FLAGS}" - correct_omp_link_flags - "${omp_link_flags}" - ) - if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0" ) - target_link_options(${target_name} PRIVATE "${correct_omp_link_flags}") - else() - set_property(TARGET ${target_name} APPEND PROPERTY LINK_FLAGS "${correct_omp_link_flags}") - endif() - endif() - - # Handle registered library general case - - # OpenMP is an interface library which doesn't have a LINK_FLAGS property - # in versions < 3.13 - set(_property_name LINK_FLAGS) - if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0" ) - # In CMake 3.13+, LINK_FLAGS was converted to LINK_OPTIONS. - set(_property_name LINK_OPTIONS) - endif() - get_target_property(target_link_flags ${target_name} ${_property_name}) - if ( target_link_flags ) - - string( REPLACE "${OpenMP_CXX_FLAGS}" "${OpenMP_Fortran_FLAGS}" - correct_link_flags - "${target_link_flags}" - ) - set_target_properties( ${target_name} PROPERTIES ${_property_name} - "${correct_link_flags}" ) - endif() - endif() - - endif() - -endfunction() ##----------------------------------------------------------------------------- ## blt_find_executable(NAME diff --git a/cmake/BLTSetupTargets.cmake b/cmake/BLTSetupTargets.cmake index 96fdf3e55..ddcb6c5d5 100644 --- a/cmake/BLTSetupTargets.cmake +++ b/cmake/BLTSetupTargets.cmake @@ -3,9 +3,9 @@ # # SPDX-License-Identifier: (BSD-3-Clause) -# This file is intended to be included in the *-config.cmake files of -# any project using a third-party library. The macro -# `blt_install_tpl_setups(DESTINATION )` installs this file +# This file is intended to be included in the installed config files of +# any project using BLT's third-party library as well as in a BLT project. +# The macro `blt_install_tpl_setups(DESTINATION )` installs this file # into the destination specified by the argument . # BLTInstallableMacros provides helper macros for setting up and creating @@ -14,40 +14,48 @@ if (NOT BLT_LOADED) include("${CMAKE_CURRENT_LIST_DIR}/BLTInstallableMacros.cmake") endif() -# If the generated TPL config file exists, include it here. + +# Handle the two cases of TPL config variables, installed from upstream project +# and the current/main BLT project. Prefix all variables here to not conflict with +# non-BLT projects that load this as a configuration file. if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/BLTThirdPartyConfigFlags.cmake") + # Case: Imported BLT project (ie. an installed TPL loading its BLT targets) include("${CMAKE_CURRENT_LIST_DIR}/BLTThirdPartyConfigFlags.cmake") else() - # Otherwise, configure the TPL flags. We have to prefix these variables with - # BLT so that they never conflict with user-level CMake variables in downstream - # projects. - # - # We have to do some checks before we overwrite these internal variables to assure - # that we don't turn off a third-party library enabled by the dependency. - if (NOT DEFINED BLT_ENABLE_HIP OR NOT ${BLT_ENABLE_HIP}) + # Case: Main BLT project (ie. a project loading it's own BLT) + # + # Always stay enabled if any upstream has already turned you on. + if(NOT BLT_ENABLE_HIP) set(BLT_ENABLE_HIP ${ENABLE_HIP}) endif() - if (NOT DEFINED BLT_ENABLE_CUDA OR NOT ${BLT_ENABLE_CUDA}) + if(NOT BLT_ENABLE_CUDA) set(BLT_ENABLE_CUDA ${ENABLE_CUDA}) endif() - if (NOT DEFINED BLT_ENABLE_MPI OR NOT ${BLT_ENABLE_MPI}) + if(NOT BLT_ENABLE_MPI) set(BLT_ENABLE_MPI ${ENABLE_MPI}) endif() - if (NOT DEFINED BLT_ENABLE_OPENMP OR NOT ${BLT_ENABLE_OPENMP}) + if(NOT BLT_ENABLE_OPENMP) set(BLT_ENABLE_OPENMP ${ENABLE_OPENMP}) endif() - if (NOT DEFINED BLT_ENABLE_FIND_MPI OR NOT ${BLT_ENABLE_FIND_MPI}) + if(NOT BLT_ENABLE_FIND_MPI) set(BLT_ENABLE_FIND_MPI ${ENABLE_FIND_MPI}) endif() - set(BLT_ENABLE_CLANG_CUDA ${ENABLE_CLANG_CUDA}) + if(NOT BLT_ENABLE_CLANG_CUDA) + set(BLT_ENABLE_CLANG_CUDA ${ENABLE_CLANG_CUDA}) + endif() + + message(STATUS "BLT MPI support is ${BLT_ENABLE_MPI}") + message(STATUS "BLT OpenMP support is ${BLT_ENABLE_OPENMP}") + message(STATUS "BLT CUDA support is ${BLT_ENABLE_CUDA}") + message(STATUS "BLT HIP support is ${BLT_ENABLE_HIP}") endif() # Detect if Fortran has been introduced. get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) if(_languages MATCHES "Fortran") - set(_fortran_already_enabled TRUE) + set(_fortran_already_enabled TRUE) else() - set(_fortran_already_enabled FALSE) + set(_fortran_already_enabled FALSE) endif() # Only update ENABLE_FORTRAN if it is a new requirement, don't turn @@ -62,8 +70,8 @@ endif() # MPI #------------------------------------ if (NOT TARGET mpi) - message(STATUS "MPI Support is ${BLT_ENABLE_MPI}") if (BLT_ENABLE_MPI AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/thirdparty/BLTSetupMPI.cmake") + message(STATUS "Creating BLT MPI targets...") include("${CMAKE_CURRENT_LIST_DIR}/thirdparty/BLTSetupMPI.cmake") endif() endif() @@ -73,8 +81,8 @@ endif() # OpenMP #------------------------------------ if (NOT TARGET openmp) - message(STATUS "OpenMP Support is ${BLT_ENABLE_OPENMP}") if (BLT_ENABLE_OPENMP AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/thirdparty/BLTSetupOpenMP.cmake") + message(STATUS "Creating BLT OpenMP targets...") include("${CMAKE_CURRENT_LIST_DIR}/thirdparty/BLTSetupOpenMP.cmake") endif() endif() @@ -84,8 +92,8 @@ endif() # CUDA #------------------------------------ if (NOT TARGET cuda) - message(STATUS "CUDA Support is ${BLT_ENABLE_CUDA}") if (BLT_ENABLE_CUDA AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/thirdparty/BLTSetupCUDA.cmake") + message(STATUS "Creating BLT CUDA targets...") include("${CMAKE_CURRENT_LIST_DIR}/thirdparty/BLTSetupCUDA.cmake") endif() endif() @@ -95,8 +103,8 @@ endif() # HIP #------------------------------------ if (NOT TARGET blt_hip) - message(STATUS "HIP Support is ${BLT_ENABLE_HIP}") if (BLT_ENABLE_HIP AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/thirdparty/BLTSetupHIP.cmake") + message(STATUS "Creating BLT HIP targets...") include("${CMAKE_CURRENT_LIST_DIR}/thirdparty/BLTSetupHIP.cmake") endif() endif() diff --git a/cmake/BLTThirdPartyConfigFlags.cmake.in b/cmake/BLTThirdPartyConfigFlags.cmake.in index ccb061ca5..d91b73cb9 100644 --- a/cmake/BLTThirdPartyConfigFlags.cmake.in +++ b/cmake/BLTThirdPartyConfigFlags.cmake.in @@ -1,40 +1,35 @@ -if ("@ENABLE_CUDA@") - set(BLT_ENABLE_CUDA "@ENABLE_CUDA@") +# Always stay enabled if any upstream has already turned you on. +if(NOT BLT_ENABLE_CUDA) + set(BLT_ENABLE_CUDA @ENABLE_CUDA@) endif() - -if ("@ENABLE_HIP@") - set(BLT_ENABLE_HIP "@ENABLE_HIP@") +if(NOT BLT_ENABLE_HIP) + set(BLT_ENABLE_HIP @ENABLE_HIP@) endif() - -if ("@ENABLE_MPI@") - set(BLT_ENABLE_MPI "@ENABLE_MPI@") +if(NOT BLT_ENABLE_MPI) + set(BLT_ENABLE_MPI @ENABLE_MPI@) endif() - -if ("@ENABLE_OPENMP@") - set(BLT_ENABLE_OPENMP "@ENABLE_OPENMP@") +if(NOT BLT_ENABLE_OPENMP) + set(BLT_ENABLE_OPENMP @ENABLE_OPENMP@) +endif() +if(NOT BLT_ENABLE_FIND_MPI) + set(BLT_ENABLE_FIND_MPI @ENABLE_FIND_MPI@) endif() -set(BLT_ENABLE_FIND_MPI "@ENABLE_FIND_MPI@") - -# User configurable CUDA options needed by downstream. Normally, exporting -# these targets would pass these flags to downstream targets, but this -# must be done manually if targets aren't exported. -if ("@ENABLE_CLANG_CUDA@" AND NOT DEFINED ENABLE_CLANG_CUDA) - set(BLT_ENABLE_CLANG_CUDA "@ENABLE_CLANG_CUDA@") -# If the user specifies this variable, ignore the inherited flag. -elseif (DEFINED ENABLE_CLANG_CUDA) +# Always prefer the current project if they turned it on +if(ENABLE_CLANG_CUDA) set(BLT_ENABLE_CLANG_CUDA ${ENABLE_CLANG_CUDA}) +else() + set(BLT_ENABLE_CLANG_CUDA @ENABLE_CLANG_CUDA@) endif() -if ("@BLT_CLANG_CUDA_ARCH@" AND NOT DEFINED BLT_CLANG_CUDA_ARCH) +if (NOT DEFINED BLT_CLANG_CUDA_ARCH) set(BLT_CLANG_CUDA_ARCH "@BLT_CLANG_CUDA_ARCH@") endif() -if ("@CUDA_TOOLKIT_ROOT_DIR@" AND NOT DEFINED CUDA_TOOLKIT_ROOT_DIR) +if (NOT DEFINED CUDA_TOOLKIT_ROOT_DIR) set(CUDA_TOOLKIT_ROOT_DIR "@CUDA_TOOLKIT_ROOT_DIR@") endif() -# User configurable HIP options needed by downstream -if ("@ROCM_PATH@" AND NOT DEFINED ROCM_PATH) +if (NOT DEFINED ROCM_PATH) set(ROCM_PATH "@ROCM_PATH@") endif() diff --git a/cmake/SetupCompilerOptions.cmake b/cmake/SetupCompilerOptions.cmake index bb9d7e29b..74a758db7 100644 --- a/cmake/SetupCompilerOptions.cmake +++ b/cmake/SetupCompilerOptions.cmake @@ -358,37 +358,57 @@ endforeach() ################################## # Remove implicit link directories ################################## +message(STATUS "CMake's C implicit link directories: ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") +message(STATUS "CMake's CXX implicit link directories: ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}") +if (ENABLE_FORTRAN) + message(STATUS "CMake's Fortran implicit link directories: ${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}") +endif () +if (ENABLE_CUDA) + message(STATUS "CMake's CUDA implicit link directories: ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}") +endif () + if(BLT_CMAKE_IMPLICIT_LINK_DIRECTORIES_EXCLUDE) message(STATUS "Removing implicit link directories: ${BLT_CMAKE_IMPLICIT_LINK_DIRECTORIES_EXCLUDE}") - list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES ${BLT_CMAKE_IMPLICIT_LINK_DIRECTORIES_EXCLUDE}) - message(STATUS "Updated CXX implicit Link Directories: ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}") + list(REMOVE_ITEM CMAKE_C_IMPLICIT_LINK_DIRECTORIES ${BLT_CMAKE_IMPLICIT_LINK_DIRECTORIES_EXCLUDE}) - message(STATUS "Updated C implicit Link Directories: ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + message(STATUS "Updated C implicit link directories: ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES ${BLT_CMAKE_IMPLICIT_LINK_DIRECTORIES_EXCLUDE}) + message(STATUS "Updated CXX implicit link directories: ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}") if (ENABLE_FORTRAN) list(REMOVE_ITEM CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES ${BLT_CMAKE_IMPLICIT_LINK_DIRECTORIES_EXCLUDE}) - message(STATUS "Updated Fortran implicit Link Directories: ${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}") + message(STATUS "Updated Fortran implicit link directories: ${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}") endif () if (ENABLE_CUDA) list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES ${BLT_CMAKE_IMPLICIT_LINK_DIRECTORIES_EXCLUDE}) - message(STATUS "Updated CUDA implicit Link Directories: ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}") + message(STATUS "Updated CUDA implicit link directories: ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}") endif () endif() ################################## # Remove implicit link libraries ################################## +message(STATUS "CMake's C implicit link libraries: ${CMAKE_C_IMPLICIT_LINK_LIBRARIES}") +message(STATUS "CMake's CXX implicit link libraries: ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}") +if (ENABLE_FORTRAN) + message(STATUS "CMake's Fortran implicit link libraries: ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}") +endif () +if (ENABLE_CUDA) + message(STATUS "CMake's CUDA implicit link libraries: ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES}") +endif () + if(BLT_CMAKE_IMPLICIT_LINK_LIBRARIES_EXCLUDE) message(STATUS "Removing implicit link libraries: ${BLT_CMAKE_IMPLICIT_LINK_LIBRARIES_EXCLUDE}") - list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_LIBRARIES ${BLT_CMAKE_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) - message(STATUS "Updated CXX implicit Link Libraries: ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}") + list(REMOVE_ITEM CMAKE_C_IMPLICIT_LINK_LIBRARIES ${BLT_CMAKE_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) - message(STATUS "Updated C implicit Link Libraries: ${CMAKE_C_IMPLICIT_LINK_LIBRARIES}") + message(STATUS "Updated C implicit link libraries: ${CMAKE_C_IMPLICIT_LINK_LIBRARIES}") + list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_LIBRARIES ${BLT_CMAKE_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) + message(STATUS "Updated CXX implicit link libraries: ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}") if (ENABLE_FORTRAN) list(REMOVE_ITEM CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES ${BLT_CMAKE_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) - message(STATUS "Updated Fortran implicit Link Libraries: ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}") + message(STATUS "Updated Fortran implicit link libraries: ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}") endif () if (ENABLE_CUDA) list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES ${BLT_CMAKE_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) - message(STATUS "Updated CUDA implicit Link Libraries: ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES}") + message(STATUS "Updated CUDA implicit link libraries: ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES}") endif () endif() diff --git a/cmake/thirdparty/BLTSetupCUDA.cmake b/cmake/thirdparty/BLTSetupCUDA.cmake index 76d1b0d1c..dc1f95ae0 100644 --- a/cmake/thirdparty/BLTSetupCUDA.cmake +++ b/cmake/thirdparty/BLTSetupCUDA.cmake @@ -114,9 +114,9 @@ message(STATUS "CUDA Version: ${CUDA_VERSION_STRING}") message(STATUS "CUDA Toolkit Root Dir: ${CUDA_TOOLKIT_ROOT_DIR}") message(STATUS "CUDA Compiler: ${CMAKE_CUDA_COMPILER}") if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.9.0" ) - message(STATUS "CUDA Host Compiler: ${CMAKE_CUDA_HOST_COMPILER}") + message(STATUS "CUDA Host Compiler: ${CMAKE_CUDA_HOST_COMPILER}") else() - message(STATUS "CUDA Host Compiler: ${CUDA_HOST_COMPILER}") + message(STATUS "CUDA Host Compiler: ${CUDA_HOST_COMPILER}") endif() message(STATUS "CUDA Include Path: ${CUDA_INCLUDE_DIRS}") message(STATUS "CUDA Libraries: ${CUDA_LIBRARIES}") diff --git a/cmake/thirdparty/BLTSetupOpenMP.cmake b/cmake/thirdparty/BLTSetupOpenMP.cmake index 186ea272f..22f3078cc 100644 --- a/cmake/thirdparty/BLTSetupOpenMP.cmake +++ b/cmake/thirdparty/BLTSetupOpenMP.cmake @@ -12,33 +12,46 @@ find_package(OpenMP REQUIRED) # check if the openmp flags used for C/C++ are different from the openmp flags # used by the Fortran compiler -set(BLT_OPENMP_FLAGS_DIFFER FALSE CACHE BOOL "") -if (BLT_ENABLE_FORTRAN) - string(COMPARE NOTEQUAL "${OpenMP_CXX_FLAGS}" "${OpenMP_Fortran_FLAGS}" - BLT_OPENMP_FLAGS_DIFFER ) +set(_flags_differ FALSE) +if(BLT_ENABLE_FORTRAN) + string(COMPARE NOTEQUAL "${OpenMP_CXX_FLAGS}" "${OpenMP_Fortran_FLAGS}" + _flags_differ) endif() +set(BLT_OPENMP_FLAGS_DIFFER ${_flags_differ} CACHE BOOL "") -# avoid generator expressions if possible, as generator expressions can be -# passed as flags to downstream projects that might not be using the same -# languages. See https://github.com/LLNL/blt/issues/205 set(_compile_flags ${OpenMP_CXX_FLAGS}) -set(_link_flags ${OpenMP_CXX_FLAGS}) - -if(NOT COMPILER_FAMILY_IS_MSVC AND BLT_ENABLE_CUDA AND BLT_OPENMP_FLAGS_DIFFER) - set(_compile_flags - $<$>,$>>:${OpenMP_CXX_FLAGS}> - $<$:-Xcompiler=${OpenMP_CXX_FLAGS}> - $<$:${OpenMP_Fortran_FLAGS}>) -elseif(NOT COMPILER_FAMILY_IS_MSVC AND BLT_ENABLE_CUDA) - set(_compile_flags - $<$>:${OpenMP_CXX_FLAGS}> - $<$:-Xcompiler=${OpenMP_CXX_FLAGS}>) -elseif(NOT COMPILER_FAMILY_IS_MSVC AND BLT_OPENMP_FLAGS_DIFFER) - set(_compile_flags - $<$>:${OpenMP_CXX_FLAGS}> - $<$:${OpenMP_Fortran_FLAGS}>) +set(_link_flags) + +if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.18.0" ) + set(_link_exp LINK_LANGUAGE) +else() + set(_link_exp COMPILE_LANGUAGE) endif() +if(NOT COMPILER_FAMILY_IS_MSVC) + if(BLT_ENABLE_CUDA AND BLT_OPENMP_FLAGS_DIFFER) + set(_compile_flags + $<$>,$>>:${OpenMP_CXX_FLAGS}> + $<$:-Xcompiler=${OpenMP_CXX_FLAGS}> + $<$:${OpenMP_Fortran_FLAGS}>) + elseif(BLT_ENABLE_CUDA) + set(_compile_flags + $<$>:${OpenMP_CXX_FLAGS}> + $<$:-Xcompiler=${OpenMP_CXX_FLAGS}>) + elseif(BLT_OPENMP_FLAGS_DIFFER) + set(_compile_flags + $<$>:${OpenMP_CXX_FLAGS}> + $<$:${OpenMP_Fortran_FLAGS}>) + endif() + + if(BLT_OPENMP_FLAGS_DIFFER) + set(_link_flags + $<$>:${OpenMP_CXX_FLAGS}> + $<$<${_link_exp}:Fortran>:${OpenMP_Fortran_FLAGS}>) + else() + set(_link_flags ${OpenMP_CXX_FLAGS}) + endif() +endif() # Allow user to override if (BLT_OPENMP_COMPILE_FLAGS) @@ -49,10 +62,10 @@ if (BLT_OPENMP_LINK_FLAGS) endif() -message(STATUS "OpenMP Compile Flags: ${_compile_flags}") -message(STATUS "OpenMP Link Flags: ${_link_flags}") +message(STATUS "BLT OpenMP Compile Flags: ${_compile_flags}") +message(STATUS "BLT OpenMP Link Flags: ${_link_flags}") -blt_import_library(NAME openmp +blt_import_library(NAME openmp COMPILE_FLAGS ${_compile_flags} LINK_FLAGS ${_link_flags} EXPORTABLE ${BLT_EXPORT_THIRDPARTY}) diff --git a/host-configs/llnl/toss_4_x86_64_ib/clang@14.0.6.cmake b/host-configs/llnl/toss_4_x86_64_ib/clang@14.0.6.cmake index 2126c2378..c42f546a3 100644 --- a/host-configs/llnl/toss_4_x86_64_ib/clang@14.0.6.cmake +++ b/host-configs/llnl/toss_4_x86_64_ib/clang@14.0.6.cmake @@ -8,7 +8,7 @@ #------------------------------------------------------------------------------ # # This file provides CMake with paths / details for: -# C,C++, & Fortran compilers + MPI +# C,C++, & Fortran compilers + MPI + OpenMP #------------------------------------------------------------------------------ # clang-14.0.6 compilers @@ -27,6 +27,8 @@ set(ENABLE_FORTRAN ON CACHE BOOL "") # fortran compiler set(CMAKE_Fortran_COMPILER "${GNU_HOME}/bin/gfortran" CACHE PATH "") +set(ENABLE_OPENMP ON CACHE BOOL "") + #------------------------------------------------------------------------------ # Static Analysis Support #------------------------------------------------------------------------------ diff --git a/tests/projects/cuda-arch/base/clang@10.0.1_nvcc_c++14_lassen.cmake b/tests/projects/cuda-arch/base/clang@10.0.1_nvcc_c++14_lassen.cmake deleted file mode 100644 index 3f46d1816..000000000 --- a/tests/projects/cuda-arch/base/clang@10.0.1_nvcc_c++14_lassen.cmake +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and -# other BLT Project Developers. See the top-level LICENSE file for details -# -# SPDX-License-Identifier: (BSD-3-Clause) - -#------------------------------------------------------------------------------ -# Host-config file for executing tests of BLT's configuration of CUDA targets on Lassen. -#------------------------------------------------------------------------------ - -#------------------------------------------------------------------------------ -# Compilers -#------------------------------------------------------------------------------ - -set(BLT_CXX_STD "c++14" CACHE STRING "") -set(CLANG_HOME "/usr/tce/packages/clang/clang-16.0.6") -set(CMAKE_C_COMPILER "${CLANG_HOME}/bin/clang" CACHE PATH "") -set(CMAKE_CXX_COMPILER "${CLANG_HOME}/bin/clang++" CACHE PATH "") - -#------------------------------------------------------------------------------ -# CUDA support -#------------------------------------------------------------------------------ -set(ENABLE_CUDA ON CACHE BOOL "") - -set(CUDA_TOOLKIT_ROOT_DIR "/usr/tce/packages/cuda/cuda-11.1.0" CACHE PATH "") -set(CMAKE_CUDA_COMPILER "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc" CACHE PATH "") -set(CMAKE_CUDA_HOST_COMPILER "${CMAKE_CXX_COMPILER}" CACHE PATH "") - -set(CMAKE_CUDA_ARCHITECTURES "60" CACHE STRING "") -set(CMAKE_CUDA_FLAGS "-restrict --expt-extended-lambda -G" CACHE STRING "") diff --git a/tests/projects/cuda-arch/downstream/CMakeLists.txt b/tests/projects/cuda-arch/downstream/CMakeLists.txt index f65b1c0ea..f86ca95dd 100644 --- a/tests/projects/cuda-arch/downstream/CMakeLists.txt +++ b/tests/projects/cuda-arch/downstream/CMakeLists.txt @@ -1,14 +1,17 @@ +# Clear variables set in the host-config so we can test that they are inherited +# from the upstream project +foreach(_option MPI CUDA HIP OPENMP) + unset(ENABLE_${_option} CACHE) + unset(ENABLE_${_option}) +endforeach() + cmake_minimum_required(VERSION 3.14) project(cuda-clang-cpp-user LANGUAGES CXX) -set(ENABLE_CLANG_CUDA On CACHE BOOL "") -set(BLT_CLANG_CUDA_ARCH "sm_70" CACHE STRING "") -set(CMAKE_CUDA_SEPARABLE_COMPILATION On CACHE BOOL "") # Load BLT include(${BLT_SOURCE_DIR}/SetupBLT.cmake) -set(BLT_CXX_STD c++14 CACHE STRING "") # Calling find_package sets up the TPL targets needed by the project # in its argument. find_package(cuda-clang-cpp REQUIRED @@ -21,28 +24,6 @@ if (NOT TARGET blt::cuda) "downstream project configuration.") endif() -# Check that the cuda target created during the `find_package` call contains the expected -# user provided flags for clang cuda. -get_target_property(cuda_compile_flags blt::cuda INTERFACE_COMPILE_OPTIONS) - -message(STATUS "CUDA target created with compile flags set to: ${cuda_compile_flags}") - -string(FIND "${cuda_compile_flags}" "-x" clang_cuda_flag) -string(FIND "${cuda_compile_flags}" "sm_70" clang_cuda_arch) -string(FIND "${cuda_compile_flags}" "/usr/tce/packages/cuda/cuda-11.1.0" expected_cuda_toolkit_dir) - -if (clang_cuda_flag EQUAL -1) - message(FATAL_ERROR "Expected downstream project CLANG CUDA config flags to override upstream project's.") -endif() - -if(clang_cuda_arch EQUAL -1) - message(FATAL_ERROR "Expected downstream project CLANG CUDA cuda arch config flags to override upstream project's.") -endif() - -if (expected_cuda_toolkit_dir EQUAL -1) - message(FATAL_ERROR "Expected downstream project config flags to inherit upstream project's when alternative is not specified.") -endif() - # Compile a basic example to test correctness of link and compile flags. blt_add_executable( NAME hello-cuda diff --git a/tests/projects/cuda-mpi-cpp/downstream/CMakeLists.txt b/tests/projects/cuda-mpi-cpp/downstream/CMakeLists.txt index b3e32def0..6ee2addaa 100644 --- a/tests/projects/cuda-mpi-cpp/downstream/CMakeLists.txt +++ b/tests/projects/cuda-mpi-cpp/downstream/CMakeLists.txt @@ -1,3 +1,10 @@ +# Clear variables set in the host-config so we can test that they are inherited +# from the upstream project +foreach(_option MPI CUDA HIP OPENMP) + unset(ENABLE_${_option} CACHE) + unset(ENABLE_${_option}) +endforeach() + cmake_minimum_required(VERSION 3.14) project(cuda-mpi-cpp-user LANGUAGES CXX) diff --git a/tests/projects/hip-config-test/base/clang@14.0.0_hip.cmake b/tests/projects/hip-config-test/base/clang@14.0.0_hip.cmake deleted file mode 100644 index ec80ea228..000000000 --- a/tests/projects/hip-config-test/base/clang@14.0.0_hip.cmake +++ /dev/null @@ -1,21 +0,0 @@ -#------------------------------------------------------------------------------ -# This is meant to be a lightweight host config file to tell CMake where to find -# HIP on Tioga, for CI purposes. -#------------------------------------------------------------------------------ -# CMake executable path: /usr/tce/packages/cmake/cmake-3.21.1/bin/cmake -#------------------------------------------------------------------------------ - -set(CMAKE_C_COMPILER "/opt/rocm-5.1.1/llvm/bin/amdclang" CACHE PATH "") -set(CMAKE_CXX_COMPILER "/opt/rocm-5.1.1/llvm/bin/amdclang++" CACHE PATH "") -set(CMAKE_Fortran_COMPILER "/opt/rocm-5.1.1/llvm/bin/amdflang" CACHE PATH "") -set(CMAKE_Fortran_FLAGS "-Mfreeform" CACHE STRING "") - -#------------------------------------------------------------------------------ -# HIP -#------------------------------------------------------------------------------ - -set(ENABLE_HIP ON CACHE BOOL "") -set(HIP_ROOT_DIR "/opt/rocm-5.1.1/hip" CACHE STRING "") -set(HIP_CLANG_PATH "/opt/rocm-5.1.1/hip/../llvm/bin" CACHE STRING "") -set(CMAKE_HIP_ARCHITECTURES "gfx90a" CACHE STRING "") -set(CMAKE_EXE_LINKER_FLAGS "-Wl,--disable-new-dtags -L/opt/rocm-5.1.1/hip/../llvm/lib -L/opt/rocm-5.1.1/hip/lib -Wl,-rpath,/opt/rocm-5.1.1/hip/../llvm/lib:/opt/rocm-5.1.1/hip/lib -lpgmath -lflang -lflangrti -lompstub -lamdhip64 -L/opt/rocm-5.1.1/hip/../lib64 -Wl,-rpath,/opt/rocm-5.1.1/hip/../lib64 -lhsakmt -lamd_comgr" CACHE STRING "") diff --git a/tests/projects/hip-config-test/downstream/CMakeLists.txt b/tests/projects/hip-config-test/downstream/CMakeLists.txt index 4804f5ea8..37554e560 100644 --- a/tests/projects/hip-config-test/downstream/CMakeLists.txt +++ b/tests/projects/hip-config-test/downstream/CMakeLists.txt @@ -1,3 +1,10 @@ +# Clear variables set in the host-config so we can test that they are inherited +# from the upstream project +foreach(_option MPI CUDA HIP OPENMP) + unset(ENABLE_${_option} CACHE) + unset(ENABLE_${_option}) +endforeach() + cmake_minimum_required(VERSION 3.14) project(hip-config-test-user LANGUAGES CXX C) diff --git a/tests/projects/mpi-cpp-fortran/downstream/CMakeLists.txt b/tests/projects/mpi-cpp-fortran/downstream/CMakeLists.txt index fb511713d..8cae44a95 100644 --- a/tests/projects/mpi-cpp-fortran/downstream/CMakeLists.txt +++ b/tests/projects/mpi-cpp-fortran/downstream/CMakeLists.txt @@ -1,3 +1,10 @@ +# Clear variables set in the host-config so we can test that they are inherited +# from the upstream project +foreach(_option MPI CUDA HIP OPENMP) + unset(ENABLE_${_option} CACHE) + unset(ENABLE_${_option}) +endforeach() + cmake_minimum_required(VERSION 3.14) project(mpi-cpp-fortran-user LANGUAGES CXX Fortran) diff --git a/tests/projects/openmp-cpp-fortran/base/clang@14.0.6.cmake b/tests/projects/openmp-cpp-fortran/base/clang@14.0.6.cmake deleted file mode 100644 index 6e83f45bb..000000000 --- a/tests/projects/openmp-cpp-fortran/base/clang@14.0.6.cmake +++ /dev/null @@ -1,4 +0,0 @@ -set(CLANG_VERSION "clang-14.0.6") -set(CLANG_HOME "/usr/tce/packages/clang/${CLANG_VERSION}") -set(CMAKE_C_COMPILER "${CLANG_HOME}/bin/clang" CACHE PATH "") -set(CMAKE_CXX_COMPILER "${CLANG_HOME}/bin/clang++" CACHE PATH "") diff --git a/tests/projects/openmp-cpp-fortran/downstream/CMakeLists.txt b/tests/projects/openmp-cpp-fortran/downstream/CMakeLists.txt index 218c73ba6..33faba0e7 100644 --- a/tests/projects/openmp-cpp-fortran/downstream/CMakeLists.txt +++ b/tests/projects/openmp-cpp-fortran/downstream/CMakeLists.txt @@ -1,3 +1,10 @@ +# Clear variables set in the host-config so we can test that they are inherited +# from the upstream project +foreach(_option MPI CUDA HIP OPENMP) + unset(ENABLE_${_option} CACHE) + unset(ENABLE_${_option}) +endforeach() + cmake_minimum_required(VERSION 3.14) project(openmp-cpp-fortran-user LANGUAGES CXX Fortran) diff --git a/tests/projects/openmp-mpi-cpp/downstream/CMakeLists.txt b/tests/projects/openmp-mpi-cpp/downstream/CMakeLists.txt index f7a77b2a2..6dc205598 100644 --- a/tests/projects/openmp-mpi-cpp/downstream/CMakeLists.txt +++ b/tests/projects/openmp-mpi-cpp/downstream/CMakeLists.txt @@ -1,3 +1,10 @@ +# Clear variables set in the host-config so we can test that they are inherited +# from the upstream project +foreach(_option MPI CUDA HIP OPENMP) + unset(ENABLE_${_option} CACHE) + unset(ENABLE_${_option}) +endforeach() + cmake_minimum_required(VERSION 3.14) project(openmp-mpi-cpp-user LANGUAGES CXX) diff --git a/tests/projects/run_tests.py b/tests/projects/run_tests.py old mode 100644 new mode 100755 index 23f5a7f57..4ef01f978 --- a/tests/projects/run_tests.py +++ b/tests/projects/run_tests.py @@ -1,217 +1,218 @@ -#!/bin/sh -"exec" "python3" "-u" "-B" "$0" "$@" -# Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and -# other BLT Project Developers. See the top-level LICENSE file for details -# -# SPDX-License-Identifier: (BSD-3-Clause) - -import os -import sys -import subprocess -import glob -import re -import argparse -import string -import shutil - -from functools import partial - -# Since we use subprocesses, flushing prints allows us to keep logs in -# order. -print = partial(print, flush=True) - -def sexe(cmd): - """ Helper for executing shell commands. """ - p = subprocess.Popen(cmd, - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - out = p.communicate()[0] - out = out.decode('utf8') - return p.returncode, out - -def cmake_build_project(path_to_test: string, blt_source_dir: string, host_config: string, is_base: bool, verbose=False): - base_or_downstream = "base" if is_base else "downstream" - install_flag = "-DCMAKE_INSTALL_PREFIX" if is_base else "-Dbase_install_dir" - blt_path_flag = "-DBLT_SOURCE_DIR" - - # Convert these paths to absolute paths to avoid CMake seeing an incorrect relative path. - source_path = os.path.abspath(os.path.join(path_to_test, base_or_downstream)) - build_path = os.path.abspath(os.path.join(source_path, "build")) - install_path = os.path.abspath(os.path.join(path_to_test, "tmp_install_dir")) - - # Projects in this directory follow a base/downstream format, where base files - # are built and installed, and downstream projects are fed their install path. - # If a base project is being built, feed CMake the path to install the built - # project. - # If a downstream project is being built, feed CMake the base install path. - cmake_command = "cmake -DENABLE_GTEST=Off -B {0} -S {1} {2}={3} {4}={5}".format( - build_path, source_path, install_flag, install_path, blt_path_flag, blt_source_dir) - if host_config is not None and os.path.exists(host_config): - cmake_command += " -C {0}".format(host_config) - - build_command = "cmake --build {0}".format(build_path) - install_command = "cmake --install {0}".format(build_path) - # cmake, build and install the base project. - code, err = sexe(cmake_command) - if code: - return code, err - elif verbose: - print(err) - code, err = sexe(build_command) - if code: - return code, err - elif verbose: - print(err) - if is_base: - code, err = sexe(install_command) - if verbose: - print(err) - if code: - return code, err - elif verbose: - print(err) - - return 0, "Success" - -def clean_helper(path_to_test: string): - shutil.rmtree(os.path.join(path_to_test, "base", "build")) - shutil.rmtree(os.path.join(path_to_test, "downstream", "build")) - shutil.rmtree(os.path.join(path_to_test, "tmp_install_dir")) - -def run_test(path_to_test: string, blt_source_dir: string, host_config: string, verbose=False, clean=False): - """ Run test, using a yaml to specify CMake arguments """ - # CMake, Build and install base - code, err = cmake_build_project(path_to_test, blt_source_dir, host_config, True, verbose) - if code: - if clean: - shutil.rmtree(os.path.join(path_to_test, "base", "build")) - return code, err - # CMake, build downstream - code, err = cmake_build_project(path_to_test, blt_source_dir, host_config, False, verbose) - - if clean: - clean_helper(path_to_test) - - if code: - return code, err - - return 0, "Test {0} passed".format(path_to_test) - -def parse_args(): - "Parses args from command line" - parser = argparse.ArgumentParser() - parser.add_argument("--host-config", - dest="host-config", - default=None, - help="Host config file to be used by all test projects.") - - # Where to find BLT - parser.add_argument("--blt-source-dir", - dest="blt-source-dir", - default=None, - help="Path to BLT source to be used by all test projects.") - - # Verbose mode: useful for debugging. - parser.add_argument("--verbose", - action='store_true', - dest="verbose", - help="Print all stdout and stderr from running tests.") - - # Specify a subset of tests to run. Useful for debugging - parser.add_argument("--run-test", - default=None, - dest="run-test", - help="Comma delimited list of tests to run. Test names must be a subset of the " - "list of directories inside test. Only run tests specified.") - - # Specify whether to clean build and install directories - parser.add_argument("--clean", - action='store_true', - help="Remove build and install paths from test directories.") - - args, extra_args = parser.parse_known_args() - args = vars(args) - - if not args["blt-source-dir"]: - print("[ERROR: Required command line argument, 'blt-source-dir', was not provided.]") - return None - - if args["host-config"] is not None and not os.path.exists(args["host-config"]): - print("ERROR: Host config file {0} specified, but file does not exist.".format(args["host-config"])) - return None - - if args["run-test"] is not None: - all_tests = set(os.listdir(os.path.relpath("."))) - user_tests = set(args["run-test"].split(",")) - if not user_tests.issubset(all_tests): - user_tests_str = ", ".join(user_tests.difference(all_tests)) - print("ERROR: Specified test(s) {0}, but test(s) do not exist inside the test directory.".format(user_tests_str)) - return None - - if args["verbose"] is True: - print("Running tests verbosely") - - # Pretty print given args - print("========================================") - print("Command line arguments:") - for key in args.keys(): - print("[{0}]: {1}".format(key, args[key])) - print("========================================") - - return args - -def should_test_run(name, path, hostconfig): - run_test = True - #TODO: read regexs (?) from yaml file that show whether we should run the test - # and run them over the given host-config. - # for example, ENABLE_CUDA being ON, if none are present just run test always - return run_test - -def main(): - args = parse_args() - if not args: - return 1 - - # Iterate through the tests, run them, and report error if encountered. - tests = [] - blt_source_dir = args["blt-source-dir"] - host_config = args["host-config"] - verbose = args["verbose"] - clean = args["clean"] - - failed_tests = [] - tests_dir = os.path.relpath(".") - tests_to_run = os.listdir(tests_dir) - # Run only a subset of tests if specified. - if args["run-test"] is not None: - tests_to_run = args["run-test"].split(",") - - print("Running tests {0}".format(", ".join(tests_to_run))) - - for test_dir in tests_to_run: - path_to_test_dir = os.path.join(tests_dir, test_dir) - if not os.path.isdir(path_to_test_dir): - print(path_to_test_dir) - continue - tests.append(test_dir) - status, err = run_test(path_to_test_dir, blt_source_dir, host_config, verbose, clean) - print(err) - if status: - print("Test {0} failed with error {1}".format(test_dir, err)) - failed_tests.append(test_dir) - - # Print final status - if len(failed_tests) == 0: - print("[Success! All tests passed!]") - else: - print("[ERROR: The following {0} out of {1} tests failed:".format(len(failed_tests), len(tests))) - for name in failed_tests: - print(" {0}".format(name)) - print("]") - return 1 - - return 0 - -if __name__ == "__main__": - sys.exit(main()) +#!/bin/sh +"exec" "python3" "-u" "-B" "$0" "$@" + +# Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level LICENSE file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +import os +import sys +import subprocess +import glob +import re +import argparse +import string +import shutil + +from functools import partial + +# Since we use subprocesses, flushing prints allows us to keep logs in +# order. +print = partial(print, flush=True) + +def sexe(cmd): + """ Helper for executing shell commands. """ + p = subprocess.Popen(cmd, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + out = p.communicate()[0] + out = out.decode('utf8') + return p.returncode, out + +def cmake_build_project(path_to_test: string, blt_source_dir: string, host_config: string, is_base: bool, verbose=False): + base_or_downstream = "base" if is_base else "downstream" + install_flag = "-DCMAKE_INSTALL_PREFIX" if is_base else "-Dbase_install_dir" + blt_path_flag = "-DBLT_SOURCE_DIR" + + # Convert these paths to absolute paths to avoid CMake seeing an incorrect relative path. + source_path = os.path.abspath(os.path.join(path_to_test, base_or_downstream)) + build_path = os.path.abspath(os.path.join(source_path, "build")) + install_path = os.path.abspath(os.path.join(path_to_test, "tmp_install_dir")) + + # Projects in this directory follow a base/downstream format, where base files + # are built and installed, and downstream projects are fed their install path. + # If a base project is being built, feed CMake the path to install the built + # project. + # If a downstream project is being built, feed CMake the base install path. + cmake_command = "cmake -DENABLE_GTEST=Off -B {0} -S {1} {2}={3} {4}={5}".format( + build_path, source_path, install_flag, install_path, blt_path_flag, blt_source_dir) + if host_config is not None and os.path.exists(host_config): + cmake_command += " -C {0}".format(host_config) + + build_command = "cmake --build {0}".format(build_path) + install_command = "cmake --install {0}".format(build_path) + # cmake, build and install the base project. + code, err = sexe(cmake_command) + if code: + return code, err + elif verbose: + print(err) + code, err = sexe(build_command) + if code: + return code, err + elif verbose: + print(err) + if is_base: + code, err = sexe(install_command) + if verbose: + print(err) + if code: + return code, err + elif verbose: + print(err) + + return 0, "Success" + +def clean_helper(path_to_test: string): + shutil.rmtree(os.path.join(path_to_test, "base", "build")) + shutil.rmtree(os.path.join(path_to_test, "downstream", "build")) + shutil.rmtree(os.path.join(path_to_test, "tmp_install_dir")) + +def run_test(path_to_test: string, blt_source_dir: string, host_config: string, verbose=False, clean=False): + """ Run test, using a yaml to specify CMake arguments """ + # CMake, Build and install base + code, err = cmake_build_project(path_to_test, blt_source_dir, host_config, True, verbose) + if code: + if clean: + shutil.rmtree(os.path.join(path_to_test, "base", "build")) + return code, err + # CMake, build downstream + code, err = cmake_build_project(path_to_test, blt_source_dir, host_config, False, verbose) + + if clean: + clean_helper(path_to_test) + + if code: + return code, err + + return 0, "Test {0} passed".format(path_to_test) + +def parse_args(): + "Parses args from command line" + parser = argparse.ArgumentParser() + parser.add_argument("--host-config", + dest="host-config", + default=None, + help="Host config file to be used by all test projects.") + + # Where to find BLT + parser.add_argument("--blt-source-dir", + dest="blt-source-dir", + default=None, + help="Path to BLT source to be used by all test projects.") + + # Verbose mode: useful for debugging. + parser.add_argument("--verbose", + action='store_true', + dest="verbose", + help="Print all stdout and stderr from running tests.") + + # Specify a subset of tests to run. Useful for debugging + parser.add_argument("--run-test", + default=None, + dest="run-test", + help="Comma delimited list of tests to run. Test names must be a subset of the " + "list of directories inside test. Only run tests specified.") + + # Specify whether to clean build and install directories + parser.add_argument("--clean", + action='store_true', + help="Remove build and install paths from test directories.") + + args, extra_args = parser.parse_known_args() + args = vars(args) + + if not args["blt-source-dir"]: + print("[ERROR: Required command line argument, 'blt-source-dir', was not provided.]") + return None + + if args["host-config"] is not None and not os.path.exists(args["host-config"]): + print("ERROR: Host config file {0} specified, but file does not exist.".format(args["host-config"])) + return None + + if args["run-test"] is not None: + all_tests = set(os.listdir(os.path.relpath("."))) + user_tests = set(args["run-test"].split(",")) + if not user_tests.issubset(all_tests): + user_tests_str = ", ".join(user_tests.difference(all_tests)) + print("ERROR: Specified test(s) {0}, but test(s) do not exist inside the test directory.".format(user_tests_str)) + return None + + if args["verbose"] is True: + print("Running tests verbosely") + + # Pretty print given args + print("========================================") + print("Command line arguments:") + for key in args.keys(): + print("[{0}]: {1}".format(key, args[key])) + print("========================================") + + return args + +def should_test_run(name, path, hostconfig): + run_test = True + #TODO: read regexs (?) from yaml file that show whether we should run the test + # and run them over the given host-config. + # for example, ENABLE_CUDA being ON, if none are present just run test always + return run_test + +def main(): + args = parse_args() + if not args: + return 1 + + # Iterate through the tests, run them, and report error if encountered. + tests = [] + blt_source_dir = args["blt-source-dir"] + host_config = args["host-config"] + verbose = args["verbose"] + clean = args["clean"] + + failed_tests = [] + tests_dir = os.path.relpath(".") + tests_to_run = os.listdir(tests_dir) + # Run only a subset of tests if specified. + if args["run-test"] is not None: + tests_to_run = args["run-test"].split(",") + + print("Running tests {0}".format(", ".join(tests_to_run))) + + for test_dir in tests_to_run: + path_to_test_dir = os.path.join(tests_dir, test_dir) + if not os.path.isdir(path_to_test_dir): + print(path_to_test_dir) + continue + tests.append(test_dir) + status, err = run_test(path_to_test_dir, blt_source_dir, host_config, verbose, clean) + print(err) + if status: + print("Test {0} failed with error {1}".format(test_dir, err)) + failed_tests.append(test_dir) + + # Print final status + if len(failed_tests) == 0: + print("[Success! All tests passed!]") + else: + print("[ERROR: The following {0} out of {1} tests failed:".format(len(failed_tests), len(tests))) + for name in failed_tests: + print(" {0}".format(name)) + print("]") + return 1 + + return 0 + +if __name__ == "__main__": + sys.exit(main())