summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Cole <david.cole@kitware.com>2008-12-19 15:35:16 (GMT)
committerDavid Cole <david.cole@kitware.com>2008-12-19 15:35:16 (GMT)
commit468c9e250b3b3f710cb6e15bcbc538e3a54fcb63 (patch)
tree92521e7294814a96fde0e9ca0ad4c733bf48ce43
parent690f83b81b3dfcf3a80f938df0b7a3a0f0ad1992 (diff)
downloadCMake-468c9e250b3b3f710cb6e15bcbc538e3a54fcb63.zip
CMake-468c9e250b3b3f710cb6e15bcbc538e3a54fcb63.tar.gz
CMake-468c9e250b3b3f710cb6e15bcbc538e3a54fcb63.tar.bz2
ENH: Add the update step in between download and build. Add UPDATE_ARGS and UPDATE_COMMAND handling. Output a -complete sentinel in synch with the -install sentinel, but do not list it as an OUTPUT of the custom command. That breaks the chaining of add_custom_commands between custom targets, but allows for a file-level dependency expression that will cause proper incremental rebuilds. When earlier targets rebuild, subsequent dependent targets will also rebuild. CVS and SVN update commands are always out-of-date so that they always run to get the latest source. To suppress that behavior on a per-external project basis use an explicit empty string for UPDATE_COMMAND. The source will still be checked out from the repository prior to the update step by the download step.
-rw-r--r--Modules/AddExternalProject.cmake162
1 files changed, 129 insertions, 33 deletions
diff --git a/Modules/AddExternalProject.cmake b/Modules/AddExternalProject.cmake
index 454d2bd..acfccf5 100644
--- a/Modules/AddExternalProject.cmake
+++ b/Modules/AddExternalProject.cmake
@@ -76,12 +76,10 @@ endfunction(mkdir)
function(add_external_project_download_command name)
- set(added 0)
get_external_project_directories(base_dir build_dir downloads_dir install_dir
sentinels_dir source_dir tmp_dir)
- if(NOT added)
get_target_property(cmd ${name} AEP_DOWNLOAD_COMMAND)
if(cmd STREQUAL "")
# Explicit empty string means no download step for this project
@@ -92,7 +90,7 @@ function(add_external_project_download_command name)
COMMENT "No download step for '${name}'"
DEPENDS ${sentinels_dir}/CMakeExternals-directories
)
- set(added 1)
+ return()
else()
if(cmd)
set(args "")
@@ -110,16 +108,14 @@ function(add_external_project_download_command name)
COMMENT "Performing download step for '${name}'"
DEPENDS ${sentinels_dir}/CMakeExternals-directories
)
- set(added 1)
+ return()
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)
@@ -137,7 +133,7 @@ function(add_external_project_download_command name)
set(cvs_tag ${tag})
endif()
- set(args -d ${cvs_repository} co ${cvs_tag} -d ${name} ${cvs_module})
+ set(args -d ${cvs_repository} -q co ${cvs_tag} -d ${name} ${cvs_module})
set(repository ${cvs_repository})
set(module ${cvs_module})
@@ -158,12 +154,10 @@ function(add_external_project_download_command name)
COMMENT "Performing download step (CVS checkout) for '${name}'"
DEPENDS ${sentinels_dir}/${name}-cvsinfo.txt
)
- set(added 1)
+ return()
endif()
- endif(NOT added)
- if(NOT added)
get_target_property(svn_repository ${name} AEP_SVN_REPOSITORY)
if(svn_repository)
if(NOT Subversion_SVN_EXECUTABLE)
@@ -197,12 +191,10 @@ function(add_external_project_download_command name)
COMMENT "Performing download step (SVN checkout) for '${name}'"
DEPENDS ${sentinels_dir}/${name}-svninfo.txt
)
- set(added 1)
+ return()
endif()
- endif(NOT added)
- if(NOT added)
get_target_property(dir ${name} AEP_DIR)
if(dir)
get_filename_component(abs_dir "${dir}" ABSOLUTE)
@@ -227,12 +219,10 @@ function(add_external_project_download_command name)
COMMENT "Performing download step (DIR copy) for '${name}'"
DEPENDS ${sentinels_dir}/${name}-dirinfo.txt
)
- set(added 1)
+ return()
endif()
- endif(NOT added)
- if(NOT added)
get_target_property(tar ${name} AEP_TAR)
if(tar)
mkdir("${source_dir}/${name}")
@@ -244,12 +234,10 @@ function(add_external_project_download_command name)
COMMENT "Performing download step (TAR untar) for '${name}'"
DEPENDS ${tar}
)
- set(added 1)
+ return()
endif()
- endif(NOT added)
- if(NOT added)
get_target_property(tgz ${name} AEP_TGZ)
if(tgz)
mkdir("${source_dir}/${name}")
@@ -261,12 +249,10 @@ function(add_external_project_download_command name)
COMMENT "Performing download step (TGZ untar) for '${name}'"
DEPENDS ${tgz}
)
- set(added 1)
+ return()
endif()
- endif(NOT added)
- if(NOT added)
get_target_property(tgz_url ${name} AEP_TGZ_URL)
if(tgz_url)
set(repository "add_external_project TGZ_URL")
@@ -289,12 +275,10 @@ function(add_external_project_download_command name)
COMMENT "Performing download step (TGZ_URL download and untar) for '${name}'"
DEPENDS ${sentinels_dir}/${name}-urlinfo.txt
)
- set(added 1)
+ return()
endif()
- endif(NOT added)
- if(NOT added)
get_target_property(tar_url ${name} AEP_TAR_URL)
if(tar_url)
set(repository "add_external_project TAR_URL")
@@ -317,22 +301,129 @@ function(add_external_project_download_command name)
COMMENT "Performing download step (TAR_URL download and untar) for '${name}'"
DEPENDS ${sentinels_dir}/${name}-urlinfo.txt
)
- set(added 1)
+ return()
endif()
- endif(NOT added)
- if(NOT added)
- message(SEND_ERROR "error: no download info for '${name}'")
- endif(NOT added)
+ message(SEND_ERROR "error: no download info for '${name}'")
endfunction(add_external_project_download_command)
+function(add_external_project_update_command name)
+ set(added 0)
+ get_external_project_directories(base_dir build_dir downloads_dir install_dir
+ sentinels_dir source_dir tmp_dir)
+
+
+ get_target_property(cmd ${name} AEP_UPDATE_COMMAND)
+ if(cmd STREQUAL "")
+ # Explicit empty string means no update step for this project
+ add_custom_command(
+ OUTPUT ${sentinels_dir}/${name}-update
+ COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-update
+ WORKING_DIRECTORY ${sentinels_dir}
+ COMMENT "No update step for '${name}'"
+ DEPENDS ${sentinels_dir}/${name}-download
+ )
+ return()
+ else()
+ if(cmd)
+ set(args "")
+ get_target_property(update_args ${name} AEP_UPDATE_ARGS)
+ if(update_args)
+ set(args "${update_args}")
+ separate_arguments(args)
+ endif()
+
+ add_custom_command(
+ OUTPUT ${sentinels_dir}/${name}-update
+ COMMAND ${cmd} ${args}
+ COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-update
+ WORKING_DIRECTORY ${source_dir}/${name}
+ COMMENT "Performing update step for '${name}'"
+ DEPENDS ${sentinels_dir}/${name}-download
+ )
+ return()
+ else()
+ # No explicit UPDATE_COMMAND property. Look for other properties
+ # indicating which update method to use in the logic below...
+ endif()
+ endif()
+
+
+ get_target_property(cvs_repository ${name} AEP_CVS_REPOSITORY)
+ if(cvs_repository)
+ if(NOT CVS_EXECUTABLE)
+ message(FATAL_ERROR "error: could not find cvs for update of ${name}")
+ endif()
+
+ get_target_property(tag ${name} AEP_CVS_TAG)
+ set(cvs_tag)
+ if(tag)
+ set(cvs_tag ${tag})
+ endif()
+
+ set(args -d ${cvs_repository} -q up -dP ${cvs_tag})
+
+ mkdir("${source_dir}/${name}")
+ add_custom_command(
+ OUTPUT ${sentinels_dir}/${name}-update
+ COMMAND ${CVS_EXECUTABLE} ${args}
+ WORKING_DIRECTORY ${source_dir}/${name}
+ COMMENT "Performing update step (CVS update) for '${name}'"
+ DEPENDS ${sentinels_dir}/${name}-download
+ )
+ return()
+ endif()
+
+
+ get_target_property(svn_repository ${name} AEP_SVN_REPOSITORY)
+ if(svn_repository)
+ if(NOT Subversion_SVN_EXECUTABLE)
+ message(FATAL_ERROR "error: could not find svn for update of ${name}")
+ endif()
+
+ get_target_property(tag ${name} AEP_SVN_TAG)
+ set(svn_tag)
+ if(tag)
+ set(svn_tag ${tag})
+ endif()
+
+ set(args up ${svn_tag})
+
+ mkdir("${source_dir}/${name}")
+ add_custom_command(
+ OUTPUT ${sentinels_dir}/${name}-update
+ COMMAND ${Subversion_SVN_EXECUTABLE} ${args}
+ WORKING_DIRECTORY ${source_dir}/${name}
+ COMMENT "Performing update step (SVN update) for '${name}'"
+ DEPENDS ${sentinels_dir}/${name}-download
+ )
+ return()
+ endif()
+
+
+ add_custom_command(
+ OUTPUT ${sentinels_dir}/${name}-update
+ COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-update
+ WORKING_DIRECTORY ${sentinels_dir}
+ COMMENT "No update step for '${name}'"
+ DEPENDS ${sentinels_dir}/${name}-download
+ )
+endfunction(add_external_project_update_command)
+
+
function(add_external_project_configure_command name)
get_external_project_directories(base_dir build_dir downloads_dir install_dir
sentinels_dir source_dir tmp_dir)
get_configure_build_working_dir(${name} working_dir)
+ get_target_property(file_deps ${name} AEP_FILE_DEPENDS)
+ if(NOT file_deps)
+ set(file_deps)
+ endif()
+ #message(STATUS "info: name='${name}' file_deps='${file_deps}'")
+
# Create the working_dir for configure, build and install steps:
#
mkdir("${working_dir}")
@@ -340,7 +431,8 @@ function(add_external_project_configure_command name)
OUTPUT ${sentinels_dir}/${name}-working_dir
COMMAND ${CMAKE_COMMAND} -E make_directory ${working_dir}
COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-working_dir
- DEPENDS ${sentinels_dir}/${name}-download
+ DEPENDS ${sentinels_dir}/${name}-update
+ ${file_deps}
)
get_target_property(cmd ${name} AEP_CONFIGURE_COMMAND)
@@ -438,6 +530,7 @@ function(add_external_project_install_command name)
add_custom_command(
OUTPUT ${sentinels_dir}/${name}-install
COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-install
+ COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-complete
WORKING_DIRECTORY ${working_dir}
COMMENT "No install step for '${name}'"
DEPENDS ${sentinels_dir}/${name}-build
@@ -472,6 +565,7 @@ function(add_external_project_install_command name)
OUTPUT ${sentinels_dir}/${name}-install
COMMAND ${cmd} ${args}
COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-install
+ COMMAND ${CMAKE_COMMAND} -E touch ${sentinels_dir}/${name}-complete
WORKING_DIRECTORY ${working_dir}
COMMENT "Performing install step for '${name}'"
DEPENDS ${sentinels_dir}/${name}-build
@@ -523,7 +617,7 @@ 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$"
+ 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|UPDATE_ARGS|UPDATE_COMMAND$"
)
#message(STATUS "info: recognized via MATCHES - key='${key}'")
set(${result_var} 1 PARENT_SCOPE)
@@ -575,11 +669,12 @@ function(add_external_project name)
if(key STREQUAL "DEPENDS")
if(NOT value STREQUAL "")
add_dependencies(${name} ${value})
+ set_property(TARGET ${name} APPEND PROPERTY AEP_FILE_DEPENDS "${sentinels_dir}/${value}-complete")
else()
message(STATUS "warning: empty DEPENDS value in add_external_project")
endif()
else()
- set_target_properties(${name} PROPERTIES AEP_${key} "${value}")
+ set_property(TARGET ${name} PROPERTY AEP_${key} "${value}")
endif()
else()
message(SEND_ERROR "error: unknown add_external_project key with name='${name}' key='${key}' value='${value}'")
@@ -596,6 +691,7 @@ function(add_external_project name)
# (Already set up above in the DEPENDS of the add_custom_target command.)
#
add_external_project_download_command(${name})
+ add_external_project_update_command(${name})
add_external_project_configure_command(${name})
add_external_project_build_command(${name})
add_external_project_install_command(${name})