aboutsummaryrefslogtreecommitdiff
path: root/third-party/cmake/DownloadAndExtractFile.cmake
blob: 14873793d9120046c5b83c7417d665e913327d95 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
if(NOT DEFINED PREFIX)
  message(FATAL_ERROR "PREFIX must be defined.")
endif()

if(NOT DEFINED URL)
  message(FATAL_ERROR "URL must be defined.")
endif()

if(NOT DEFINED DOWNLOAD_DIR)
  message(FATAL_ERROR "DOWNLOAD_DIR must be defined.")
endif()

if((NOT DEFINED EXPECTED_SHA1) OR (NOT DEFINED EXPECTED_MD5))
  message(FATAL_ERROR "EXPECTED_SHA1 or EXPECTED_MD5 must be defined.")
endif()

if(NOT DEFINED TARGET)
  message(FATAL_ERROR "TARGET must be defined.")
endif()

# Taken from ExternalProject_Add.  Let's hope we can drop this one day when
# ExternalProject_Add allows you to disable SHOW_PROGRESS on the file download.
if(TIMEOUT)
  set(timeout_args TIMEOUT ${timeout})
  set(timeout_msg "${timeout} seconds")
else()
  set(timeout_args "# no TIMEOUT")
  set(timeout_msg "none")
endif()

string(REGEX MATCH "[^/\\?]*$" fname "${URL}")
if(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)$")
  message(FATAL_ERROR "Could not extract tarball filename from url:\n  ${url}")
endif()
string(REPLACE ";" "-" fname "${fname}")

set(file ${DOWNLOAD_DIR}/${fname})
message(STATUS "file: ${file}")

message(STATUS "downloading...
     src='${URL}'
     dst='${file}'
     timeout='${timeout_msg}'")

if((DEFINED EXPECTED_SHA1) AND (${CMAKE_VERSION} VERSION_GREATER 2.8.10))
  set(hash_args EXPECTED_HASH SHA1=${EXPECTED_SHA1})
else()
  set(hash_args EXPECTED_MD5 ${EXPECTED_MD5})
endif()

file(DOWNLOAD ${URL} ${file}
  ${timeout_args}
  ${hash_args}
  STATUS status
  LOG log)

list(GET status 0 status_code)
list(GET status 1 status_string)

if(NOT status_code EQUAL 0)
  message(FATAL_ERROR "error: downloading '${URL}' failed
  status_code: ${status_code}
  status_string: ${status_string}
  log: ${log}
")
endif()

message(STATUS "downloading... done")

set(SRC_DIR ${PREFIX}/src/${TARGET})

# Slurped from a generated extract-TARGET.cmake file.
message(STATUS "extracting...
     src='${file}'
     dst='${SRC_DIR}'")

if(NOT EXISTS "${file}")
  message(FATAL_ERROR "error: file to extract does not exist: '${file}'")
endif()

# Prepare a space for extracting:
#
set(i 1234)
while(EXISTS "${SRC_DIR}/../ex-${TARGET}${i}")
  math(EXPR i "${i} + 1")
endwhile()
set(ut_dir "${SRC_DIR}/../ex-${TARGET}${i}")
file(MAKE_DIRECTORY "${ut_dir}")

# Extract it:
#
message(STATUS "extracting... [tar xfz]")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xfz ${file}
  WORKING_DIRECTORY ${ut_dir}
  RESULT_VARIABLE rv)

if(NOT rv EQUAL 0)
  message(STATUS "extracting... [error clean up]")
  file(REMOVE_RECURSE "${ut_dir}")
  message(FATAL_ERROR "error: extract of '${file}' failed")
endif()

# Analyze what came out of the tar file:
#
message(STATUS "extracting... [analysis]")
file(GLOB contents "${ut_dir}/*")
list(LENGTH contents n)
if(NOT n EQUAL 1 OR NOT IS_DIRECTORY "${contents}")
  set(contents "${ut_dir}")
endif()

# Move "the one" directory to the final directory:
#
message(STATUS "extracting... [rename]")
file(REMOVE_RECURSE ${SRC_DIR})
get_filename_component(contents ${contents} ABSOLUTE)
file(RENAME ${contents} ${SRC_DIR})

# Clean up:
#
message(STATUS "extracting... [clean up]")
file(REMOVE_RECURSE "${ut_dir}")

message(STATUS "extracting... done")