summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/AddExternalProject.cmake225
-rw-r--r--Tests/ExternalProject/CMakeLists.txt97
2 files changed, 217 insertions, 105 deletions
diff --git a/Modules/AddExternalProject.cmake b/Modules/AddExternalProject.cmake
index 9e14bd2..5fd6df0 100644
--- a/Modules/AddExternalProject.cmake
+++ b/Modules/AddExternalProject.cmake
@@ -36,6 +36,36 @@ function(get_configure_build_working_dir name working_dir_var)
endfunction(get_configure_build_working_dir)
+function(get_configure_command_id name cfg_cmd_id_var)
+ get_target_property(cmd ${name} AEP_CONFIGURE_COMMAND)
+
+ if(cmd STREQUAL "")
+ # Explicit empty string means no configure step for this project
+ set(${cfg_cmd_id_var} "none" PARENT_SCOPE)
+ else()
+ if(NOT cmd)
+ # Default is "use cmake":
+ set(${cfg_cmd_id_var} "cmake" PARENT_SCOPE)
+ else()
+ # Otherwise we have to analyze the value:
+ if(cmd MATCHES "/configure$")
+ set(${cfg_cmd_id_var} "configure" PARENT_SCOPE)
+ else()
+ if(cmd MATCHES "cmake")
+ set(${cfg_cmd_id_var} "cmake" PARENT_SCOPE)
+ else()
+ if(cmd MATCHES "config")
+ set(${cfg_cmd_id_var} "configure" PARENT_SCOPE)
+ else()
+ set(${cfg_cmd_id_var} "unknown:${cmd}" PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+ endif()
+ endif()
+endfunction(get_configure_command_id)
+
+
function(add_external_project_download_command name)
set(added 0)
get_external_project_directories(base_dir build_dir downloads_dir install_dir
@@ -43,6 +73,42 @@ function(add_external_project_download_command name)
if(NOT added)
+ get_target_property(cmd ${name} AEP_DOWNLOAD_COMMAND)
+ if(cmd STREQUAL "")
+ # Explicit empty string means no download step for this project
+ add_custom_command(
+ OUTPUT ${sentinels_dir}/${name}-download
+ COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-download
+ WORKING_DIRECTORY ${sentinels_dir}
+ COMMENT "No download step for '${name}'"
+ )
+ set(added 1)
+ else()
+ if(cmd)
+ set(args "")
+ get_target_property(download_args ${name} AEP_DOWNLOAD_ARGS)
+ if(download_args)
+ set(args "${download_args}")
+ separate_arguments(args)
+ endif()
+
+ add_custom_command(
+ OUTPUT ${sentinels_dir}/${name}-download
+ COMMAND ${cmd} ${args}
+ COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-download
+ WORKING_DIRECTORY ${downloads_dir}
+ COMMENT "Performing download step for '${name}'"
+ )
+ set(added 1)
+ else()
+ # No explicit DOWNLOAD_COMMAND property. Look for other properties
+ # indicating which download method to use in the logic below...
+ endif()
+ endif()
+ endif()
+
+
+ if(NOT added)
get_target_property(cvs_repository ${name} AEP_CVS_REPOSITORY)
if(cvs_repository)
if(NOT CVS_EXECUTABLE)
@@ -275,13 +341,21 @@ function(add_external_project_build_command name)
DEPENDS ${sentinels_dir}/${name}-configure
)
else()
+ get_configure_command_id(${name} cfg_cmd_id)
+
if(NOT cmd)
- set(cmd ${CMAKE_COMMAND})
+ set(cmd make)
+ if(cfg_cmd_id STREQUAL "cmake")
+ set(cmd ${CMAKE_COMMAND})
+ endif()
endif()
get_target_property(args ${name} AEP_BUILD_ARGS)
if(NOT args)
- set(args --build ${working_dir} --config ${CMAKE_CFG_INTDIR})
+ set(args)
+ if(cfg_cmd_id STREQUAL "cmake")
+ set(args --build ${working_dir} --config ${CMAKE_CFG_INTDIR})
+ endif()
endif()
add_custom_command(
@@ -312,13 +386,24 @@ function(add_external_project_install_command name)
DEPENDS ${sentinels_dir}/${name}-build
)
else()
+ get_configure_command_id(${name} cfg_cmd_id)
+
if(NOT cmd)
- set(cmd ${CMAKE_COMMAND})
+ set(cmd make)
+ if(cfg_cmd_id STREQUAL "cmake")
+ set(cmd ${CMAKE_COMMAND})
+ endif()
endif()
get_target_property(args ${name} AEP_INSTALL_ARGS)
if(NOT args)
- set(args --build ${working_dir} --config ${CMAKE_CFG_INTDIR} --target install)
+ set(args)
+ if(cfg_cmd_id STREQUAL "cmake")
+ set(args --build ${working_dir} --config ${CMAKE_CFG_INTDIR} --target install)
+ endif()
+ if(cfg_cmd_id STREQUAL "configure")
+ set(args "install")
+ endif()
endif()
add_custom_command(
@@ -339,123 +424,101 @@ function(add_CMakeExternals_target)
sentinels_dir source_dir tmp_dir)
add_custom_command(
- OUTPUT ${tmp_dir}
+ OUTPUT ${sentinels_dir}/CMakeExternals-directories
COMMAND ${CMAKE_COMMAND} -E make_directory ${build_dir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${downloads_dir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${install_dir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${sentinels_dir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${source_dir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${tmp_dir}
+ COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/CMakeExternals-directories
+ COMMENT "Creating CMakeExternals directories"
)
add_custom_target(CMakeExternals ALL
- DEPENDS ${tmp_dir}
+ DEPENDS ${sentinels_dir}/CMakeExternals-directories
)
endif()
endfunction(add_CMakeExternals_target)
+function(is_known_aep_property_key key result_var)
+ set(${result_var} 0 PARENT_SCOPE)
+
+ if(key MATCHES "^BUILD_ARGS|BUILD_COMMAND|CONFIGURE_ARGS|CONFIGURE_COMMAND|CONFIGURE_DIR|CVS_REPOSITORY|CVS_MODULE|CVS_TAG|DEPENDS|DOWNLOAD_ARGS|DOWNLOAD_COMMAND|DIR|INSTALL_ARGS|INSTALL_COMMAND|SVN_REPOSITORY|SVN_TAG|TAR|TAR_URL|TGZ|TGZ_URL$"
+ )
+ #message(STATUS "info: recognized via MATCHES - key='${key}'")
+ set(${result_var} 1 PARENT_SCOPE)
+ else()
+ message(STATUS "warning: is_known_aep_property_key unknown key='${key}'")
+ endif()
+endfunction(is_known_aep_property_key)
+
+
function(add_external_project name)
get_external_project_directories(base_dir build_dir downloads_dir install_dir
sentinels_dir source_dir tmp_dir)
+
+ # Ensure root CMakeExternals target and directories are created.
+ # All external projects will depend on this root CMakeExternals target.
+ #
add_CMakeExternals_target()
+
+ # Add a custom target for the external project and make its DEPENDS
+ # the output of the final build step:
+ #
add_custom_target(${name} ALL
DEPENDS ${sentinels_dir}/${name}-install
)
set_target_properties(${name} PROPERTIES AEP_IS_EXTERNAL_PROJECT 1)
+ add_dependencies(${name} CMakeExternals)
- # Loop over ARGN by 2's extracting key/value pairs from
- # the non-explicit arguments to the function:
+
+ # Transfer the arguments to this function into target properties for the
+ # new custom target we just added so that we can set up all the build steps
+ # correctly based on target properties.
+ #
+ # Loop over ARGN by 2's extracting key/value pairs from the non-explicit
+ # arguments to this function:
#
list(LENGTH ARGN n)
set(i 0)
while(i LESS n)
math(EXPR j ${i}+1)
+
list(GET ARGN ${i} key)
list(GET ARGN ${j} value)
- #message(STATUS " ${key}='${value}'")
-
- if(key STREQUAL "BUILD_ARGS")
- set_target_properties(${name} PROPERTIES AEP_BUILD_ARGS "${value}")
- endif()
-
- if(key STREQUAL "BUILD_COMMAND")
- set_target_properties(${name} PROPERTIES AEP_BUILD_COMMAND "${value}")
- endif()
-
- if(key STREQUAL "CONFIGURE_ARGS")
- set_target_properties(${name} PROPERTIES AEP_CONFIGURE_ARGS "${value}")
- endif()
-
- if(key STREQUAL "CONFIGURE_COMMAND")
- set_target_properties(${name} PROPERTIES AEP_CONFIGURE_COMMAND "${value}")
- endif()
-
- if(key STREQUAL "CONFIGURE_DIR")
- set_target_properties(${name} PROPERTIES AEP_CONFIGURE_DIR "${value}")
- endif()
-
- if(key STREQUAL "CVS_REPOSITORY")
- set_target_properties(${name} PROPERTIES AEP_CVS_REPOSITORY "${value}")
- endif()
-
- if(key STREQUAL "CVS_MODULE")
- set_target_properties(${name} PROPERTIES AEP_CVS_MODULE "${value}")
- endif()
-
- if(key STREQUAL "CVS_TAG")
- set_target_properties(${name} PROPERTIES AEP_CVS_TAG "${value}")
- endif()
-
- if(key STREQUAL "DEPENDS")
- add_dependencies(${name} ${value})
- endif()
-
- if(key STREQUAL "DIR")
- set_target_properties(${name} PROPERTIES AEP_DIR "${value}")
- endif()
- if(key STREQUAL "INSTALL_ARGS")
- set_target_properties(${name} PROPERTIES AEP_INSTALL_ARGS "${value}")
- endif()
-
- if(key STREQUAL "INSTALL_COMMAND")
- set_target_properties(${name} PROPERTIES AEP_INSTALL_COMMAND "${value}")
- endif()
-
- if(key STREQUAL "SVN_REPOSITORY")
- set_target_properties(${name} PROPERTIES AEP_SVN_REPOSITORY "${value}")
- endif()
-
- if(key STREQUAL "SVN_TAG")
- set_target_properties(${name} PROPERTIES AEP_SVN_TAG "${value}")
- endif()
-
- if(key STREQUAL "TAR")
- set_target_properties(${name} PROPERTIES AEP_TAR "${value}")
- endif()
-
- if(key STREQUAL "TAR_URL")
- set_target_properties(${name} PROPERTIES AEP_TAR_URL "${value}")
- endif()
-
- if(key STREQUAL "TGZ")
- set_target_properties(${name} PROPERTIES AEP_TGZ "${value}")
- endif()
-
- if(key STREQUAL "TGZ_URL")
- set_target_properties(${name} PROPERTIES AEP_TGZ_URL "${value}")
+ is_known_aep_property_key("${key}" is_known_key)
+
+ if(is_known_key)
+ if(key STREQUAL "DEPENDS")
+ if(NOT value STREQUAL "")
+ add_dependencies(${name} ${value})
+ else()
+ message(STATUS "warning: empty DEPENDS value in add_external_project")
+ endif()
+ else()
+ set_target_properties(${name} PROPERTIES AEP_${key} "${value}")
+ endif()
+ else()
+ message(SEND_ERROR "error: unknown add_external_project key with name='${name}' key='${key}' value='${value}'")
endif()
math(EXPR i ${i}+2)
endwhile()
+
+ # Set up custom build steps based on the target properties.
+ # Each step depends on the previous one.
+ #
+ # The target depends on the output of the final step.
+ # (Already set up above in the DEPENDS of the add_custom_target command.)
+ #
add_external_project_download_command(${name})
add_external_project_configure_command(${name})
add_external_project_build_command(${name})
add_external_project_install_command(${name})
-
- add_dependencies(${name} CMakeExternals)
endfunction(add_external_project)
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index c894037..00fffc9 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -16,23 +16,64 @@ set(prefix "${install_dir}")
#
include("${CMAKE_CURRENT_SOURCE_DIR}/TryCheckout.cmake")
-try_cvs_checkout(
- ":pserver:anonymous:cmake@www.cmake.org:/cvsroot/CMake"
- "CMake/Tests/Tutorial/Step1"
- "${CMAKE_CURRENT_BINARY_DIR}/TryCheckout/TutorialStep1"
- can_use_cvs
- )
+if(NOT DEFINED can_use_cvs)
+ try_cvs_checkout(
+ ":pserver:anonymous:cmake@www.cmake.org:/cvsroot/CMake"
+ "CMake/Tests/Tutorial/Step1"
+ "${CMAKE_CURRENT_BINARY_DIR}/TryCheckout/TutorialStep1"
+ can_use_cvs
+ )
+ set(can_use_cvs ${can_use_cvs} CACHE STRING "Was try_cvs_checkout successful?")
+endif()
-try_svn_checkout(
- "http://gdcm.svn.sourceforge.net/svnroot/gdcm/trunk/Utilities/gdcmmd5"
- "${CMAKE_CURRENT_BINARY_DIR}/TryCheckout/gdcmmd5"
- can_use_svn
- )
+if(NOT DEFINED can_use_svn)
+ try_svn_checkout(
+ "http://gdcm.svn.sourceforge.net/svnroot/gdcm/trunk/Utilities/gdcmmd5"
+ "${CMAKE_CURRENT_BINARY_DIR}/TryCheckout/gdcmmd5"
+ can_use_svn
+ )
+ set(can_use_svn ${can_use_svn} CACHE STRING "Was try_svn_checkout successful?")
+endif()
message(STATUS "can_use_cvs='${can_use_cvs}'")
message(STATUS "can_use_svn='${can_use_svn}'")
+# Empty projects that test all the known add_external_project argument key words:
+#
+set(proj MinimalNoOpProject)
+add_external_project(${proj}
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+
+set(proj EmptyNoOpProject)
+add_external_project(${proj}
+ BUILD_ARGS ""
+ BUILD_COMMAND ""
+ CONFIGURE_ARGS ""
+ CONFIGURE_COMMAND ""
+ CONFIGURE_DIR ""
+ CVS_REPOSITORY ""
+ CVS_MODULE ""
+ CVS_TAG ""
+ DEPENDS "MinimalNoOpProject"
+ DIR ""
+ DOWNLOAD_ARGS ""
+ DOWNLOAD_COMMAND ""
+ INSTALL_ARGS ""
+ INSTALL_COMMAND ""
+ SVN_REPOSITORY ""
+ SVN_TAG ""
+ TAR ""
+ TAR_URL ""
+ TGZ ""
+ TGZ_URL ""
+)
+
+
# Local DIR:
#
set(proj TutorialStep5-Local)
@@ -70,7 +111,7 @@ add_external_project(${proj}
set(proj TutorialStep1-LocalNoDirTGZ)
add_external_project(${proj}
- TGZ "${CMAKE_CURRENT_SOURCE_DIR}/Step1.tgz"
+ TGZ "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tgz"
CONFIGURE_ARGS "\"-DCMAKE_INSTALL_PREFIX:PATH=${prefix}\" -G \"${CMAKE_GENERATOR}\" \"${source_dir}/${proj}\""
INSTALL_COMMAND ""
)
@@ -91,12 +132,13 @@ add_external_project(${proj}
if(can_use_cvs)
# CVS by date stamp:
#
- set(proj KWStyle-20081201)
+ set(proj TutorialStep1-20081201)
add_external_project(${proj}
- CVS_REPOSITORY ":pserver:anoncvs@public.kitware.com:/cvsroot/KWStyle"
- CVS_MODULE "KWStyle"
+ CVS_REPOSITORY ":pserver:anonymous:cmake@www.cmake.org:/cvsroot/CMake"
+ CVS_MODULE "CMake/Tests/Tutorial/Step1"
CVS_TAG "-D\;2008-12-01 01:00:00 UTC"
CONFIGURE_ARGS "\"-DCMAKE_INSTALL_PREFIX:PATH=${prefix}\" -G \"${CMAKE_GENERATOR}\" \"${source_dir}/${proj}\""
+ INSTALL_COMMAND ""
)
# CVS by tag:
@@ -112,12 +154,19 @@ if(can_use_cvs)
# Live CVS / HEAD (no CVS_TAG):
#
- set(proj TutorialStep1-CVSHEAD)
+ set(proj KWStyle-CVSHEAD)
add_external_project(${proj}
- CVS_REPOSITORY ":pserver:anonymous:cmake@www.cmake.org:/cvsroot/CMake"
- CVS_MODULE "CMake/Tests/Tutorial/Step1"
+ CVS_REPOSITORY ":pserver:anoncvs@public.kitware.com:/cvsroot/KWStyle"
+ CVS_MODULE "KWStyle"
CONFIGURE_ARGS "\"-DCMAKE_INSTALL_PREFIX:PATH=${prefix}\" -G \"${CMAKE_GENERATOR}\" \"${source_dir}/${proj}\""
- INSTALL_COMMAND ""
+ DEPENDS "EmptyNoOpProject"
+ DEPENDS "TutorialStep5-Local"
+ DEPENDS "TutorialStep1-LocalTAR"
+ DEPENDS "TutorialStep1-LocalNoDirTAR"
+ DEPENDS "TutorialStep1-LocalTGZ"
+ DEPENDS "TutorialStep1-LocalNoDirTGZ"
+ DEPENDS "TutorialStep1-20081201"
+ DEPENDS "kwsys-from-CMake-2-6-2"
)
endif()
@@ -162,7 +211,7 @@ enable_testing()
# Use these as input to the KWStyle tests:
#
-set(kwstyleXmlFile "${source_dir}/KWStyle-20081201/Testing/Data/0001-KWStyleConfiguration.kws.xml")
+set(kwstyleXmlFile "${source_dir}/KWStyle-CVSHEAD/Testing/Data/0001-KWStyleConfiguration.kws.xml")
set(header "${install_dir}/include/TutorialConfig.h")
@@ -187,14 +236,14 @@ add_test(TutorialStep1-LocalNoDirTGZ-BuildTreeTest
"${build_dir}/TutorialStep1-LocalNoDirTGZ/Tutorial" 9)
if(can_use_cvs)
- add_test(KWStyle-20081201-BuildTreeTest
- "${build_dir}/KWStyle-20081201/KWStyle" -xml "${kwstyleXmlFile}" "${header}")
+ add_test(TutorialStep1-20081201-BuildTreeTest
+ "${build_dir}/TutorialStep1-20081201/Tutorial" 4)
add_test(kwsys-from-CMake-2-6-2-BuildTreeTest
"${build_dir}/kwsys-from-CMake-2-6-2/kwsysTestProcess" 1)
- add_test(TutorialStep1-CVSHEAD-BuildTreeTest
- "${build_dir}/TutorialStep1-LocalNoDirTGZ/Tutorial" 4)
+ add_test(KWStyle-CVSHEAD-BuildTreeTest
+ "${build_dir}/KWStyle-CVSHEAD/KWStyle" -xml "${kwstyleXmlFile}" "${header}")
endif()
if(can_use_svn)