2017-05-25 14:33:16 +08:00
## # vcpkg_download_distfile
##
## Download and cache a file needed for this port.
##
2018-01-06 08:16:08 +08:00
## This helper should always be used instead of CMake's built-in `file(DOWNLOAD)` command.
##
2017-05-25 14:33:16 +08:00
## ## Usage
## ```cmake
## vcpkg_download_distfile(
## <OUT_VARIABLE>
## URLS <http://mainUrl> <http://mirror1>...
## FILENAME <output.zip>
## SHA512 <5981de...>
## )
## ```
## ## Parameters
## ### OUT_VARIABLE
## This variable will be set to the full path to the downloaded file. This can then immediately be passed in to [`vcpkg_extract_source_archive`](vcpkg_extract_source_archive.md) for sources.
##
## ### URLS
## A list of URLs to be consulted. They will be tried in order until one of the downloaded files successfully matches the SHA512 given.
##
## ### FILENAME
## The local name for the file. Files are shared between ports, so the file may need to be renamed to make it clearly attributed to this port and avoid conflicts.
##
## ### SHA512
## The expected hash for the file.
##
## If this doesn't match the downloaded version, the build will be terminated with a message describing the mismatch.
##
2017-12-30 06:21:18 +08:00
## ### SKIP_SHA512
## Skip SHA512 hash check for file.
##
2018-01-06 08:16:08 +08:00
## This switch is only valid when building with the `--head` command line flag.
##
2017-05-25 14:33:16 +08:00
## ## Notes
2018-01-06 08:16:08 +08:00
## The helper [`vcpkg_from_github`](vcpkg_from_github.md) should be used for downloading from GitHub projects.
2017-05-25 14:33:16 +08:00
##
## ## Examples
##
2018-01-06 08:16:08 +08:00
## * [apr](https://github.com/Microsoft/vcpkg/blob/master/ports/apr/portfile.cmake)
2017-05-25 14:33:16 +08:00
## * [fontconfig](https://github.com/Microsoft/vcpkg/blob/master/ports/fontconfig/portfile.cmake)
## * [openssl](https://github.com/Microsoft/vcpkg/blob/master/ports/openssl/portfile.cmake)
2016-09-19 11:50:08 +08:00
function ( vcpkg_download_distfile VAR )
2017-12-30 06:21:18 +08:00
set ( options SKIP_SHA512 )
2016-09-25 06:23:04 +08:00
set ( oneValueArgs FILENAME SHA512 )
set ( multipleValuesArgs URLS )
2017-12-30 06:21:18 +08:00
cmake_parse_arguments ( vcpkg_download_distfile "${options}" "${oneValueArgs}" "${multipleValuesArgs}" ${ ARGN } )
2017-11-03 09:54:10 +08:00
2017-12-21 19:47:02 +08:00
if ( NOT DEFINED vcpkg_download_distfile_URLS )
message ( FATAL_ERROR "vcpkg_download_distfile requires a URLS argument." )
endif ( )
if ( NOT DEFINED vcpkg_download_distfile_FILENAME )
message ( FATAL_ERROR "vcpkg_download_distfile requires a FILENAME argument." )
endif ( )
2018-01-14 11:49:04 +08:00
if ( NOT _VCPKG_INTERNAL_NO_HASH_CHECK )
if ( vcpkg_download_distfile_SKIP_SHA512 AND NOT VCPKG_USE_HEAD_VERSION )
message ( FATAL_ERROR "vcpkg_download_distfile only allows SKIP_SHA512 when building with --head" )
endif ( )
if ( NOT vcpkg_download_distfile_SKIP_SHA512 AND NOT DEFINED vcpkg_download_distfile_SHA512 )
message ( FATAL_ERROR "vcpkg_download_distfile requires a SHA512 argument. If you do not know the SHA512, add it as 'SHA512 0' and re-run this command." )
endif ( )
if ( vcpkg_download_distfile_SKIP_SHA512 AND DEFINED vcpkg_download_distfile_SHA512 )
message ( FATAL_ERROR "vcpkg_download_distfile must not be passed both SHA512 and SKIP_SHA512." )
endif ( )
2017-12-21 19:47:02 +08:00
endif ( )
2016-09-24 21:23:18 +08:00
set ( downloaded_file_path ${ DOWNLOADS } / ${ vcpkg_download_distfile_FILENAME } )
2017-11-03 09:54:10 +08:00
set ( download_file_path_part "${DOWNLOADS}/temp/${vcpkg_download_distfile_FILENAME}" )
file ( REMOVE_RECURSE "${DOWNLOADS}/temp" )
file ( MAKE_DIRECTORY "${DOWNLOADS}/temp" )
2016-09-25 06:36:50 +08:00
function ( test_hash FILE_KIND CUSTOM_ERROR_ADVICE )
2018-01-06 08:16:08 +08:00
if ( _VCPKG_INTERNAL_NO_HASH_CHECK )
# When using the internal hash skip, do not output an explicit message.
return ( )
endif ( )
if ( vcpkg_download_distfile_SKIP_SHA512 )
message ( STATUS "Skipping hash check for ${downloaded_file_path}." )
2017-11-04 05:34:08 +08:00
return ( )
endif ( )
2016-09-25 06:36:50 +08:00
message ( STATUS "Testing integrity of ${FILE_KIND}..." )
2016-09-24 21:23:18 +08:00
file ( SHA512 ${ downloaded_file_path } FILE_HASH )
if ( NOT "${FILE_HASH}" STREQUAL "${vcpkg_download_distfile_SHA512}" )
2016-09-19 11:50:08 +08:00
message ( FATAL_ERROR
2016-09-24 21:23:18 +08:00
" \ n F i l e d o e s n o t h a v e e x p e c t e d h a s h : \ n "
2016-09-25 06:24:38 +08:00
" F i l e p a t h : [ $ { d o w n l o a d e d _ f i l e _ p a t h } ] \ n "
" E x p e c t e d h a s h : [ $ { v c p k g _ d o w n l o a d _ d i s t f i l e _ S H A 5 1 2 } ] \ n "
" A c t u a l h a s h : [ $ { F I L E _ H A S H } ] \ n "
2016-09-25 06:36:50 +08:00
" $ { C U S T O M _ E R R O R _ A D V I C E } \ n " )
2016-09-19 11:50:08 +08:00
endif ( )
2016-09-25 06:36:50 +08:00
message ( STATUS "Testing integrity of ${FILE_KIND}... OK" )
endfunction ( )
if ( EXISTS ${ downloaded_file_path } )
message ( STATUS "Using cached ${downloaded_file_path}" )
2018-01-06 08:16:08 +08:00
test_hash ( "cached file" "Please delete the file and retry if this file should be downloaded again." )
2016-09-19 11:50:08 +08:00
else ( )
2017-05-03 11:34:11 +08:00
if ( _VCPKG_NO_DOWNLOADS )
message ( FATAL_ERROR "Downloads are disabled, but '${downloaded_file_path}' does not exist." )
endif ( )
2016-09-24 21:23:18 +08:00
# Tries to download the file.
2016-09-25 06:23:04 +08:00
foreach ( url IN LISTS vcpkg_download_distfile_URLS )
2016-09-24 21:23:18 +08:00
message ( STATUS "Downloading ${url}..." )
2017-11-03 10:08:53 +08:00
file ( DOWNLOAD ${ url } "${download_file_path_part}" STATUS download_status )
2016-09-24 21:23:18 +08:00
list ( GET download_status 0 status_code )
if ( NOT "${status_code}" STREQUAL "0" )
2016-09-25 06:25:40 +08:00
message ( STATUS "Downloading ${url}... Failed. Status: ${download_status}" )
2016-09-24 21:23:18 +08:00
set ( download_success 0 )
else ( )
2018-02-22 08:45:24 +08:00
get_filename_component ( downloaded_file_dir "${downloaded_file_path}" DIRECTORY )
file ( MAKE_DIRECTORY "${downloaded_file_dir}" )
2017-11-03 09:54:10 +08:00
file ( RENAME ${ download_file_path_part } ${ downloaded_file_path } )
2016-09-24 21:23:18 +08:00
message ( STATUS "Downloading ${url}... OK" )
set ( download_success 1 )
break ( )
endif ( )
endforeach ( url )
2017-10-12 23:22:50 +08:00
if ( NOT download_success )
2016-09-24 21:23:18 +08:00
message ( FATAL_ERROR
" \ n "
" F a i l e d t o d o w n l o a d f i l e . \ n "
2016-09-25 06:26:05 +08:00
" A d d m i r r o r s o r s u b m i t a n i s s u e a t h t t p s : / / g i t h u b . c o m / M i c r o s o f t / v c p k g / i s s u e s \ n " )
2016-09-24 21:23:18 +08:00
else ( )
2018-01-06 08:16:08 +08:00
test_hash ( "downloaded file" "The file may have been corrupted in transit." )
2016-09-24 21:23:18 +08:00
endif ( )
2016-09-19 11:50:08 +08:00
endif ( )
2016-09-24 21:23:18 +08:00
set ( ${ VAR } ${ downloaded_file_path } PARENT_SCOPE )
2016-09-19 11:50:08 +08:00
endfunction ( )