From f598f1aa836f7c9a60bc59b53ebbc2faae24f5a4 Mon Sep 17 00:00:00 2001
From: "Daniele E. Domenichelli" <daniele.domenichelli@iit.it>
Date: Mon, 3 Nov 2014 16:14:49 +0100
Subject: 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
---
 Modules/ExternalProject.cmake | 58 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 02383cb..8513437 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -303,6 +303,19 @@ line prior to any ``ExternalProject_Add`` calls in your ``CMakeLists.txt``
 file::
 
  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)
     add_custom_target(${name}-${step}
       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 FOLDER "ExternalProjectTargets/${name}")
 
@@ -1418,6 +1432,7 @@ function(ExternalProject_Add_Step name step)
     WORKING_DIRECTORY ${work_dir}
     VERBATIM
     )
+  set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step})
 
   # Add custom "step target"?
   get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS)
@@ -1444,6 +1459,49 @@ function(ExternalProject_Add_Step name step)
 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)
   ExternalProject_Get_Property(${name}
     source_dir binary_dir install_dir stamp_dir download_dir tmp_dir)
-- 
cgit v0.12