On 11/25/2013 07:01 PM, Pau Garcia i Quiles wrote: > I have implemented an EXTRACT_COMMAND for ExternalProject_Add. > > It is useful in case you are downloading a file that CMake does > not know how to extract, but you do (e. g. NSIS installers that > can be extracted without installation, self-extracting ZIP files, etc). > > Code is here for now: > > https://elpauer.assembla.com/code/elpauercmake/git/nodes/epa_extract_command > > A test has been implemented. Run "git diff master epa_extract_command" to > see the changes, which are not really that important.
Thanks for working on this. I squashed the topic into a single commit and attached the patch for reference here. As I state in the commit message it is useful to be able to re-use the builtin download command and just substitute the extraction command. The test fails for me with spaces in the path because you're writing the extraction command into the script without quoting so the spaces cause incorrect parsing at build time. You can write it as file(WRITE ... " ... set(extract_command "${extract_command}") ... ... COMMAND \${extract_command} ... ... ") so that the exact value of the command is stored in the script and expanded when evaluated at build time. It is probably simplest to refactor the default extraction command to be written into the script in this way also. Then you simply don't generate the default when an explicit command is passed. The EXTRACT_COMMAND needs a way to have a placeholder for the file name so that the caller does not need to know where ExternalProject keeps the file after downloading. > I don't understand the "...After you have been invited..." > in http://www.cmake.org/Wiki/CMake/Git/Account#Git > (who would know I need an invitation!?) The sentence immediately preceding that says "See our new maintainer instructions to join" and has a link to the instructions. They have a step for posting to this list for discussion. We invite productive contributors for direct access in due time. -Brad
>From e9ae31d869604a5f759a8ec191c98faab4a9d3a0 Mon Sep 17 00:00:00 2001 Message-Id: <e9ae31d869604a5f759a8ec191c98faab4a9d3a0.1385478441.git.brad.k...@kitware.com> From: Pau Garcia i Quiles <pgqui...@elpauer.org> Date: Tue, 26 Nov 2013 09:36:49 -0500 Subject: [PATCH] ExternalProject: Add EXTRACT_COMMAND option 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@Zs#U|`^2SYEWuCj7HufgU3RgESKZ14uNuB(=a$-`O`YJJlz%xTILGq@tvB zqQC!P1D>Pre~Mgta3Sv0eCF?gWiOVjT_No;XOT|fb%)tJ>WR)B@BN~B4_?@zT6g}u z{pn4@`X{V&OT?}Gen^=tY<f}{q}x@*cm1aCDYKOMfmI&U4n|*E<SS|2oZ9@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@9&G<Kkn~7)^SX1S9@aGx4o79GwbAqGvcnQI<HMx zm%$nw(CiYn)zoKqm*ab#P#!NY=9!I7H?mHP?0l@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@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
-- Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers