diff --git a/scripts/cmake/CPM.cmake b/scripts/cmake/CPM.cmake index 2e3767633eb..5cb076f180f 100644 --- a/scripts/cmake/CPM.cmake +++ b/scripts/cmake/CPM.cmake @@ -5,7 +5,7 @@ # MIT License # ----------- #[[ - Copyright (c) 2019-2022 Lars Melchior and contributors + Copyright (c) 2019-2023 Lars Melchior and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -42,7 +42,7 @@ if(NOT COMMAND cpm_message) endfunction() endif() -set(CURRENT_CPM_VERSION 0.38.2) +set(CURRENT_CPM_VERSION 0.40.1) get_filename_component(CPM_CURRENT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" REALPATH) if(CPM_DIRECTORY) @@ -99,6 +99,12 @@ macro(cpm_set_policies) cmake_policy(SET CMP0135 NEW) set(CMAKE_POLICY_DEFAULT_CMP0135 NEW) endif() + + # treat relative git repository paths as being relative to the parent project's remote + if(POLICY CMP0150) + cmake_policy(SET CMP0150 NEW) + set(CMAKE_POLICY_DEFAULT_CMP0150 NEW) + endif() endmacro() cpm_set_policies() @@ -294,12 +300,6 @@ function(CPMFindPackage) return() endif() - cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}") - if(CPM_PACKAGE_ALREADY_ADDED) - cpm_export_variables(${CPM_ARGS_NAME}) - return() - endif() - cpm_find_package(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" ${CPM_ARGS_FIND_PACKAGE_ARGUMENTS}) if(NOT CPM_PACKAGE_FOUND) @@ -391,8 +391,8 @@ function(cpm_parse_add_package_single_arg arg outArgs) # We don't try to parse the version if it's not provided explicitly. cpm_get_version_from_url # should do this at a later point else() - # We should never get here. This is an assertion and hitting it means there's a bug in the code - # above. A packageType was set, but not handled by this if-else. + # We should never get here. This is an assertion and hitting it means there's a problem with the + # code above. A packageType was set, but not handled by this if-else. message(FATAL_ERROR "${CPM_INDENT} Unsupported package type '${packageType}' of '${arg}'") endif() @@ -464,6 +464,69 @@ function(cpm_check_git_working_dir_is_clean repoPath gitTag isClean) endfunction() +# Add PATCH_COMMAND to CPM_ARGS_UNPARSED_ARGUMENTS. This method consumes a list of files in ARGN +# then generates a `PATCH_COMMAND` appropriate for `ExternalProject_Add()`. This command is appended +# to the parent scope's `CPM_ARGS_UNPARSED_ARGUMENTS`. +function(cpm_add_patches) + # Return if no patch files are supplied. + if(NOT ARGN) + return() + endif() + + # Find the patch program. + find_program(PATCH_EXECUTABLE patch) + if(WIN32 AND NOT PATCH_EXECUTABLE) + # The Windows git executable is distributed with patch.exe. Find the path to the executable, if + # it exists, then search `../../usr/bin` for patch.exe. + find_package(Git QUIET) + if(GIT_EXECUTABLE) + get_filename_component(extra_search_path ${GIT_EXECUTABLE} DIRECTORY) + get_filename_component(extra_search_path ${extra_search_path} DIRECTORY) + get_filename_component(extra_search_path ${extra_search_path} DIRECTORY) + find_program(PATCH_EXECUTABLE patch HINTS "${extra_search_path}/usr/bin") + endif() + endif() + if(NOT PATCH_EXECUTABLE) + message(FATAL_ERROR "Couldn't find `patch` executable to use with PATCHES keyword.") + endif() + + # Create a temporary + set(temp_list ${CPM_ARGS_UNPARSED_ARGUMENTS}) + + # Ensure each file exists (or error out) and add it to the list. + set(first_item True) + foreach(PATCH_FILE ${ARGN}) + # Make sure the patch file exists, if we can't find it, try again in the current directory. + if(NOT EXISTS "${PATCH_FILE}") + if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${PATCH_FILE}") + message(FATAL_ERROR "Couldn't find patch file: '${PATCH_FILE}'") + endif() + set(PATCH_FILE "${CMAKE_CURRENT_LIST_DIR}/${PATCH_FILE}") + endif() + + # Convert to absolute path for use with patch file command. + get_filename_component(PATCH_FILE "${PATCH_FILE}" ABSOLUTE) + + # The first patch entry must be preceded by "PATCH_COMMAND" while the following items are + # preceded by "&&". + if(first_item) + set(first_item False) + list(APPEND temp_list "PATCH_COMMAND") + else() + list(APPEND temp_list "&&") + endif() + # Add the patch command to the list + list(APPEND temp_list "${PATCH_EXECUTABLE}" "-p1" "<" "${PATCH_FILE}") + endforeach() + + # Move temp out into parent scope. + set(CPM_ARGS_UNPARSED_ARGUMENTS + ${temp_list} + PARENT_SCOPE + ) + +endfunction() + # method to overwrite internal FetchContent properties, to allow using CPM.cmake to overload # FetchContent calls. As these are internal cmake properties, this method should be used carefully # and may need modification in future CMake versions. Source: @@ -528,16 +591,16 @@ function(CPMAddPackage) BITBUCKET_REPOSITORY GIT_REPOSITORY SOURCE_DIR - DOWNLOAD_COMMAND FIND_PACKAGE_ARGUMENTS NO_CACHE SYSTEM GIT_SHALLOW EXCLUDE_FROM_ALL SOURCE_SUBDIR + CUSTOM_CACHE_KEY ) - set(multiValueArgs URL OPTIONS) + set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND PATCHES) cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}") @@ -628,6 +691,7 @@ function(CPMAddPackage) SOURCE_DIR "${PACKAGE_SOURCE}" EXCLUDE_FROM_ALL "${CPM_ARGS_EXCLUDE_FROM_ALL}" SYSTEM "${CPM_ARGS_SYSTEM}" + PATCHES "${CPM_ARGS_PATCHES}" OPTIONS "${CPM_ARGS_OPTIONS}" SOURCE_SUBDIR "${CPM_ARGS_SOURCE_SUBDIR}" DOWNLOAD_ONLY "${DOWNLOAD_ONLY}" @@ -683,6 +747,8 @@ function(CPMAddPackage) set(CPM_FETCHCONTENT_BASE_DIR ${CMAKE_BINARY_DIR}/_deps) endif() + cpm_add_patches(${CPM_ARGS_PATCHES}) + if(DEFINED CPM_ARGS_DOWNLOAD_COMMAND) list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS DOWNLOAD_COMMAND ${CPM_ARGS_DOWNLOAD_COMMAND}) elseif(DEFINED CPM_ARGS_SOURCE_DIR) @@ -705,7 +771,10 @@ function(CPMAddPackage) string(TOLOWER ${CPM_ARGS_NAME} lower_case_name) set(origin_parameters ${CPM_ARGS_UNPARSED_ARGUMENTS}) list(SORT origin_parameters) - if(CPM_USE_NAMED_CACHE_DIRECTORIES) + if(CPM_ARGS_CUSTOM_CACHE_KEY) + # Application set a custom unique directory name + set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${CPM_ARGS_CUSTOM_CACHE_KEY}) + elseif(CPM_USE_NAMED_CACHE_DIRECTORIES) string(SHA1 origin_hash "${origin_parameters};NEW_CACHE_STRUCTURE_TAG") set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${origin_hash}/${CPM_ARGS_NAME}) else() @@ -793,14 +862,38 @@ function(CPMAddPackage) ) if(NOT CPM_SKIP_FETCH) + # CMake 3.28 added EXCLUDE, SYSTEM (3.25), and SOURCE_SUBDIR (3.18) to FetchContent_Declare. + # Calling FetchContent_MakeAvailable will then internally forward these options to + # add_subdirectory. Up until these changes, we had to call FetchContent_Populate and + # add_subdirectory separately, which is no longer necessary and has been deprecated as of 3.30. + set(fetchContentDeclareExtraArgs "") + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0") + if(${CPM_ARGS_EXCLUDE_FROM_ALL}) + list(APPEND fetchContentDeclareExtraArgs EXCLUDE_FROM_ALL) + endif() + if(${CPM_ARGS_SYSTEM}) + list(APPEND fetchContentDeclareExtraArgs SYSTEM) + endif() + if(DEFINED CPM_ARGS_SOURCE_SUBDIR) + list(APPEND fetchContentDeclareExtraArgs SOURCE_SUBDIR ${CPM_ARGS_SOURCE_SUBDIR}) + endif() + # For CMake version <3.28 OPTIONS are parsed in cpm_add_subdirectory + if(CPM_ARGS_OPTIONS AND NOT DOWNLOAD_ONLY) + foreach(OPTION ${CPM_ARGS_OPTIONS}) + cpm_parse_option("${OPTION}") + set(${OPTION_KEY} "${OPTION_VALUE}") + endforeach() + endif() + endif() cpm_declare_fetch( - "${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}" "${PACKAGE_INFO}" "${CPM_ARGS_UNPARSED_ARGUMENTS}" + "${CPM_ARGS_NAME}" ${fetchContentDeclareExtraArgs} "${CPM_ARGS_UNPARSED_ARGUMENTS}" ) - cpm_fetch_package("${CPM_ARGS_NAME}" populated) + + cpm_fetch_package("${CPM_ARGS_NAME}" ${DOWNLOAD_ONLY} populated ${CPM_ARGS_UNPARSED_ARGUMENTS}) if(CPM_SOURCE_CACHE AND download_directory) file(LOCK ${download_directory}/../cmake.lock RELEASE) endif() - if(${populated}) + if(${populated} AND ${CMAKE_VERSION} VERSION_LESS "3.28.0") cpm_add_subdirectory( "${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}" @@ -911,7 +1004,7 @@ function(CPMGetPackageVersion PACKAGE OUTPUT) endfunction() # declares a package in FetchContent_Declare -function(cpm_declare_fetch PACKAGE VERSION INFO) +function(cpm_declare_fetch PACKAGE) if(${CPM_DRY_RUN}) cpm_message(STATUS "${CPM_INDENT} Package not declared (dry run)") return() @@ -987,7 +1080,7 @@ endfunction() # downloads a previously declared package via FetchContent and exports the variables # `${PACKAGE}_SOURCE_DIR` and `${PACKAGE}_BINARY_DIR` to the parent scope -function(cpm_fetch_package PACKAGE populated) +function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY populated) set(${populated} FALSE PARENT_SCOPE @@ -1002,7 +1095,24 @@ function(cpm_fetch_package PACKAGE populated) string(TOLOWER "${PACKAGE}" lower_case_name) if(NOT ${lower_case_name}_POPULATED) - FetchContent_Populate(${PACKAGE}) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0") + if(DOWNLOAD_ONLY) + # MakeAvailable will call add_subdirectory internally which is not what we want when + # DOWNLOAD_ONLY is set. Populate will only download the dependency without adding it to the + # build + FetchContent_Populate( + ${PACKAGE} + SOURCE_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-src" + BINARY_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-build" + SUBBUILD_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-subbuild" + ${ARGN} + ) + else() + FetchContent_MakeAvailable(${PACKAGE}) + endif() + else() + FetchContent_Populate(${PACKAGE}) + endif() set(${populated} TRUE PARENT_SCOPE @@ -1096,15 +1206,17 @@ function(cpm_prettify_package_arguments OUT_VAR IS_IN_COMMENT) DOWNLOAD_ONLY GITHUB_REPOSITORY GITLAB_REPOSITORY + BITBUCKET_REPOSITORY GIT_REPOSITORY SOURCE_DIR - DOWNLOAD_COMMAND FIND_PACKAGE_ARGUMENTS NO_CACHE SYSTEM GIT_SHALLOW + EXCLUDE_FROM_ALL + SOURCE_SUBDIR ) - set(multiValueArgs OPTIONS) + set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND) cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) foreach(oneArgName ${oneValueArgs}) diff --git a/scripts/cmake/Dependencies.cmake b/scripts/cmake/Dependencies.cmake index 09761b4decb..357ed756c01 100644 --- a/scripts/cmake/Dependencies.cmake +++ b/scripts/cmake/Dependencies.cmake @@ -171,7 +171,9 @@ if(OGS_USE_MFRONT) GIT_TAG rliv-2.0 OPTIONS "enable-doxygen-doc OFF" "enable-fortran-bindings OFF" "enable-website OFF" - EXCLUDE_FROM_ALL YES SYSTEM TRUE + EXCLUDE_FROM_ALL + YES SYSTEM TRUE PATCHES + ${PROJECT_SOURCE_DIR}/scripts/cmake/mgis-flags.patch ) list(APPEND DISABLE_WARNINGS_TARGETS MFrontGenericInterface) endif() @@ -355,7 +357,7 @@ if(NOT (GUIX_BUILD OR CONDA_BUILD)) if((OGS_BUILD_TESTING OR OGS_BUILD_UTILS)) CPMAddPackage( NAME vtkdiff GITHUB_REPOSITORY ufz/vtkdiff - GIT_TAG 9754b4da43c6adfb65d201ed920b5f6ea27b38b9 + GIT_TAG 7cc474101bcee45804124df8010a2275022e2f3b ) if(vtkdiff_ADDED) install(PROGRAMS $ DESTINATION bin) diff --git a/scripts/cmake/mgis-flags.patch b/scripts/cmake/mgis-flags.patch new file mode 100644 index 00000000000..eed2c72ec87 --- /dev/null +++ b/scripts/cmake/mgis-flags.patch @@ -0,0 +1,13 @@ +diff --git a/cmake/modules/common-compiler-flags.cmake b/cmake/modules/common-compiler-flags.cmake +index 12fd730..bcc978b 100644 +--- a/cmake/modules/common-compiler-flags.cmake ++++ b/cmake/modules/common-compiler-flags.cmake +@@ -61,8 +61,6 @@ else(enable-developer-warnings) + tfel_enable_cxx_compiler_flag(COMPILER_WARNINGS "Wno-missing-declarations") + tfel_enable_cxx_compiler_flag(COMPILER_WARNINGS "Wno-weak-vtables") + tfel_enable_cxx_compiler_flag(COMPILER_WARNINGS "Wno-unused-macros") +- tfel_enable_cxx_compiler_flag(COMPILER_WARNINGS +- "Wno-missing-variable-declarations") + endif(enable-developer-warnings) + +