Browse Source

ENH: Added macro ctkMacroValidateBuildOptions

Assuming the user enable only the option he wants (for example the application
ctkDicom), this macro will make sure all dependent targets are also enabled
(in that case: CTKCore)
Jean-Christophe Fillion-Robin 15 years ago
parent
commit
a7d97079db
2 changed files with 145 additions and 6 deletions
  1. 128 0
      CMake/ctkMacroValidateBuildOptions.cmake
  2. 17 6
      CMakeLists.txt

+ 128 - 0
CMake/ctkMacroValidateBuildOptions.cmake

@@ -0,0 +1,128 @@
+#
+#
+#
+MACRO(ctkMacroGetOptionName target_directories_with_target_name target_name option_name_var)
+  
+  FOREACH(target_info ${target_directories_with_target_name})
+    # extract target_dir and option_name
+    #MESSAGE("target_info:${target_info}")
+    STRING(REPLACE "^^" "\\;" target_info_list ${target_info})
+    SET(target_info_list ${target_info_list})
+    LIST(GET target_info_list 0 _target_dir)
+    LIST(GET target_info_list 1 _option_name)
+    LIST(GET target_info_list 2 _target_name)
+    IF(${_target_name} STREQUAL ${target_name})
+      SET(${option_name_var} ${_option_name})
+    ENDIF()
+  ENDFOREACH()
+ENDMACRO()
+
+#
+#
+#
+MACRO(ctkMacroValidateBuildOptions dir executable target_directories)
+  IF(NOT EXISTS ${dir})
+    MESSAGE(FATAL_ERROR "Directory ${dir} doesn't exist!")
+  ENDIF()
+
+  IF(NOT EXISTS ${executable})
+    MESSAGE(FATAL_ERROR "Executable ${executable} doesn't exist!")
+  ENDIF()
+
+  SET(target_directories_with_target_name)
+  
+  # Create target_directories_with_target_name
+  FOREACH(target_info ${target_directories})
+
+    # extract target_dir and option_name
+    STRING(REPLACE "^^" "\\;" target_info ${target_info})
+    SET(target_info_list ${target_info})
+    LIST(GET target_info_list 0 target_dir)
+    LIST(GET target_info_list 1 option_name)
+    #MESSAGE(STATUS target_dir:${target_dir})
+    #MESSAGE(STATUS option_name:${option_name})
+    #MESSAGE(STATUS option_name-value:${${option_name}})
+    
+    # make sure the directory exists
+    IF(NOT EXISTS ${target_dir}/CMakeLists.txt)
+      MESSAGE(FATAL_ERROR "Target directory ${target_dir}/CMakeLists.txt doesn't exists !")
+    ENDIF()
+
+    # extract project name from CMakeLists.txt
+    FILE(STRINGS "${target_dir}/CMakeLists.txt" project_string
+      REGEX "^ *(P|p)(R|r)(O|o)(J|j)(E|e)(C|c)(T|t)\\("
+      LIMIT_COUNT 10)
+    STRING(REGEX MATCH "\\((.*)\\)" target_project_name ${project_string})
+    STRING(REGEX REPLACE "\\(|\\)" "" target_project_name ${target_project_name})
+    IF(${target_project_name} STREQUAL "")
+      MESSAGE(FATAL_ERROR "Failed to extract project name from ${target_dir}/CMakeLists.txt")
+    ENDIF()
+    #MESSAGE(STATUS target_project_name:${target_project_name})
+
+    LIST(APPEND target_directories_with_target_name
+      ${target_dir}^^${option_name}^^${target_project_name}
+      )
+  ENDFOREACH()
+
+  FOREACH(target_info ${target_directories_with_target_name})
+
+    # extract target_dir and option_name
+    STRING(REPLACE "^^" "\\;" target_info ${target_info})
+    SET(target_info_list ${target_info})
+    LIST(GET target_info_list 0 target_dir)
+    LIST(GET target_info_list 1 option_name)
+    #MESSAGE(STATUS target_dir:${target_dir})
+    #MESSAGE(STATUS option_name:${option_name})
+    #MESSAGE(STATUS option_name-value:${${option_name}})
+    
+    # make sure the directory exists
+    IF(NOT EXISTS ${target_dir}/CMakeLists.txt)
+      MESSAGE(FATAL_ERROR "Target directory ${target_dir}/CMakeLists.txt doesn't exists !")
+    ENDIF()
+
+    # extract project name from CMakeLists.txt
+    FILE(STRINGS "${target_dir}/CMakeLists.txt" project_string
+      REGEX "^ *(P|p)(R|r)(O|o)(J|j)(E|e)(C|c)(T|t)\\("
+      LIMIT_COUNT 10)
+    STRING(REGEX MATCH "\\((.*)\\)" target_project_name ${project_string})
+    STRING(REGEX REPLACE "\\(|\\)" "" target_project_name ${target_project_name})
+    IF(${target_project_name} STREQUAL "")
+      MESSAGE(FATAL_ERROR "Failed to extract project name from ${target_dir}/CMakeLists.txt")
+    ENDIF()
+    #MESSAGE(STATUS target_project_name:${target_project_name})
+
+    IF(${${option_name}})
+      # Obtain dependency path
+      EXECUTE_PROCESS(
+        COMMAND "${executable}" "${CTK_BINARY_DIR}/DGraphInput-alldep.txt" -path ${target_project_name}
+        WORKING_DIRECTORY ${CTK_BINARY_DIR}
+        RESULT_VARIABLE RESULT_VAR
+        OUTPUT_VARIABLE dep_path
+        ERROR_VARIABLE error
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+      IF(RESULT_VAR)
+        MESSAGE(FATAL_ERROR "Failed to obtain dependence path of ${subir}.\n${RESULT_VAR}\n${CTK_BINARY_DIR}\n${error}")
+      ENDIF()
+
+      # Convert 'dep_path' to a list
+      STRING(REPLACE " " "\\;" dep_path_list ${dep_path})
+      SET(dep_path_list ${dep_path_list})
+
+      #MESSAGE("path for ${target_project_name} is: ${dep_path}")
+      
+      # Check if all target included in the dependency path are enabled
+      FOREACH(dep ${dep_path_list})
+        ctkMacroGetOptionName("${target_directories_with_target_name}" ${dep} dep_option)
+        IF(NOT ${${dep_option}})
+          # Enable option
+          MESSAGE(STATUS "Enabling option [${dep_option}] required by target [${target_project_name}]")
+          SET(${dep_option} ON CACHE BOOL "Enable ${target_project_name} library" FORCE)
+        ENDIF()
+      ENDFOREACH()
+    ENDIF()
+    
+  ENDFOREACH()
+
+  #MESSAGE(STATUS "Validated: CTK_LIB_*, CTK_PLUGIN_*, CTK_APP_*")
+ENDMACRO()

+ 17 - 6
CMakeLists.txt

@@ -100,6 +100,7 @@ INCLUDE(CMake/ctkMacroBuildQtDesignerPlugin.cmake)
 INCLUDE(CMake/ctkMacroSetupQt.cmake)
 INCLUDE(CMake/ctkMacroTargetLibraries.cmake) # Import multiple macros
 INCLUDE(CMake/ctkMacroExtractOptionNameAndValue.cmake)
+INCLUDE(CMake/ctkMacroValidateBuildOptions.cmake)
 INCLUDE(CMake/ctkMacroAddCtkLibraryOptions.cmake)
 INCLUDE(CMake/ctkMacroGenerateDGraphInput.cmake)
 INCLUDE(CMake/ctkMacroGenerateProjectXml.cmake)
@@ -231,7 +232,6 @@ SET(CTK_APPLICATIONS
   ctkDICOM:OFF
   ctkDICOMIndexer:OFF
   )
-
   
 #-----------------------------------------------------------------------------
 # To make options show up in both CTK-SuperBuild and CTK regular build, let's add them
@@ -305,7 +305,8 @@ OPTION(CTK_SUPERBUILD "Build CTK and the projects it depends on via SuperBuild.c
 MARK_AS_ADVANCED(CTK_SUPERBUILD)
 
 #-----------------------------------------------------------------------------
-# Project.xml
+# Generate target_directories list - List of directory corresponding to the different
+# libraries, plugins and applications associated with the corresponding option name.
 #
 
 # Create list of directories corresponding to the enabled targets
@@ -328,9 +329,6 @@ ENDFOREACH()
 
 #MESSAGE(STATUS target_directories:${target_directories})
 
-# Generate Project.xml file expected by the CTest driver script
-ctkMacroGenerateProjectXml(${CTK_BINARY_DIR} ${PROJECT_NAME} "${target_directories}" ${CTK_SUPERBUILD})
-
 #-----------------------------------------------------------------------------
 # Compile DGraph - An application allowing to check for cycle in DAG and also obtain the
 # topological order.
@@ -351,6 +349,12 @@ FIND_PROGRAM(DGraph_EXECUTABLE DGraph
 MARK_AS_ADVANCED(DGraph_EXECUTABLE)
 
 #-----------------------------------------------------------------------------
+# Let's make sure the enabled/disabled libraries, plugins or applications are coherent
+#
+ctkMacroGenerateDGraphInput(${CTK_BINARY_DIR} "${target_directories}" FALSE)
+ctkMacroValidateBuildOptions("${CTK_BINARY_DIR}" "${DGraph_EXECUTABLE}" "${target_directories}")
+
+#-----------------------------------------------------------------------------
 # DGraph
 #
 
@@ -359,7 +363,7 @@ ctkMacroGenerateDGraphInput(${CTK_BINARY_DIR} "${target_directories}" TRUE)
 
 # Obtain list of target ordered topologically
 EXECUTE_PROCESS(
-  COMMAND ${DGraph_EXECUTABLE} ${CTK_BINARY_DIR}/DGraphInput.txt  
+  COMMAND "${DGraph_EXECUTABLE}" "${CTK_BINARY_DIR}/DGraphInput.txt"  
   WORKING_DIRECTORY ${CTK_BINARY_DIR}
   RESULT_VARIABLE RESULT_VAR
   OUTPUT_VARIABLE CTEST_PROJECT_SUBPROJECTS
@@ -375,6 +379,13 @@ CONFIGURE_FILE(${CTK_SOURCE_DIR}/CTestConfigSubProject.cmake.in
                ${CTK_BINARY_DIR}/CTestConfigSubProject.cmake)
 
 #-----------------------------------------------------------------------------
+# Project.xml
+#
+
+# Generate Project.xml file expected by the CTest driver script
+ctkMacroGenerateProjectXml(${CTK_BINARY_DIR} ${PROJECT_NAME} "${target_directories}" ${CTK_SUPERBUILD})
+
+#-----------------------------------------------------------------------------
 # Superbuild script
 #