ExternalProject: Add ExternalProject_Add_StepDependencies function

The ExternalProject_Add_StepDependencies function add some dependencies
for some external project step.

The syntax is:
 ExternalProject_Add_Step_Dependencies(<name> <step> [target1 [target2 [...]]])

This function takes care to set both target and file level dependencies,
and will ensure that parallel builds will not break.

It should be used instead of add_dependencies() when adding a dependency
for some of the step targets generated by ExternalProject. See also:
http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/8680/focus=8926
This commit is contained in:
Daniele E. Domenichelli 2014-11-03 16:14:49 +01:00
parent 4ae133e09c
commit f598f1aa83
1 changed files with 58 additions and 0 deletions

View File

@ -303,6 +303,19 @@ line prior to any ``ExternalProject_Add`` calls in your ``CMakeLists.txt``
file:: file::
set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test) set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test)
.. command:: ExternalProject_Add_StepDependencies
The ``ExternalProject_Add_StepDependencies`` function add some
dependencies for some external project step::
ExternalProject_Add_StepDependencies(<name> <step> [target1 [target2 [...]]])
This function takes care to set both target and file level
dependencies, and will ensure that parallel builds will not break.
It should be used instead of :command:`add_dependencies()` when adding
a dependency for some of the step targets generated by
``ExternalProject``.
#]=======================================================================] #]=======================================================================]
#============================================================================= #=============================================================================
@ -1318,6 +1331,7 @@ function(ExternalProject_Add_StepTargets name)
_ep_get_step_stampfile(${name} ${step} stamp_file) _ep_get_step_stampfile(${name} ${step} stamp_file)
add_custom_target(${name}-${step} add_custom_target(${name}-${step}
DEPENDS ${stamp_file}) DEPENDS ${stamp_file})
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 LABELS ${name})
set_property(TARGET ${name}-${step} PROPERTY FOLDER "ExternalProjectTargets/${name}") set_property(TARGET ${name}-${step} PROPERTY FOLDER "ExternalProjectTargets/${name}")
@ -1418,6 +1432,7 @@ function(ExternalProject_Add_Step name step)
WORKING_DIRECTORY ${work_dir} WORKING_DIRECTORY ${work_dir}
VERBATIM VERBATIM
) )
set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step})
# Add custom "step target"? # Add custom "step target"?
get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS) get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS)
@ -1444,6 +1459,49 @@ function(ExternalProject_Add_Step name step)
endfunction() endfunction()
function(ExternalProject_Add_StepDependencies name step)
set(dependencies ${ARGN})
# Sanity checks on "name" and "step".
if(NOT TARGET ${name})
message(FATAL_ERROR "Cannot find target \"${name}\". Perhaps it has not yet been created using ExternalProject_Add.")
endif()
get_property(is_ep TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT)
if(NOT is_ep)
message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add.")
endif()
get_property(steps TARGET ${name} PROPERTY _EP_STEPS)
list(FIND steps ${step} is_step)
if(NOT is_step)
message(FATAL_ERROR "External project \"${name}\" does not have a step \"${step}\".")
endif()
if(TARGET ${name}-${step})
get_property(is_ep_step TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP)
if(NOT is_ep_step)
message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add_StepTargets.")
endif()
endif()
# Always add file-level dependency, but add target-level dependency
# only if the target exists for that step.
_ep_get_step_stampfile(${name} ${step} stamp_file)
foreach(dep ${dependencies})
add_custom_command(APPEND
OUTPUT ${stamp_file}
DEPENDS ${dep})
if(TARGET ${name}-${step})
foreach(dep ${dependencies})
add_dependencies(${name}-${step} ${dep})
endforeach()
endif()
endforeach()
endfunction()
function(_ep_add_mkdir_command name) function(_ep_add_mkdir_command name)
ExternalProject_Get_Property(${name} ExternalProject_Get_Property(${name}
source_dir binary_dir install_dir stamp_dir download_dir tmp_dir) source_dir binary_dir install_dir stamp_dir download_dir tmp_dir)