[PATCH] ExternalProject: Add EXTRACT_COMMAND option
Pau Garcia i Quiles
pgquiles at elpauer.org
Tue Nov 26 09:36:49 EST 2013
Add an EXTRACT_COMMAND option to ExternalProject_Add to specify the
extraction command explicitly. This is useful when downloading a file
that CMake does not know how to extract, but we do. Rather than having
to replace the entire DOWNLOAD_COMMAND with a custom version, this
allows us to re-use the builtin download features while plugging in our
own extraction command.
Extend the ExternalProject test to cover custom extraction of a
self-extracting zip file.
---
Modules/ExternalProject.cmake | 42 +++++++++++++++++-----------
Tests/ExternalProject/CMakeLists.txt | 15 ++++++++++
Tests/ExternalProject/autoextractingzip.exe | Bin 0 -> 1074 bytes
3 files changed, 41 insertions(+), 16 deletions(-)
create mode 100644 Tests/ExternalProject/autoextractingzip.exe
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 63f1180..4cd7a3c 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -38,6 +38,8 @@
# [TLS_VERIFY bool] # Should certificate for https be checked
# [TLS_CAINFO file] # Path to a certificate authority file
# [TIMEOUT seconds] # Time allowed for file download operations
+# #--Extract step --------------
+# [EXTRACT_COMMAND cmd...] # Custom command to extract downloaded file
# #--Update/Patch step----------
# [UPDATE_COMMAND cmd...] # Source work-tree update command
# [PATCH_COMMAND cmd...] # Command to patch downloaded source
@@ -612,22 +614,27 @@ ${script_content}
endfunction()
-function(_ep_write_extractfile_script script_filename name filename directory)
+function(_ep_write_extractfile_script script_filename name filename directory excommand)
set(args "")
- if(filename MATCHES "(\\.|=)(bz2|tar\\.gz|tgz|zip)$")
- set(args xfz)
- endif()
+ if(NOT excommand STREQUAL "")
+ set(args "${excommand}")
+ else()
+ if(filename MATCHES "(\\.|=)(bz2|tar\\.gz|tgz|zip)$")
+ set(args "\${CMAKE_COMMAND} -E tar xfz")
+ endif()
- if(filename MATCHES "(\\.|=)tar$")
- set(args xf)
- endif()
+ if(filename MATCHES "(\\.|=)tar$")
+ set(args "\${CMAKE_COMMAND} -E tar xf")
+ endif()
- if(args STREQUAL "")
- message(SEND_ERROR "error: do not know how to extract '${filename}' -- known types are .bz2, .tar, .tar.gz, .tgz and .zip")
- return()
+ if(args STREQUAL "")
+ message(SEND_ERROR "error: do not know how to extract '${filename}' -- known types are .bz2, .tar, .tar.gz, .tgz and .zip")
+ return()
+ endif()
endif()
+
file(WRITE ${script_filename}
"# Make file names absolute:
#
@@ -653,8 +660,8 @@ file(MAKE_DIRECTORY \"\${ut_dir}\")
# Extract it:
#
-message(STATUS \"extracting... [tar ${args}]\")
-execute_process(COMMAND \${CMAKE_COMMAND} -E tar ${args} \${filename}
+message(STATUS \"extracting... [${args}]\")
+execute_process(COMMAND ${args} \${filename}
WORKING_DIRECTORY \${ut_dir}
RESULT_VARIABLE rv)
@@ -664,7 +671,7 @@ if(NOT rv EQUAL 0)
message(FATAL_ERROR \"error: extract of '\${filename}' failed\")
endif()
-# Analyze what came out of the tar file:
+# Analyze what came out of the file:
#
message(STATUS \"extracting... [analysis]\")
file(GLOB contents \"\${ut_dir}/*\")
@@ -1216,6 +1223,9 @@ function(_ep_add_download_command name)
get_property(hg_repository TARGET ${name} PROPERTY _EP_HG_REPOSITORY )
get_property(url TARGET ${name} PROPERTY _EP_URL)
get_property(fname TARGET ${name} PROPERTY _EP_DOWNLOAD_NAME)
+ get_property(excmd_set TARGET ${name} PROPERTY _EP_EXTRACT_COMMAND SET)
+ get_property(excmd TARGET ${name} PROPERTY _EP_EXTRACT_COMMAND)
+
# TODO: Perhaps file:// should be copied to download dir before extraction.
string(REGEX REPLACE "^file://" "" url "${url}")
@@ -1411,11 +1421,11 @@ function(_ep_add_download_command name)
if("x${fname}" STREQUAL "x")
string(REGEX MATCH "[^/\\?]*$" fname "${url}")
endif()
- if(NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|zip)$")
+ if(NOT excmd_set AND NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|zip)$")
string(REGEX MATCH "([^/\\?]+(\\.|=)(bz2|tar|tgz|tar\\.gz|zip))/.*$" match_result "${url}")
set(fname "${CMAKE_MATCH_1}")
endif()
- if(NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|zip)$")
+ if(NOT excmd_set AND NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|zip)$")
message(FATAL_ERROR "Could not extract tarball filename from url:\n ${url}")
endif()
string(REPLACE ";" "-" fname "${fname}")
@@ -1435,7 +1445,7 @@ function(_ep_add_download_command name)
_ep_write_verifyfile_script("${stamp_dir}/verify-${name}.cmake" "${file}" "${hash}")
list(APPEND cmd ${CMAKE_COMMAND} -P ${stamp_dir}/verify-${name}.cmake
COMMAND)
- _ep_write_extractfile_script("${stamp_dir}/extract-${name}.cmake" "${name}" "${file}" "${source_dir}")
+ _ep_write_extractfile_script("${stamp_dir}/extract-${name}.cmake" "${name}" "${file}" "${source_dir}" "${excmd}")
list(APPEND cmd ${CMAKE_COMMAND} -P ${stamp_dir}/extract-${name}.cmake)
endif()
else()
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index 602ff0f..65f008e 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -250,6 +250,21 @@ ExternalProject_Add(${proj}
)
set_property(TARGET ${proj} PROPERTY FOLDER "Local/ZIP")
+# Local autoextracting ZIP:
+#
+# (The extract test here is just to verify the EXTRACT_COMMAND does
+# overrides the downloadable files white list... The configure and build
+# commands are set to nothing to make the test quicker...)
+#
+set(proj TutorialStep1-LocalExtractCommand)
+ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/autoextractingzip.exe"
+ EXTRACT_COMMAND ${CMAKE_COMMAND} -E tar xvf "${CMAKE_CURRENT_SOURCE_DIR}/autoextractingzip.exe"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "Local/ExtractCommand")
# CVS-based tests:
#
diff --git a/Tests/ExternalProject/autoextractingzip.exe b/Tests/ExternalProject/autoextractingzip.exe
new file mode 100644
index 0000000000000000000000000000000000000000..49dac24edff7e6b281bd3ce85cfd1a9f3dbd6107
GIT binary patch
literal 1074
zcmWIWW at Zs#U|`^2SYEWuCj7HufgU3RgESKZ14uNuB(=a$-`O`YJJlz%xTILGq at tvB
zqQC!P1D>Pre~Mgta3Sv0eCF?gWiOVjT_No;XOT|fb%)tJ>WR)B at BN~B4_?@zT6g}u
z{pn4@`X{V&OT?}Gen^=tY<f}{q}x@*cm1aCDYKOMfmI&U4n|*E<SS|2oZ9 at M?a3C?
z1gGszr)C_E*W1VcaP!A4YaVF*_1AkAxKGAusp-}@b|--g3j#a>UW*-!zQOVQz)ik`
z*B(6nP$PCzF|8{1nx2_^aD2Jhgd-A5C&+&KAu!pX;o{HZwV{6MKPTy*YS)_oVfUh6
zdwv`{)!w(}<Q7TU-TB==cT`!ueYf^7lhaDZq@}$J%0IMJJaBT{)LH$5Ez5gBZ%*@}
z#DjA8znVQv?A~xSSNgTv!TXLm_m76!OnGBkax(M8ML~gg0c`qVx|<>%+223xc;LPK
z%sX#`zOe?NgzwF&uRHXC;p+<wUm<w-mXwy{7iA{q=p|QFv<CWSA94`b`+j}J5|$*+
z!0I*I6qd4cn<lIk*WRQyJ4Nwk at 9&G<Kkn~7)^SX1S9 at aGx4o79GwbAqGvcnQI<HMx
zm%$nw(CiYn)zoKqm*ab#P#!NY=9!I7H?mHP?0l at GnS09Mn%Yw%t$DlGPRifCw`<m-
z%OAzAc^u9BspNX>^NJ4~4-YL^6r*5~7V^}yW61)p?|T2^)>fzZGt5)8_?OtzK5unn
zt?=e3%P296%1qxEKc&2vnM`M at llu8``iDbo6?JDX9Ncx==JqX}_~-JME4Ee6-*fcy
ze}l`BHt&1?ZTYw|^PJqnJ9Em)w_McP&U3UUl<9DAX~9Lq?eFwrc6jS#W=hU;=snZa
zW?>^3JwbS<)62O=2V1W*<jd;T$zMBvaBH`@^)4Q+^`)~`u6=#5L*@iOYVgh%Uab`i
z4A!MUEC~<Z5NPl^=jWwmrt4+sW#(PJ9<FiHBh=&EdGFIc`nq1efhY7ePM$fh9p-Vy
zJ5a+<SM%f<Z~ZWj)A~Uinz|?TPx+jA806>ad-{xbEBBH1oouYtzkVP6ZB_M?UDF~#
zy!^o8^OyN|+fCTPEH2Iv;LXS+0?t0zGZoNb48Sx11=z9}x(VpX2BZ~YLIRM2n1Gy!
i(DkE-3qt>XU_ylG#}Y~b-mGjOrOZHh5=aL#gLnWD?Xc(o
literal 0
HcmV?d00001
--
1.8.4.rc3
--------------080801080103070902050407--
More information about the cmake-developers
mailing list