From d6be117ca06154bdf9f0b72c6159a496da1646f7 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Tue, 16 Jul 2019 14:13:43 -0400 Subject: ExternalProject: Support not initializing any submodules Fixes #15592 --- Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0097.rst | 23 ++++++++ .../external-project-support-no-git-submodules.rst | 6 ++ Modules/ExternalProject.cmake | 68 ++++++++++++++++------ Source/cmPolicies.h | 6 +- Tests/ExternalProject/CMakeLists.txt | 21 ++++++- 6 files changed, 104 insertions(+), 21 deletions(-) create mode 100644 Help/policy/CMP0097.rst create mode 100644 Help/release/dev/external-project-support-no-git-submodules.rst diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 6bdabaf..44ea1a8 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.16 .. toctree:: :maxdepth: 1 + CMP0097: ExternalProject_Add with GIT_SUBMODULES "" initializes no submodules. CMP0096: project() preserves leading zeros in version components. CMP0095: RPATH entries are properly escaped in the intermediary CMake install script. diff --git a/Help/policy/CMP0097.rst b/Help/policy/CMP0097.rst new file mode 100644 index 0000000..8a5ff88 --- /dev/null +++ b/Help/policy/CMP0097.rst @@ -0,0 +1,23 @@ +CMP0097 +------- + +:command:`ExternalProject_Add` with ``GIT_SUBMODULES ""`` initializes no +submodules. + +The module provides a ``GIT_SUBMODULES`` option which controls what submodules +to initialize and update. Starting with CMake 3.16, explicitly setting +``GIT_SUBMODULES`` to an empty string means no submodules will be initialized +or updated. + +This policy provides compatibility for projects that have not been updated +to expect the new behavior. + +The ``OLD`` behavior for this policy is for ``GIT_SUBMODULES`` when set to +an empty string to initialize and update all git submodules. +The ``New`` behavior for this policy is for ``GIT_SUBMODULES`` when set to +an empty string to initialize and update no git submodules. + +This policy was introduced in CMake version 3.16. Use the +:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. +Unlike most policies, CMake version |release| does *not* warn +when this policy is not set and simply uses ``OLD`` behavior. diff --git a/Help/release/dev/external-project-support-no-git-submodules.rst b/Help/release/dev/external-project-support-no-git-submodules.rst new file mode 100644 index 0000000..1d4be66 --- /dev/null +++ b/Help/release/dev/external-project-support-no-git-submodules.rst @@ -0,0 +1,6 @@ +external-project-support-no-git-submodules +------------------------------------------ + +* The :module:`ExternalProject` module's ``ExternalProject_Add`` command + has been updated so that ``GIT_SUBMODULES ""`` initializes no submodules. See + policy :policy:`CMP0097`. diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 20b37d2..14fc231 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -261,7 +261,9 @@ External Project Definition ``GIT_SUBMODULES ...`` Specific git submodules that should also be updated. If this option is - not provided, all git submodules will be updated. + not provided, all git submodules will be updated. When :policy:`CMP0097` + is set to ``NEW`` if this value is set to an empty string then no submodules + are initialized or updated. ``GIT_SHALLOW `` When this option is enabled, the ``git clone`` operation will be given @@ -1016,6 +1018,9 @@ function(_ep_parse_arguments f name ns args) endif() else() set(key "${arg}") + if(key MATCHES GIT) + get_property(have_key TARGET ${name} PROPERTY ${ns}${key} SET) + endif() endif() endforeach() endfunction() @@ -1060,7 +1065,7 @@ define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED "ExternalProject module." ) -function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name git_submodules git_shallow git_progress git_config src_name work_dir gitclone_infofile gitclone_stampfile tls_verify) +function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name init_submodules git_submodules git_shallow git_progress git_config src_name work_dir gitclone_infofile gitclone_stampfile tls_verify) if(NOT GIT_VERSION_STRING VERSION_LESS 1.8.5) # Use `git checkout --` to avoid ambiguity with a local path. set(git_checkout_explicit-- "--") @@ -1145,11 +1150,14 @@ if(error_code) message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\") endif() -execute_process( - COMMAND \"${git_EXECUTABLE}\" ${git_options} submodule update --recursive --init ${git_submodules} - WORKING_DIRECTORY \"${work_dir}/${src_name}\" - RESULT_VARIABLE error_code - ) +set(init_submodules ${init_submodules}) +if(init_submodules) + execute_process( + COMMAND \"${git_EXECUTABLE}\" ${git_options} submodule update --recursive --init ${git_submodules} + WORKING_DIRECTORY \"${work_dir}/${src_name}\" + RESULT_VARIABLE error_code + ) +endif() if(error_code) message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\") endif() @@ -1226,7 +1234,7 @@ endif() endfunction() -function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name git_submodules git_repository work_dir) +function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name init_submodules git_submodules git_repository work_dir) if("${git_tag}" STREQUAL "") message(FATAL_ERROR "Tag for git checkout should not be empty.") endif() @@ -1383,11 +1391,14 @@ if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\" endif() endif() - execute_process( - COMMAND \"${git_EXECUTABLE}\" submodule update --recursive --init ${git_submodules} - WORKING_DIRECTORY \"${work_dir}/${src_name}\" - RESULT_VARIABLE error_code - ) + set(init_submodules ${init_submodules}) + if(init_submodules) + execute_process( + COMMAND \"${git_EXECUTABLE}\" submodule update --recursive --init ${git_submodules} + WORKING_DIRECTORY \"${work_dir}/${src_name}\" + RESULT_VARIABLE error_code + ) + endif() if(error_code) message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\") endif() @@ -1972,7 +1983,7 @@ endif() set(stderr_log "${logbase}-err.log") endif() set(code " -cmake_minimum_required(VERSION 3.13) +cmake_minimum_required(VERSION 3.15) ${code_cygpath_make} set(command \"${command}\") set(log_merged \"${log_merged}\") @@ -2420,7 +2431,15 @@ function(_ep_add_download_command name) if(NOT git_tag) set(git_tag "master") endif() - get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES) + + set(git_init_submodules TRUE) + get_property(git_submodules_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES SET) + if(git_submodules_set) + get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES) + if(git_submodules STREQUAL "" AND _EP_CMP0097 STREQUAL "NEW") + set(git_init_submodules FALSE) + endif() + endif() get_property(git_remote_name TARGET ${name} PROPERTY _EP_GIT_REMOTE_NAME) if(NOT git_remote_name) @@ -2458,7 +2477,7 @@ function(_ep_add_download_command name) # The script will delete the source directory and then call git clone. # _ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir} - ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir} + ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir} ${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt "${tls_verify}" ) set(comment "Performing download step (git clone) for '${name}'") @@ -2723,9 +2742,18 @@ function(_ep_add_update_command name) if(NOT git_remote_name) set(git_remote_name "origin") endif() - get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES) + + set(git_init_submodules TRUE) + get_property(git_submodules_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES SET) + if(git_submodules_set) + get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES) + if(git_submodules STREQUAL "" AND _EP_CMP0097 STREQUAL "NEW") + set(git_init_submodules FALSE) + endif() + endif() + _ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake - ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} "${git_submodules}" ${git_repository} ${work_dir} + ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules}" ${git_repository} ${work_dir} ) set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake) set(always 1) @@ -3138,6 +3166,10 @@ endfunction() function(ExternalProject_Add name) + cmake_policy(GET CMP0097 _EP_CMP0097 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + _ep_get_configuration_subdir_suffix(cfgdir) # Add a custom target for the external project. diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index e0f48de..92c80bb 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -286,7 +286,11 @@ class cmMakefile; 3, 16, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0096, \ "project() preserves leading zeros in version components.", 3, 16, \ - 0, cmPolicies::WARN) + 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0097, \ + "ExternalProject_Add with GIT_SUBMODULES \"\" initializes no " \ + "submodules.", \ + 3, 16, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt index 5adcbd9..093391e 100644 --- a/Tests/ExternalProject/CMakeLists.txt +++ b/Tests/ExternalProject/CMakeLists.txt @@ -421,7 +421,7 @@ if(do_git_tests) set(local_git_repo "../../LocalRepositories/GIT-with-submodules") - set(proj TS1-GIT-no-GIT_SUBMODULES) + set(proj TS1-GIT-all-GIT_SUBMODULES) ExternalProject_Add(${proj} GIT_REPOSITORY "${local_git_repo}" CMAKE_GENERATOR "${CMAKE_GENERATOR}" @@ -435,7 +435,8 @@ if(do_git_tests) ) set_property(TARGET ${proj} PROPERTY FOLDER "GIT") - set(proj TS1-GIT-empty-GIT_SUBMODULES) + set(proj TS1-GIT-all-GIT_SUBMODULES-via-CMP0097-OLD) + cmake_policy(SET CMP0097 OLD) ExternalProject_Add(${proj} GIT_REPOSITORY "${local_git_repo}" GIT_SUBMODULES "" @@ -450,6 +451,22 @@ if(do_git_tests) ) set_property(TARGET ${proj} PROPERTY FOLDER "GIT") + set(proj TS1-GIT-no-GIT_SUBMODULES) + cmake_policy(SET CMP0097 NEW) + ExternalProject_Add(${proj} + GIT_REPOSITORY "${local_git_repo}" + GIT_SUBMODULES "" + CMAKE_GENERATOR "${CMAKE_GENERATOR}" + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= + -DWITH_m1:BOOL=OFF + -DWITH_m2:BOOL=OFF + BUILD_COMMAND "" + INSTALL_COMMAND "" + DEPENDS "SetupLocalGITRepository" + "SetupLocalGITRepositoryWithSubmodules" + ) + set_property(TARGET ${proj} PROPERTY FOLDER "GIT") + set(proj TS1-GIT-some-GIT_SUBMODULES) ExternalProject_Add(${proj} GIT_REPOSITORY "${local_git_repo}" -- cgit v0.12