summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/policy/CMP0114.rst85
-rw-r--r--Help/release/dev/ExternalProject-steps-refinement.rst5
-rw-r--r--Modules/ExternalProject.cmake278
-rw-r--r--Source/cmPolicies.h5
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies-stderr.txt12
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target-stderr.txt12
-rw-r--r--Tests/RunCMake/ExternalProject/BadIndependentStep1-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/BadIndependentStep1-stderr.txt7
-rw-r--r--Tests/RunCMake/ExternalProject/BadIndependentStep1.cmake14
-rw-r--r--Tests/RunCMake/ExternalProject/BadIndependentStep2-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/BadIndependentStep2-stderr.txt7
-rw-r--r--Tests/RunCMake/ExternalProject/BadIndependentStep2.cmake13
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-Common.cmake (renamed from Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake)1
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct-stderr.txt7
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct.cmake4
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-stderr.txt16
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW.cmake2
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-OLD-stderr.txt (renamed from Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt)12
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-OLD.cmake2
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN-stderr.txt119
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN.cmake2
-rw-r--r--Tests/RunCMake/ExternalProject/RunCMakeTest.cmake37
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-Common.cmake34
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-download-check.cmake3
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-install-check.cmake3
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-test-check.cmake2
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-update-check.cmake3
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW.cmake2
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-download-check.cmake3
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-install-check.cmake3
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-test-check.cmake2
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-update-check.cmake3
-rw-r--r--Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD.cmake2
36 files changed, 655 insertions, 50 deletions
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 3821dc3..0392325 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.19
.. toctree::
:maxdepth: 1
+ CMP0114: ExternalProject step targets fully adopt their steps. </policy/CMP0114>
CMP0113: Makefile generators do not repeat custom commands from target dependencies. </policy/CMP0113>
CMP0112: Target file component generator expressions do not add target dependencies. </policy/CMP0112>
CMP0111: An imported target with a missing location fails during generation. </policy/CMP0111>
diff --git a/Help/policy/CMP0114.rst b/Help/policy/CMP0114.rst
new file mode 100644
index 0000000..1bc1216
--- /dev/null
+++ b/Help/policy/CMP0114.rst
@@ -0,0 +1,85 @@
+CMP0114
+-------
+
+.. versionadded:: 3.19
+
+:module:`ExternalProject` step targets fully adopt their steps.
+
+The :command:`ExternalProject_Add` ``STEP_TARGETS`` option, and the
+:command:`ExternalProject_Add_StepTargets` function, can be used to
+create build targets for individual steps of an external project.
+
+In CMake 3.18 and below, step targets have some limitations:
+
+* Step targets always depend on targets named by the
+ :command:`ExternalProject_Add` ``DEPENDS`` option even though
+ not all steps need them. In order to allow step targets to be created
+ without those dependencies, the :command:`ExternalProject_Add`
+ ``INDEPENDENT_STEP_TARGETS`` option or the
+ :command:`ExternalProject_Add_StepTargets` ``NO_DEPENDS`` option may
+ be used. However, adding such "independent" step targets makes sense
+ only for specific steps such as ``download``, ``update``, and ``patch``
+ because they do not need any of the external project's build dependencies.
+ Furthermore, it does not make sense to create independent step targets
+ for steps that depend on non-independent steps. Such rules are not
+ enforced, and projects that do not follow them can generate build systems
+ with confusing and generator-specific behavior.
+
+* Step targets hold copies of the custom commands implementing their
+ steps that are separate from the copies in the primary target created
+ by :command:`ExternalProject_Add`, and the primary target does not
+ depend on the step targets. In parallel builds that drive the primary
+ target and step targets concurrently, multiple copies of the steps'
+ commands may run concurrently and race each other.
+
+ Also, prior to policy :policy:`CMP0113`, the step targets generated
+ by :ref:`Makefile Generators` also contain all the custom commands
+ on which their step depends. This can lead to repeated execution of
+ those steps even in serial builds.
+
+In CMake 3.19 and above, the :module:`ExternalProject` module prefers
+a revised design to address these problems:
+
+* Each step is classified as "independent" if it does not depend
+ on other targets named by the :command:`ExternalProject_Add` ``DEPENDS``.
+ The predefined steps are automatically classified by default:
+
+ * The ``download``, ``update``, and ``patch`` steps are independent.
+ * The ``configure``, ``build``, ``test``, and ``install`` steps are not.
+
+ For custom steps, the :command:`ExternalProject_Add_Step` command provies
+ an ``INDEPENDENT`` option to mark them as independent. It is an error to
+ mark a step as independent if it depends on other steps that are not. Note
+ that this use of the term "independent" refers only to independence from
+ external targets and is orthogonal to a step's dependencies on other steps.
+
+* Step targets created by the :command:`ExternalProject_Add` ``STEP_TARGETS``
+ option or the :command:`ExternalProject_Add_Step` function are now
+ independent if and only if their steps are marked as independent.
+ The :command:`ExternalProject_Add` ``INDEPENDENT_STEP_TARGETS`` option
+ and :command:`ExternalProject_Add_StepTargets` ``NO_DEPENDS`` option
+ are no longer allowed.
+
+* Step targets, when created, are fully responsible for holding the
+ custom commands implementing their steps. The primary target created
+ by :command:`ExternalProject_Add` depends on the step targets, and the
+ step targets depend on each other. The target-level dependencies match
+ the file-level dependencies used by the custom commands for each step.
+
+ When the :command:`ExternalProject_Add` ``UPDATE_DISCONNECTED`` or
+ ``TEST_EXCLUDE_FROM_MAIN`` option is used, or the
+ :command:`ExternalProject_Add_Step` ``EXCLUDE_FROM_MAIN`` option is used
+ for a custom step, some step targets may be created automatically.
+ These are needed to hold the steps commonly depended upon by the primary
+ target and the disconnected step targets.
+
+Policy ``CMP0114`` provides compatibility for projects that have not been
+updated to expect the new behavior. The ``OLD`` behavior for this policy
+is to use the above-documented behavior from 3.18 and below. The ``NEW``
+behavior for this policy is to use the above-documented behavior preferred
+by 3.19 and above.
+
+This policy was introduced in CMake version 3.19. CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
diff --git a/Help/release/dev/ExternalProject-steps-refinement.rst b/Help/release/dev/ExternalProject-steps-refinement.rst
new file mode 100644
index 0000000..9762927
--- /dev/null
+++ b/Help/release/dev/ExternalProject-steps-refinement.rst
@@ -0,0 +1,5 @@
+ExternalProject-steps-refinement
+--------------------------------
+
+* The :module:`ExternalProject` module handling of step target dependencies
+ has been revised. See policy :policy:`CMP0114`.
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 5ab9784..b795784 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -398,6 +398,9 @@ External Project Definition
project also provides a cache variable or some other convenient method
for setting the directory property).
+ This may cause a step target to be created automatically for the
+ ``download`` step. See policy :policy:`CMP0114`.
+
``PATCH_COMMAND <cmd>...``
Specifies a custom command to patch the sources after an update. By
default, no patch command is defined. Note that it can be quite difficult
@@ -578,6 +581,8 @@ External Project Definition
If enabled, the main build's default ALL target will not depend on the
test step. This can be a useful way of ensuring the test step is defined
but only gets invoked when manually requested.
+ This may cause a step target to be created automatically for either
+ the ``install`` or ``build`` step. See policy :policy:`CMP0114`.
**Output Logging Options:**
Each of the following ``LOG_...`` options can be used to wrap the relevant
@@ -664,19 +669,21 @@ External Project Definition
steps need to be triggered manually or if they need to be used as
dependencies of other targets. If this option is not specified, the
default value is taken from the ``EP_STEP_TARGETS`` directory property.
- See :command:`ExternalProject_Add_Step` below for further discussion of
- the effects of this option.
+ See :command:`ExternalProject_Add_StepTargets` below for further
+ discussion of the effects of this option.
``INDEPENDENT_STEP_TARGETS <step-target>...``
- Generate custom targets for the specified steps and prevent these targets
+ Deprecated. This is allowed only if policy :policy:`CMP0114` is not set
+ to ``NEW``.
+ Generates custom targets for the specified steps and prevent these targets
from having the usual dependencies applied to them. If this option is not
specified, the default value is taken from the
``EP_INDEPENDENT_STEP_TARGETS`` directory property. This option is mostly
useful for allowing individual steps to be driven independently, such as
for a CDash setup where each step should be initiated and reported
individually rather than as one whole build. See
- :command:`ExternalProject_Add_Step` below for further discussion of the
- effects of this option.
+ :command:`ExternalProject_Add_StepTargets` below for further discussion
+ of the effects of this option.
**Miscellaneous Options:**
``LIST_SEPARATOR <sep>``
@@ -772,6 +779,21 @@ control needed to implement such step-level capabilities.
``DEPENDS <file>...``
Files on which this custom step depends.
+ ``INDEPENDENT <bool>``
+ Specifies whether this step is independent of the external dependencies
+ specified by the :command:`ExternalProject_Add`'s ``DEPENDS`` option.
+ The default is ``FALSE``. Steps marked as independent may depend only
+ on other steps marked independent. See policy :policy:`CMP0114`.
+
+ Note that this use of the term "independent" refers only to independence
+ from external targets specified by the ``DEPENDS`` option and is
+ orthogonal to a step's dependencies on other steps.
+
+ If a step target is created for an independent step by the
+ :command:`ExternalProject_Add` ``STEP_TARGETS`` option or by the
+ :command:`ExternalProject_Add_StepTargets` function, it will not depend
+ on the external targets, but may depend on targets for other steps.
+
``BYPRODUCTS <file>...``
Files that will be generated by this custom step but which might or might
not have their modification time updated by subsequent builds. This list of
@@ -785,6 +807,8 @@ control needed to implement such step-level capabilities.
``EXCLUDE_FROM_MAIN <bool>``
When enabled, this option specifies that the external project's main target
does not depend on the custom step.
+ This may cause step targets to be created automatically for the steps on
+ which this step depends. See policy :policy:`CMP0114`.
``WORKING_DIRECTORY <dir>``
Specifies the working directory to set before running the custom step's
@@ -815,7 +839,7 @@ control needed to implement such step-level capabilities.
.. code-block:: cmake
- ExternalProject_Add_StepTargets(<name> [NO_DEPENDS] <step1> [<step2>...])
+ ExternalProject_Add_StepTargets(<name> <step1> [<step2>...])
Creating a target for a step allows it to be used as a dependency of another
target or to be triggered manually. Having targets for specific steps also
@@ -827,37 +851,53 @@ control needed to implement such step-level capabilities.
through the step dependency chain, then all the previous steps will also run
to ensure everything is up to date.
- If the ``NO_DEPENDS`` option is specified, the step target will not depend on
- the dependencies of the external project (i.e. on any dependencies of the
- ``<name>`` custom target created by :command:`ExternalProject_Add`). This is
- usually safe for the ``download``, ``update`` and ``patch`` steps, since they
- do not typically require that the dependencies are updated and built. Using
- ``NO_DEPENDS`` for any of the other pre-defined steps, however, may break
- parallel builds. Only use ``NO_DEPENDS`` where it is certain that the named
- steps genuinely do not have dependencies. For custom steps, consider whether
- or not the custom commands require the dependencies to be configured, built
- and installed.
-
Internally, :command:`ExternalProject_Add` calls
:command:`ExternalProject_Add_Step` to create each step. If any
- ``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` were specified, then
- ``ExternalProject_Add_StepTargets()`` will also be called after
- :command:`ExternalProject_Add_Step`. ``INDEPENDENT_STEP_TARGETS`` have the
- ``NO_DEPENDS`` option set, whereas ``STEP_TARGETS`` do not. Other than that,
- the two options result in ``ExternalProject_Add_StepTargets()`` being called
- in the same way. Even if a step is not mentioned in either of those two
- options, ``ExternalProject_Add_StepTargets()`` can still be called later to
- manually define a target for the step.
-
- The ``STEP_TARGETS`` and ``INDEPENDENT_STEP_TARGETS`` options for
- :command:`ExternalProject_Add` are generally the easiest way to ensure
- targets are created for specific steps of interest. For custom steps,
- ``ExternalProject_Add_StepTargets()`` must be called explicitly if a target
- should also be created for that custom step. An alternative to these two
- options is to populate the ``EP_STEP_TARGETS`` and
- ``EP_INDEPENDENT_STEP_TARGETS`` directory properties. These act as defaults
- for the step target options and can save having to repeatedly specify the
- same set of step targets when multiple external projects are being defined.
+ ``STEP_TARGETS`` were specified, then ``ExternalProject_Add_StepTargets()``
+ will also be called after :command:`ExternalProject_Add_Step`. Even if a
+ step is not mentioned in the ``STEP_TARGETS`` option,
+ ``ExternalProject_Add_StepTargets()`` can still be called later to manually
+ define a target for the step.
+
+ The ``STEP_TARGETS`` option for :command:`ExternalProject_Add` is generally
+ the easiest way to ensure targets are created for specific steps of interest.
+ For custom steps, ``ExternalProject_Add_StepTargets()`` must be called
+ explicitly if a target should also be created for that custom step.
+ An alternative to these two options is to populate the ``EP_STEP_TARGETS``
+ directory property. It acts as a default for the step target options and
+ can save having to repeatedly specify the same set of step targets when
+ multiple external projects are being defined.
+
+ If :policy:`CMP0114` is set to ``NEW``, step targets are fully responsible
+ for holding the custom commands implementing their steps. The primary target
+ created by ``ExternalProject_Add`` depends on the step targets, and the
+ step targets depend on each other. The target-level dependencies match
+ the file-level dependencies used by the custom commands for each step.
+ The targets for steps created with :command:`ExternalProject_Add_Step`'s
+ ``INDEPENDENT`` option do not depend on the external targets specified
+ by :command:`ExternalProject_Add`'s ``DEPENDS`` option. The predefined
+ steps ``mkdir``, ``download``, ``update``, and ``patch`` are independent.
+
+ If :policy:`CMP0114` is not ``NEW``, the following deprecated behavior
+ is available:
+
+ * A deprecated ``NO_DEPENDS`` option may be specified immediately after the
+ ``<name>`` and before the first step.
+ If the ``NO_DEPENDS`` option is specified, the step target will not depend on
+ the dependencies of the external project (i.e. on any dependencies of the
+ ``<name>`` custom target created by :command:`ExternalProject_Add`). This is
+ usually safe for the ``download``, ``update`` and ``patch`` steps, since they
+ do not typically require that the dependencies are updated and built. Using
+ ``NO_DEPENDS`` for any of the other pre-defined steps, however, may break
+ parallel builds. Only use ``NO_DEPENDS`` where it is certain that the named
+ steps genuinely do not have dependencies. For custom steps, consider whether
+ or not the custom commands require the dependencies to be configured, built
+ and installed.
+
+ * The ``INDEPENDENT_STEP_TARGETS`` option for :command:`ExternalProject_Add`,
+ or the ``EP_INDEPENDENT_STEP_TARGETS`` directory property, tells the
+ function to call ``ExternalProject_Add_StepTargets()`` internally
+ using the ``NO_DEPENDS`` option for the specified steps.
.. command:: ExternalProject_Add_StepDependencies
@@ -1991,19 +2031,43 @@ endfunction()
function(_ep_step_add_target name step no_deps)
+ if(TARGET ${name}-${step})
+ return()
+ endif()
+ get_property(cmp0114 TARGET ${name} PROPERTY _EP_CMP0114)
_ep_get_step_stampfile(${name} ${step} stamp_file)
+ cmake_policy(PUSH)
+ if(cmp0114 STREQUAL "NEW")
+ # To implement CMP0114 NEW behavior with Makefile generators,
+ # we need CMP0113 NEW behavior.
+ cmake_policy(SET CMP0113 NEW)
+ endif()
add_custom_target(${name}-${step}
DEPENDS ${stamp_file})
+ cmake_policy(POP)
set_property(TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP 1)
set_property(TARGET ${name}-${step} PROPERTY LABELS ${name})
set_property(TARGET ${name}-${step} PROPERTY FOLDER "ExternalProjectTargets/${name}")
- if(no_deps AND "${step}" MATCHES "^(configure|build|install|test)$")
- message(AUTHOR_WARNING "Using NO_DEPENDS for \"${step}\" step might break parallel builds")
+ if(cmp0114 STREQUAL "NEW")
+ # Add target-level dependencies for the step.
+ get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN)
+ if(NOT exclude_from_main)
+ add_dependencies(${name} ${name}-${step})
+ endif()
+ _ep_step_add_target_dependencies(${name} ${step} ${step})
+ _ep_step_add_target_dependents(${name} ${step} ${step})
+
+ get_property(independent TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT)
+ else()
+ if(no_deps AND "${step}" MATCHES "^(configure|build|install|test)$")
+ message(AUTHOR_WARNING "Using NO_DEPENDS for \"${step}\" step might break parallel builds")
+ endif()
+ set(independent ${no_deps})
endif()
# Depend on other external projects (target-level).
- if(NOT no_deps)
+ if(NOT independent)
get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
foreach(arg IN LISTS deps)
add_dependencies(${name}-${step} ${arg})
@@ -2012,7 +2076,43 @@ function(_ep_step_add_target name step no_deps)
endfunction()
+function(_ep_step_add_target_dependencies name step node)
+ get_property(dependees TARGET ${name} PROPERTY _EP_${node}_INTERNAL_DEPENDEES)
+ list(REMOVE_DUPLICATES dependees)
+ foreach(dependee IN LISTS dependees)
+ get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN)
+ get_property(dependee_dependers TARGET ${name} PROPERTY _EP_${dependee}_INTERNAL_DEPENDERS)
+ if(exclude_from_main OR dependee_dependers MATCHES ";")
+ # The step on which our step target depends itself has
+ # dependents in multiple targes. It needs a step target too
+ # so that there is a unique place for its custom command.
+ _ep_step_add_target("${name}" "${dependee}" "FALSE")
+ endif()
+
+ if(TARGET ${name}-${dependee})
+ add_dependencies(${name}-${step} ${name}-${dependee})
+ else()
+ _ep_step_add_target_dependencies(${name} ${step} ${dependee})
+ endif()
+ endforeach()
+endfunction()
+
+
+function(_ep_step_add_target_dependents name step node)
+ get_property(dependers TARGET ${name} PROPERTY _EP_${node}_INTERNAL_DEPENDERS)
+ list(REMOVE_DUPLICATES dependers)
+ foreach(depender IN LISTS dependers)
+ if(TARGET ${name}-${depender})
+ add_dependencies(${name}-${depender} ${name}-${step})
+ else()
+ _ep_step_add_target_dependents(${name} ${step} ${depender})
+ endif()
+ endforeach()
+endfunction()
+
+
function(ExternalProject_Add_StepTargets name)
+ get_property(cmp0114 TARGET ${name} PROPERTY _EP_CMP0114)
set(steps ${ARGN})
if(ARGC GREATER 1 AND "${ARGV1}" STREQUAL "NO_DEPENDS")
set(no_deps 1)
@@ -2020,6 +2120,28 @@ function(ExternalProject_Add_StepTargets name)
else()
set(no_deps 0)
endif()
+ if(cmp0114 STREQUAL "NEW")
+ if(no_deps)
+ message(FATAL_ERROR
+ "The 'NO_DEPENDS' option is no longer allowed. "
+ "It has been superseded by the per-step 'INDEPENDENT' option. "
+ "See policy CMP0114."
+ )
+ endif()
+ elseif(cmp0114 STREQUAL "")
+ cmake_policy(GET_WARNING CMP0114 _cmp0114_warning)
+ string(APPEND _cmp0114_warning "\n"
+ "ExternalProject target '${name}' would depend on the targets for "
+ "step(s) '${steps}' under policy CMP0114, but this is being left out "
+ "for compatibility since the policy is not set."
+ )
+ if(no_deps)
+ string(APPEND _cmp0114_warning
+ " Also, the NO_DEPENDS option is deprecated in favor of policy CMP0114."
+ )
+ endif()
+ message(AUTHOR_WARNING "${_cmp0114_warning}")
+ endif()
foreach(step ${steps})
_ep_step_add_target("${name}" "${step}" "${no_deps}")
endforeach()
@@ -2027,12 +2149,19 @@ endfunction()
function(ExternalProject_Add_Step name step)
+ get_property(cmp0114 TARGET ${name} PROPERTY _EP_CMP0114)
_ep_get_complete_stampfile(${name} complete_stamp_file)
_ep_get_step_stampfile(${name} ${step} stamp_file)
_ep_parse_arguments(ExternalProject_Add_Step
${name} _EP_${step}_ "${ARGN}")
+ get_property(independent TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT)
+ if(independent STREQUAL "")
+ set(independent FALSE)
+ set_property(TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT "${independent}")
+ endif()
+
get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN)
if(NOT exclude_from_main)
add_custom_command(APPEND
@@ -2043,12 +2172,21 @@ function(ExternalProject_Add_Step name step)
# Steps depending on this step.
get_property(dependers TARGET ${name} PROPERTY _EP_${step}_DEPENDERS)
+ set_property(TARGET ${name} APPEND PROPERTY _EP_${step}_INTERNAL_DEPENDERS ${dependers})
foreach(depender IN LISTS dependers)
+ set_property(TARGET ${name} APPEND PROPERTY _EP_${depender}_INTERNAL_DEPENDEES ${step})
_ep_get_step_stampfile(${name} ${depender} depender_stamp_file)
add_custom_command(APPEND
OUTPUT ${depender_stamp_file}
DEPENDS ${stamp_file}
)
+ if(cmp0114 STREQUAL "NEW" AND NOT independent)
+ get_property(dep_independent TARGET ${name} PROPERTY _EP_${depender}_INDEPENDENT)
+ if(dep_independent)
+ message(FATAL_ERROR "ExternalProject '${name}' step '${depender}' is marked INDEPENDENT "
+ "but depends on step '${step}' that is not marked INDEPENDENT.")
+ endif()
+ endif()
endforeach()
# Dependencies on files.
@@ -2059,9 +2197,18 @@ function(ExternalProject_Add_Step name step)
# Dependencies on steps.
get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES)
+ set_property(TARGET ${name} APPEND PROPERTY _EP_${step}_INTERNAL_DEPENDEES ${dependees})
foreach(dependee IN LISTS dependees)
+ set_property(TARGET ${name} APPEND PROPERTY _EP_${dependee}_INTERNAL_DEPENDERS ${step})
_ep_get_step_stampfile(${name} ${dependee} dependee_stamp_file)
list(APPEND depends ${dependee_stamp_file})
+ if(cmp0114 STREQUAL "NEW" AND independent)
+ get_property(dep_independent TARGET ${name} PROPERTY _EP_${dependee}_INDEPENDENT)
+ if(NOT dep_independent)
+ message(FATAL_ERROR "ExternalProject '${name}' step '${step}' is marked INDEPENDENT "
+ "but depends on step '${dependee}' that is not marked INDEPENDENT.")
+ endif()
+ endif()
endforeach()
# The command to run.
@@ -2165,12 +2312,37 @@ function(ExternalProject_Add_Step name step)
if(NOT independent_step_targets)
get_property(independent_step_targets DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS)
endif()
- foreach(st ${independent_step_targets})
- if("${st}" STREQUAL "${step}")
- _ep_step_add_target("${name}" "${step}" "TRUE")
- break()
+ if(cmp0114 STREQUAL "NEW")
+ if(independent_step_targets)
+ message(FATAL_ERROR
+ "ExternalProject '${name}' option 'INDEPENDENT_STEP_TARGETS' is set to\n"
+ " ${independent_step_targets}\n"
+ "but the option is no longer allowed. "
+ "It has been superseded by the per-step 'INDEPENDENT' option. "
+ "See policy CMP0114."
+ )
endif()
- endforeach()
+ else()
+ if(independent_step_targets AND cmp0114 STREQUAL "")
+ get_property(warned TARGET ${name} PROPERTY _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS)
+ if(NOT warned)
+ set_property(TARGET ${name} PROPERTY _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS 1)
+ cmake_policy(GET_WARNING CMP0114 _cmp0114_warning)
+ string(APPEND _cmp0114_warning "\n"
+ "ExternalProject '${name}' option INDEPENDENT_STEP_TARGETS is set to\n"
+ " ${independent_step_targets}\n"
+ "but the option is deprecated in favor of policy CMP0114."
+ )
+ message(AUTHOR_WARNING "${_cmp0114_warning}")
+ endif()
+ endif()
+ foreach(st ${independent_step_targets})
+ if("${st}" STREQUAL "${step}")
+ _ep_step_add_target("${name}" "${step}" "TRUE")
+ break()
+ endif()
+ endforeach()
+ endif()
endfunction()
@@ -2233,6 +2405,7 @@ function(_ep_add_mkdir_command name)
_ep_get_configuration_subdir_suffix(cfgdir)
ExternalProject_Add_Step(${name} mkdir
+ INDEPENDENT TRUE
COMMENT "Creating directories for '${name}'"
COMMAND ${CMAKE_COMMAND} -E make_directory ${source_dir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${binary_dir}
@@ -2608,6 +2781,7 @@ function(_ep_add_download_command name)
endforeach()
cmake_language(EVAL CODE "
ExternalProject_Add_Step(\${name} download
+ INDEPENDENT TRUE
COMMENT \${comment}
COMMAND ${__cmdQuoted}
WORKING_DIRECTORY \${work_dir}
@@ -2771,6 +2945,7 @@ Update to Mercurial >= 2.1.1.
endforeach()
cmake_language(EVAL CODE "
ExternalProject_Add_Step(${name} update
+ INDEPENDENT TRUE
COMMENT \${comment}
COMMAND ${__cmdQuoted}
ALWAYS \${always}
@@ -2817,6 +2992,7 @@ function(_ep_add_patch_command name)
endforeach()
cmake_language(EVAL CODE "
ExternalProject_Add_Step(${name} patch
+ INDEPENDENT TRUE
COMMAND ${__cmdQuoted}
WORKING_DIRECTORY \${work_dir}
DEPENDEES \${patch_dep}
@@ -2981,6 +3157,7 @@ function(_ep_add_configure_command name)
endforeach()
cmake_language(EVAL CODE "
ExternalProject_Add_Step(${name} configure
+ INDEPENDENT FALSE
COMMAND ${__cmdQuoted}
WORKING_DIRECTORY \${binary_dir}
DEPENDEES patch
@@ -3032,6 +3209,7 @@ function(_ep_add_build_command name)
endforeach()
cmake_language(EVAL CODE "
ExternalProject_Add_Step(${name} build
+ INDEPENDENT FALSE
COMMAND ${__cmdQuoted}
BYPRODUCTS \${build_byproducts}
WORKING_DIRECTORY \${binary_dir}
@@ -3075,6 +3253,7 @@ function(_ep_add_install_command name)
endforeach()
cmake_language(EVAL CODE "
ExternalProject_Add_Step(${name} install
+ INDEPENDENT FALSE
COMMAND ${__cmdQuoted}
WORKING_DIRECTORY \${binary_dir}
DEPENDEES build
@@ -3142,6 +3321,7 @@ function(_ep_add_test_command name)
endforeach()
cmake_language(EVAL CODE "
ExternalProject_Add_Step(${name} test
+ INDEPENDENT FALSE
COMMAND ${__cmdQuoted}
WORKING_DIRECTORY \${binary_dir}
${dependees_args}
@@ -3159,6 +3339,9 @@ function(ExternalProject_Add name)
cmake_policy(GET CMP0097 _EP_CMP0097
PARENT_SCOPE # undocumented, do not use outside of CMake
)
+ cmake_policy(GET CMP0114 cmp0114
+ PARENT_SCOPE # undocumented, do not use outside of CMake
+ )
_ep_get_configuration_subdir_suffix(cfgdir)
@@ -3166,14 +3349,23 @@ function(ExternalProject_Add name)
set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
_ep_get_complete_stampfile(${name} complete_stamp_file)
+ cmake_policy(PUSH)
+ if(cmp0114 STREQUAL "NEW")
+ # To implement CMP0114 NEW behavior with Makefile generators,
+ # we need CMP0113 NEW behavior.
+ cmake_policy(SET CMP0113 NEW)
+ endif()
# The "ALL" option to add_custom_target just tells it to not set the
# EXCLUDE_FROM_ALL target property. Later, if the EXCLUDE_FROM_ALL
# argument was passed, we explicitly set it for the target.
add_custom_target(${name} ALL DEPENDS ${complete_stamp_file})
+ cmake_policy(POP)
set_property(TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT 1)
set_property(TARGET ${name} PROPERTY LABELS ${name})
set_property(TARGET ${name} PROPERTY FOLDER "ExternalProjectTargets/${name}")
+ set_property(TARGET ${name} PROPERTY _EP_CMP0114 "${cmp0114}")
+
_ep_parse_arguments(ExternalProject_Add ${name} _EP_ "${ARGN}")
_ep_set_directories(${name})
_ep_get_step_stampfile(${name} "done" done_stamp_file)
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index f9ec0d6..958d061 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -337,7 +337,10 @@ class cmMakefile;
SELECT(POLICY, CMP0113, \
"Makefile generators do not repeat custom commands from target " \
"dependencies.", \
- 3, 19, 0, cmPolicies::WARN)
+ 3, 19, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0114, \
+ "ExternalProject step targets fully adopt their steps.", 3, 19, 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/RunCMake/ExternalProject/Add_StepDependencies-stderr.txt b/Tests/RunCMake/ExternalProject/Add_StepDependencies-stderr.txt
new file mode 100644
index 0000000..d0ff15f
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Policy CMP0114 is not set: ExternalProject step targets fully adopt their
+ steps. Run "cmake --help-policy CMP0114" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ ExternalProject target 'FOO' would depend on the targets for step\(s\)
+ 'do_something' under policy CMP0114, but this is being left out for
+ compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+ Add_StepDependencies.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target-stderr.txt b/Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target-stderr.txt
new file mode 100644
index 0000000..2ae2b53
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Policy CMP0114 is not set: ExternalProject step targets fully adopt their
+ steps. Run "cmake --help-policy CMP0114" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ ExternalProject target 'FOO' would depend on the targets for step\(s\)
+ 'do_something' under policy CMP0114, but this is being left out for
+ compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+ Add_StepDependencies_no_target.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/ExternalProject/BadIndependentStep1-result.txt b/Tests/RunCMake/ExternalProject/BadIndependentStep1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/BadIndependentStep1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalProject/BadIndependentStep1-stderr.txt b/Tests/RunCMake/ExternalProject/BadIndependentStep1-stderr.txt
new file mode 100644
index 0000000..3188910
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/BadIndependentStep1-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ ExternalProject 'proj' step 'custom' is marked INDEPENDENT but depends on
+ step 'configure' that is not marked INDEPENDENT.
+Call Stack \(most recent call first\):
+ BadIndependentStep1.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/BadIndependentStep1.cmake b/Tests/RunCMake/ExternalProject/BadIndependentStep1.cmake
new file mode 100644
index 0000000..c81eb07
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/BadIndependentStep1.cmake
@@ -0,0 +1,14 @@
+include(ExternalProject)
+cmake_policy(SET CMP0114 NEW)
+
+ExternalProject_Add(proj
+ SOURCE_DIR "."
+ DOWNLOAD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+ExternalProject_Add_Step(proj custom
+ DEPENDEES configure
+ INDEPENDENT 1
+ )
diff --git a/Tests/RunCMake/ExternalProject/BadIndependentStep2-result.txt b/Tests/RunCMake/ExternalProject/BadIndependentStep2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/BadIndependentStep2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalProject/BadIndependentStep2-stderr.txt b/Tests/RunCMake/ExternalProject/BadIndependentStep2-stderr.txt
new file mode 100644
index 0000000..0b87e5e
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/BadIndependentStep2-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ ExternalProject 'proj' step 'update' is marked INDEPENDENT but depends on
+ step 'custom' that is not marked INDEPENDENT.
+Call Stack \(most recent call first\):
+ BadIndependentStep2.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/BadIndependentStep2.cmake b/Tests/RunCMake/ExternalProject/BadIndependentStep2.cmake
new file mode 100644
index 0000000..4a530ea
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/BadIndependentStep2.cmake
@@ -0,0 +1,13 @@
+include(ExternalProject)
+cmake_policy(SET CMP0114 NEW)
+
+ExternalProject_Add(proj
+ SOURCE_DIR "."
+ DOWNLOAD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+ExternalProject_Add_Step(proj custom
+ DEPENDERS update
+ )
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-Common.cmake
index 57626d6..176e28b 100644
--- a/Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-Common.cmake
@@ -1,4 +1,3 @@
-cmake_minimum_required(VERSION 2.8.12)
include(ExternalProject RESULT_VARIABLE GOO)
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct-result.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct-stderr.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct-stderr.txt
new file mode 100644
index 0000000..c6bf767
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ The 'NO_DEPENDS' option is no longer allowed. It has been superseded by
+ the per-step 'INDEPENDENT' option. See policy CMP0114.
+Call Stack \(most recent call first\):
+ NO_DEPENDS-CMP0114-NEW-Direct.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct.cmake b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct.cmake
new file mode 100644
index 0000000..7ec1a00
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-Direct.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0114 NEW)
+include(ExternalProject)
+ExternalProject_Add(BAR SOURCE_DIR . TEST_COMMAND echo test)
+ExternalProject_Add_StepTargets(BAR NO_DEPENDS test)
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-result.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-stderr.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-stderr.txt
new file mode 100644
index 0000000..5a5ba89
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-stderr.txt
@@ -0,0 +1,16 @@
+^CMake Error at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ ExternalProject 'FOO' option 'INDEPENDENT_STEP_TARGETS' is set to
+
+ download;patch;update;configure;build
+
+ but the option is no longer allowed. It has been superseded by the
+ per-step 'INDEPENDENT' option. See policy CMP0114.
+Call Stack \(most recent call first\):
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_mkdir_command\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-NEW.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW.cmake b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW.cmake
new file mode 100644
index 0000000..9622a60
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0114 NEW)
+include(NO_DEPENDS-CMP0114-Common.cmake)
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-OLD-stderr.txt
index 42400d4..2b0feb6 100644
--- a/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-OLD-stderr.txt
@@ -10,7 +10,8 @@ Call Stack \(most recent call first\):
]*/Modules/ExternalProject.cmake:[0-9]+ \(cmake_language\)
[^
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_configure_command\)
- NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-OLD.cmake:[0-9]+ \(include\)
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
+
@@ -26,7 +27,8 @@ Call Stack \(most recent call first\):
]*/Modules/ExternalProject.cmake:[0-9]+ \(cmake_language\)
[^
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_build_command\)
- NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-OLD.cmake:[0-9]+ \(include\)
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
+
@@ -42,7 +44,8 @@ Call Stack \(most recent call first\):
]*/Modules/ExternalProject.cmake:[0-9]+ \(cmake_language\)
[^
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_install_command\)
- NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-OLD.cmake:[0-9]+ \(include\)
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
+
@@ -52,6 +55,7 @@ CMake Warning \(dev\) at [^
Call Stack \(most recent call first\):
[^
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_step_add_target\)
- NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ NO_DEPENDS-CMP0114-OLD.cmake:[0-9]+ \(include\)
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-OLD.cmake b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-OLD.cmake
new file mode 100644
index 0000000..c20d443
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0114 OLD)
+include(NO_DEPENDS-CMP0114-Common.cmake)
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN-stderr.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN-stderr.txt
new file mode 100644
index 0000000..bbf7178
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN-stderr.txt
@@ -0,0 +1,119 @@
+^CMake Warning \(dev\) at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Policy CMP0114 is not set: ExternalProject step targets fully adopt their
+ steps. Run "cmake --help-policy CMP0114" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ ExternalProject 'FOO' option INDEPENDENT_STEP_TARGETS is set to
+
+ download;patch;update;configure;build
+
+ but the option is deprecated in favor of policy CMP0114.
+Call Stack \(most recent call first\):
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_mkdir_command\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Using NO_DEPENDS for "configure" step might break parallel builds
+Call Stack \(most recent call first\):
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_step_add_target\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+:EVAL:2 \(ExternalProject_Add_Step\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(cmake_language\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_configure_command\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Using NO_DEPENDS for "build" step might break parallel builds
+Call Stack \(most recent call first\):
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_step_add_target\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+:EVAL:2 \(ExternalProject_Add_Step\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(cmake_language\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_build_command\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Policy CMP0114 is not set: ExternalProject step targets fully adopt their
+ steps. Run "cmake --help-policy CMP0114" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ ExternalProject 'BAR' option INDEPENDENT_STEP_TARGETS is set to
+
+ install
+
+ but the option is deprecated in favor of policy CMP0114.
+Call Stack \(most recent call first\):
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_mkdir_command\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Using NO_DEPENDS for "install" step might break parallel builds
+Call Stack \(most recent call first\):
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_step_add_target\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+:EVAL:2 \(ExternalProject_Add_Step\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(cmake_language\)
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_install_command\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
+ NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Policy CMP0114 is not set: ExternalProject step targets fully adopt their
+ steps. Run "cmake --help-policy CMP0114" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ ExternalProject target 'BAR' would depend on the targets for step\(s\)
+ 'test;bar' under policy CMP0114, but this is being left out for
+ compatibility since the policy is not set. Also, the NO_DEPENDS option is
+ deprecated in favor of policy CMP0114.
+Call Stack \(most recent call first\):
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Using NO_DEPENDS for "test" step might break parallel builds
+Call Stack \(most recent call first\):
+ [^
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_step_add_target\)
+ NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN.cmake b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN.cmake
new file mode 100644
index 0000000..3d9642d
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN.cmake
@@ -0,0 +1,2 @@
+# Policy CMP0114 not set.
+include(NO_DEPENDS-CMP0114-Common.cmake)
diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
index c2c77e0..1e88e0b 100644
--- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
@@ -6,6 +6,8 @@ include(RunCMake)
unset(ENV{http_proxy})
unset(ENV{https_proxy})
+run_cmake(BadIndependentStep1)
+run_cmake(BadIndependentStep2)
run_cmake(IncludeScope-Add)
run_cmake(IncludeScope-Add_Step)
run_cmake(NoOptions)
@@ -14,13 +16,46 @@ run_cmake(SourceMissing)
run_cmake(CMAKE_CACHE_ARGS)
run_cmake(CMAKE_CACHE_DEFAULT_ARGS)
run_cmake(CMAKE_CACHE_mix)
-run_cmake(NO_DEPENDS)
+run_cmake(NO_DEPENDS-CMP0114-WARN)
+run_cmake(NO_DEPENDS-CMP0114-OLD)
+run_cmake(NO_DEPENDS-CMP0114-NEW)
+run_cmake(NO_DEPENDS-CMP0114-NEW-Direct)
run_cmake(Add_StepDependencies)
run_cmake(Add_StepDependencies_iface)
run_cmake(Add_StepDependencies_iface_step)
run_cmake(Add_StepDependencies_no_target)
run_cmake(UsesTerminal)
+macro(check_steps_missing proj)
+ set(steps "${ARGN}")
+ foreach(step ${steps})
+ if(EXISTS ${RunCMake_TEST_BINARY_DIR}/${proj}-${step}-mark)
+ string(APPEND RunCMake_TEST_FAILED "${proj} '${step}' step ran but should not have\n")
+ endif()
+ endforeach()
+endmacro()
+
+macro(check_steps_present proj)
+ set(steps "${ARGN}")
+ foreach(step ${steps})
+ if(NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/${proj}-${step}-mark)
+ string(APPEND RunCMake_TEST_FAILED "${proj} '${step}' step did not run but should have\n")
+ endif()
+ endforeach()
+endmacro()
+
+function(run_steps_CMP0114 val)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Steps-CMP0114-${val}-build)
+ run_cmake(Steps-CMP0114-${val})
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(Steps-CMP0114-${val}-build-download ${CMAKE_COMMAND} --build . --target proj1-download)
+ run_cmake_command(Steps-CMP0114-${val}-build-update ${CMAKE_COMMAND} --build . --target proj1-update)
+ run_cmake_command(Steps-CMP0114-${val}-build-install ${CMAKE_COMMAND} --build . --target proj1-install)
+ run_cmake_command(Steps-CMP0114-${val}-build-test ${CMAKE_COMMAND} --build . --target proj1-test)
+endfunction()
+run_steps_CMP0114(OLD)
+run_steps_CMP0114(NEW)
+
# Run both cmake and build steps. We always do a clean before the
# build to ensure that the download step re-runs each time.
function(__ep_test_with_build testName)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-Common.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-Common.cmake
new file mode 100644
index 0000000..210edb1
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-Common.cmake
@@ -0,0 +1,34 @@
+include(ExternalProject)
+
+ExternalProject_Add(proj0
+ SOURCE_DIR "."
+ DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj0-download-mark
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj0-configure-mark
+ BUILD_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj0-build-mark
+ INSTALL_COMMAND ""
+ )
+
+cmake_policy(GET CMP0114 cmp0114)
+if(cmp0114 STREQUAL "NEW")
+ set(step_targets "update;test")
+ set(independent_step_targets "")
+else()
+ set(step_targets "install;test")
+ set(independent_step_targets "download;update")
+endif()
+
+ExternalProject_Add(proj1
+ DEPENDS proj0
+ SOURCE_DIR "."
+ DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj1-download-mark
+ UPDATE_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj1-update-mark
+ PATCH_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj1-patch-mark
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj1-configure-mark
+ BUILD_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj1-build-mark
+ INSTALL_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj1-install-mark
+ TEST_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/proj1-test-mark
+ TEST_EXCLUDE_FROM_MAIN 1 # Along with 'STEP_TARGETS test', implies 'STEP_TARGETS install'
+ UPDATE_DISCONNECTED 1 # Along with 'STEP_TARGETS update', implies 'STEP_TARGETS download'
+ STEP_TARGETS ${step_targets}
+ INDEPENDENT_STEP_TARGETS ${independent_step_targets}
+ )
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-download-check.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-download-check.cmake
new file mode 100644
index 0000000..1439f02
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-download-check.cmake
@@ -0,0 +1,3 @@
+check_steps_missing(proj0 download configure build)
+check_steps_present(proj1 download)
+check_steps_missing(proj1 update patch configure build install test)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-install-check.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-install-check.cmake
new file mode 100644
index 0000000..c1c9c8f
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-install-check.cmake
@@ -0,0 +1,3 @@
+check_steps_present(proj0 download configure build)
+check_steps_present(proj1 download patch configure build install)
+check_steps_missing(proj1 test)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-test-check.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-test-check.cmake
new file mode 100644
index 0000000..fe256f2
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-test-check.cmake
@@ -0,0 +1,2 @@
+check_steps_present(proj0 download configure build)
+check_steps_present(proj1 download patch configure build install test)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-update-check.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-update-check.cmake
new file mode 100644
index 0000000..63e2e1d
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW-build-update-check.cmake
@@ -0,0 +1,3 @@
+check_steps_missing(proj0 download configure build)
+check_steps_present(proj1 download update)
+check_steps_missing(proj1 patch configure build install test)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW.cmake
new file mode 100644
index 0000000..9d8e99e
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0114 NEW)
+include(Steps-CMP0114-Common.cmake)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-download-check.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-download-check.cmake
new file mode 100644
index 0000000..1439f02
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-download-check.cmake
@@ -0,0 +1,3 @@
+check_steps_missing(proj0 download configure build)
+check_steps_present(proj1 download)
+check_steps_missing(proj1 update patch configure build install test)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-install-check.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-install-check.cmake
new file mode 100644
index 0000000..c1c9c8f
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-install-check.cmake
@@ -0,0 +1,3 @@
+check_steps_present(proj0 download configure build)
+check_steps_present(proj1 download patch configure build install)
+check_steps_missing(proj1 test)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-test-check.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-test-check.cmake
new file mode 100644
index 0000000..fe256f2
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-test-check.cmake
@@ -0,0 +1,2 @@
+check_steps_present(proj0 download configure build)
+check_steps_present(proj1 download patch configure build install test)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-update-check.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-update-check.cmake
new file mode 100644
index 0000000..63e2e1d
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD-build-update-check.cmake
@@ -0,0 +1,3 @@
+check_steps_missing(proj0 download configure build)
+check_steps_present(proj1 download update)
+check_steps_missing(proj1 patch configure build install test)
diff --git a/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD.cmake b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD.cmake
new file mode 100644
index 0000000..0b51ad8
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Steps-CMP0114-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0114 OLD)
+include(Steps-CMP0114-Common.cmake)