This commit is contained in:
kleuter
2023-11-01 22:26:17 +01:00
parent 94b1c5907b
commit 860ee1cc77
3387 changed files with 257471 additions and 0 deletions

View File

@ -0,0 +1,6 @@
# This is a generated file and its contents are an internal implementation detail.
# The update step will be re-executed if anything in this file changes.
# No other meaning or use of this file is supported.
command=@cmd@
work_dir=@work_dir@

View File

@ -0,0 +1,9 @@
# This is a generated file and its contents are an internal implementation detail.
# The download step will be re-executed if anything in this file changes.
# No other meaning or use of this file is supported.
method=@method@
command=@cmd@
source_dir=@source_dir@
work_dir=@work_dir@
@extra_repo_info@

View File

@ -0,0 +1,7 @@
# This is a generated file and its contents are an internal implementation detail.
# The patch step will be re-executed if anything in this file changes.
# No other meaning or use of this file is supported.
command (connected)=@cmd@
command (disconnected)=@cmd_disconnected@
work_dir=@work_dir@

View File

@ -0,0 +1 @@
cmd='@cmd@'

View File

@ -0,0 +1,173 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION 3.5)
function(check_file_hash has_hash hash_is_good)
if("${has_hash}" STREQUAL "")
message(FATAL_ERROR "has_hash Can't be empty")
endif()
if("${hash_is_good}" STREQUAL "")
message(FATAL_ERROR "hash_is_good Can't be empty")
endif()
if("@ALGO@" STREQUAL "")
# No check
set("${has_hash}" FALSE PARENT_SCOPE)
set("${hash_is_good}" FALSE PARENT_SCOPE)
return()
endif()
set("${has_hash}" TRUE PARENT_SCOPE)
message(STATUS "verifying file...
file='@LOCAL@'")
file("@ALGO@" "@LOCAL@" actual_value)
if(NOT "${actual_value}" STREQUAL "@EXPECT_VALUE@")
set("${hash_is_good}" FALSE PARENT_SCOPE)
message(STATUS "@ALGO@ hash of
@LOCAL@
does not match expected value
expected: '@EXPECT_VALUE@'
actual: '${actual_value}'")
else()
set("${hash_is_good}" TRUE PARENT_SCOPE)
endif()
endfunction()
function(sleep_before_download attempt)
if(attempt EQUAL 0)
return()
endif()
if(attempt EQUAL 1)
message(STATUS "Retrying...")
return()
endif()
set(sleep_seconds 0)
if(attempt EQUAL 2)
set(sleep_seconds 5)
elseif(attempt EQUAL 3)
set(sleep_seconds 5)
elseif(attempt EQUAL 4)
set(sleep_seconds 15)
elseif(attempt EQUAL 5)
set(sleep_seconds 60)
elseif(attempt EQUAL 6)
set(sleep_seconds 90)
elseif(attempt EQUAL 7)
set(sleep_seconds 300)
else()
set(sleep_seconds 1200)
endif()
message(STATUS "Retry after ${sleep_seconds} seconds (attempt #${attempt}) ...")
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep "${sleep_seconds}")
endfunction()
if("@LOCAL@" STREQUAL "")
message(FATAL_ERROR "LOCAL can't be empty")
endif()
if("@REMOTE@" STREQUAL "")
message(FATAL_ERROR "REMOTE can't be empty")
endif()
if(EXISTS "@LOCAL@")
check_file_hash(has_hash hash_is_good)
if(has_hash)
if(hash_is_good)
message(STATUS "File already exists and hash match (skip download):
file='@LOCAL@'
@ALGO@='@EXPECT_VALUE@'"
)
return()
else()
message(STATUS "File already exists but hash mismatch. Removing...")
file(REMOVE "@LOCAL@")
endif()
else()
message(STATUS "File already exists but no hash specified (use URL_HASH):
file='@LOCAL@'
Old file will be removed and new file downloaded from URL."
)
file(REMOVE "@LOCAL@")
endif()
endif()
set(retry_number 5)
message(STATUS "Downloading...
dst='@LOCAL@'
timeout='@TIMEOUT_MSG@'
inactivity timeout='@INACTIVITY_TIMEOUT_MSG@'"
)
set(download_retry_codes 7 6 8 15 28)
set(skip_url_list)
set(status_code)
foreach(i RANGE ${retry_number})
if(status_code IN_LIST download_retry_codes)
sleep_before_download(${i})
endif()
foreach(url @REMOTE@)
if(NOT url IN_LIST skip_url_list)
message(STATUS "Using src='${url}'")
@TLS_VERIFY_CODE@
@TLS_CAINFO_CODE@
@NETRC_CODE@
@NETRC_FILE_CODE@
file(
DOWNLOAD
"${url}" "@LOCAL@"
@SHOW_PROGRESS@
@TIMEOUT_ARGS@
@INACTIVITY_TIMEOUT_ARGS@
STATUS status
LOG log
@USERPWD_ARGS@
@HTTP_HEADERS_ARGS@
)
list(GET status 0 status_code)
list(GET status 1 status_string)
if(status_code EQUAL 0)
check_file_hash(has_hash hash_is_good)
if(has_hash AND NOT hash_is_good)
message(STATUS "Hash mismatch, removing...")
file(REMOVE "@LOCAL@")
else()
message(STATUS "Downloading... done")
return()
endif()
else()
string(APPEND logFailedURLs "error: downloading '${url}' failed
status_code: ${status_code}
status_string: ${status_string}
log:
--- LOG BEGIN ---
${log}
--- LOG END ---
"
)
if(NOT status_code IN_LIST download_retry_codes)
list(APPEND skip_url_list "${url}")
break()
endif()
endif()
endif()
endforeach()
endforeach()
message(FATAL_ERROR "Each download failed!
${logFailedURLs}
"
)

View File

@ -0,0 +1,65 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION 3.5)
# Make file names absolute:
#
get_filename_component(filename "@filename@" ABSOLUTE)
get_filename_component(directory "@directory@" ABSOLUTE)
message(STATUS "extracting...
src='${filename}'
dst='${directory}'"
)
if(NOT EXISTS "${filename}")
message(FATAL_ERROR "File to extract does not exist: '${filename}'")
endif()
# Prepare a space for extracting:
#
set(i 1234)
while(EXISTS "${directory}/../ex-@name@${i}")
math(EXPR i "${i} + 1")
endwhile()
set(ut_dir "${directory}/../ex-@name@${i}")
file(MAKE_DIRECTORY "${ut_dir}")
# Extract it:
#
message(STATUS "extracting... [tar @args@]")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar @args@ ${filename} @options@
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 "Extract of '${filename}' failed")
endif()
# Analyze what came out of the tar file:
#
message(STATUS "extracting... [analysis]")
file(GLOB contents "${ut_dir}/*")
list(REMOVE_ITEM contents "${ut_dir}/.DS_Store")
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 ${directory})
get_filename_component(contents ${contents} ABSOLUTE)
file(RENAME ${contents} ${directory})
# Clean up:
#
message(STATUS "extracting... [clean up]")
file(REMOVE_RECURSE "${ut_dir}")
message(STATUS "extracting... done")

View File

@ -0,0 +1,73 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION 3.5)
if(EXISTS "@gitclone_stampfile@" AND EXISTS "@gitclone_infofile@" AND
"@gitclone_stampfile@" IS_NEWER_THAN "@gitclone_infofile@")
message(STATUS
"Avoiding repeated git clone, stamp file is up to date: "
"'@gitclone_stampfile@'"
)
return()
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -E rm -rf "@source_dir@"
RESULT_VARIABLE error_code
)
if(error_code)
message(FATAL_ERROR "Failed to remove directory: '@source_dir@'")
endif()
# try the clone 3 times in case there is an odd git clone issue
set(error_code 1)
set(number_of_tries 0)
while(error_code AND number_of_tries LESS 3)
execute_process(
COMMAND "@git_EXECUTABLE@"
clone @git_clone_options@ "@git_repository@" "@src_name@"
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
)
math(EXPR number_of_tries "${number_of_tries} + 1")
endwhile()
if(number_of_tries GREATER 1)
message(STATUS "Had to git clone more than once: ${number_of_tries} times.")
endif()
if(error_code)
message(FATAL_ERROR "Failed to clone repository: '@git_repository@'")
endif()
execute_process(
COMMAND "@git_EXECUTABLE@"
checkout "@git_tag@" @git_checkout_explicit--@
WORKING_DIRECTORY "@work_dir@/@src_name@"
RESULT_VARIABLE error_code
)
if(error_code)
message(FATAL_ERROR "Failed to checkout tag: '@git_tag@'")
endif()
set(init_submodules @init_submodules@)
if(init_submodules)
execute_process(
COMMAND "@git_EXECUTABLE@" @git_submodules_config_options@
submodule update @git_submodules_recurse@ --init @git_submodules@
WORKING_DIRECTORY "@work_dir@/@src_name@"
RESULT_VARIABLE error_code
)
endif()
if(error_code)
message(FATAL_ERROR "Failed to update submodules in: '@work_dir@/@src_name@'")
endif()
# Complete success, update the script-last-run stamp file:
#
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "@gitclone_infofile@" "@gitclone_stampfile@"
RESULT_VARIABLE error_code
)
if(error_code)
message(FATAL_ERROR "Failed to copy script-last-run stamp file: '@gitclone_stampfile@'")
endif()

View File

@ -0,0 +1,292 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION 3.5)
function(do_fetch)
message(VERBOSE "Fetching latest from the remote @git_remote_name@")
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git fetch --tags --force "@git_remote_name@"
WORKING_DIRECTORY "@work_dir@"
COMMAND_ERROR_IS_FATAL LAST
)
endfunction()
function(get_hash_for_ref ref out_var err_var)
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git rev-parse "${ref}^0"
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
OUTPUT_VARIABLE ref_hash
ERROR_VARIABLE error_msg
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(error_code)
set(${out_var} "" PARENT_SCOPE)
else()
set(${out_var} "${ref_hash}" PARENT_SCOPE)
endif()
set(${err_var} "${error_msg}" PARENT_SCOPE)
endfunction()
get_hash_for_ref(HEAD head_sha error_msg)
if(head_sha STREQUAL "")
message(FATAL_ERROR "Failed to get the hash for HEAD:\n${error_msg}")
endif()
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git show-ref "@git_tag@"
WORKING_DIRECTORY "@work_dir@"
OUTPUT_VARIABLE show_ref_output
)
if(show_ref_output MATCHES "^[a-z0-9]+[ \\t]+refs/remotes/")
# Given a full remote/branch-name and we know about it already. Since
# branches can move around, we should always fetch, if permitted.
if(can_fetch)
do_fetch()
endif()
set(checkout_name "@git_tag@")
elseif(show_ref_output MATCHES "^[a-z0-9]+[ \\t]+refs/tags/")
# Given a tag name that we already know about. We don't know if the tag we
# have matches the remote though (tags can move), so we should fetch. As a
# special case to preserve backward compatibility, if we are already at the
# same commit as the tag we hold locally, don't do a fetch and assume the tag
# hasn't moved on the remote.
# FIXME: We should provide an option to always fetch for this case
get_hash_for_ref("@git_tag@" tag_sha error_msg)
if(tag_sha STREQUAL head_sha)
message(VERBOSE "Already at requested tag: ${tag_sha}")
return()
endif()
if(can_fetch)
do_fetch()
endif()
set(checkout_name "@git_tag@")
elseif(show_ref_output MATCHES "^[a-z0-9]+[ \\t]+refs/heads/")
# Given a branch name without any remote and we already have a branch by that
# name. We might already have that branch checked out or it might be a
# different branch. It isn't fully safe to use a bare branch name without the
# remote, so do a fetch (if allowed) and replace the ref with one that
# includes the remote.
if(can_fetch)
do_fetch()
endif()
set(checkout_name "@git_remote_name@/@git_tag@")
else()
get_hash_for_ref("@git_tag@" tag_sha error_msg)
if(tag_sha STREQUAL head_sha)
# Have the right commit checked out already
message(VERBOSE "Already at requested ref: ${tag_sha}")
return()
elseif(tag_sha STREQUAL "")
# We don't know about this ref yet, so we have no choice but to fetch.
if(NOT can_fetch)
message(FATAL_ERROR
"Requested git ref \"@git_tag@\" is not present locally, and not "
"allowed to contact remote due to UPDATE_DISCONNECTED setting."
)
endif()
# We deliberately swallow any error message at the default log level
# because it can be confusing for users to see a failed git command.
# That failure is being handled here, so it isn't an error.
if(NOT error_msg STREQUAL "")
message(VERBOSE "${error_msg}")
endif()
do_fetch()
set(checkout_name "@git_tag@")
else()
# We have the commit, so we know we were asked to find a commit hash
# (otherwise it would have been handled further above), but we don't
# have that commit checked out yet. We don't need to fetch from the remote.
set(checkout_name "@git_tag@")
if(NOT error_msg STREQUAL "")
message(WARNING "${error_msg}")
endif()
endif()
endif()
set(git_update_strategy "@git_update_strategy@")
if(git_update_strategy STREQUAL "")
# Backward compatibility requires REBASE as the default behavior
set(git_update_strategy REBASE)
endif()
if(git_update_strategy MATCHES "^REBASE(_CHECKOUT)?$")
# Asked to potentially try to rebase first, maybe with fallback to checkout.
# We can't if we aren't already on a branch and we shouldn't if that local
# branch isn't tracking the one we want to checkout.
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git symbolic-ref -q HEAD
WORKING_DIRECTORY "@work_dir@"
OUTPUT_VARIABLE current_branch
OUTPUT_STRIP_TRAILING_WHITESPACE
# Don't test for an error. If this isn't a branch, we get a non-zero error
# code but empty output.
)
if(current_branch STREQUAL "")
# Not on a branch, checkout is the only sensible option since any rebase
# would always fail (and backward compatibility requires us to checkout in
# this situation)
set(git_update_strategy CHECKOUT)
else()
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git for-each-ref "--format=%(upstream:short)" "${current_branch}"
WORKING_DIRECTORY "@work_dir@"
OUTPUT_VARIABLE upstream_branch
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY # There is no error if no upstream is set
)
if(NOT upstream_branch STREQUAL checkout_name)
# Not safe to rebase when asked to checkout a different branch to the one
# we are tracking. If we did rebase, we could end up with arbitrary
# commits added to the ref we were asked to checkout if the current local
# branch happens to be able to rebase onto the target branch. There would
# be no error message and the user wouldn't know this was occurring.
set(git_update_strategy CHECKOUT)
endif()
endif()
elseif(NOT git_update_strategy STREQUAL "CHECKOUT")
message(FATAL_ERROR "Unsupported git update strategy: ${git_update_strategy}")
endif()
# Check if stash is needed
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git status --porcelain
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
OUTPUT_VARIABLE repo_status
)
if(error_code)
message(FATAL_ERROR "Failed to get the status")
endif()
string(LENGTH "${repo_status}" need_stash)
# If not in clean state, stash changes in order to be able to perform a
# rebase or checkout without losing those changes permanently
if(need_stash)
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git stash save @git_stash_save_options@
WORKING_DIRECTORY "@work_dir@"
COMMAND_ERROR_IS_FATAL ANY
)
endif()
if(git_update_strategy STREQUAL "CHECKOUT")
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git checkout "${checkout_name}"
WORKING_DIRECTORY "@work_dir@"
COMMAND_ERROR_IS_FATAL ANY
)
else()
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git rebase "${checkout_name}"
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
OUTPUT_VARIABLE rebase_output
ERROR_VARIABLE rebase_output
)
if(error_code)
# Rebase failed, undo the rebase attempt before continuing
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git rebase --abort
WORKING_DIRECTORY "@work_dir@"
)
if(NOT git_update_strategy STREQUAL "REBASE_CHECKOUT")
# Not allowed to do a checkout as a fallback, so cannot proceed
if(need_stash)
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git stash pop --index --quiet
WORKING_DIRECTORY "@work_dir@"
)
endif()
message(FATAL_ERROR "\nFailed to rebase in: '@work_dir@'."
"\nOutput from the attempted rebase follows:"
"\n${rebase_output}"
"\n\nYou will have to resolve the conflicts manually")
endif()
# Fall back to checkout. We create an annotated tag so that the user
# can manually inspect the situation and revert if required.
# We can't log the failed rebase output because MSVC sees it and
# intervenes, causing the build to fail even though it completes.
# Write it to a file instead.
string(TIMESTAMP tag_timestamp "%Y%m%dT%H%M%S" UTC)
set(tag_name _cmake_ExternalProject_moved_from_here_${tag_timestamp}Z)
set(error_log_file ${CMAKE_CURRENT_LIST_DIR}/rebase_error_${tag_timestamp}Z.log)
file(WRITE ${error_log_file} "${rebase_output}")
message(WARNING "Rebase failed, output has been saved to ${error_log_file}"
"\nFalling back to checkout, previous commit tagged as ${tag_name}")
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git tag -a
-m "ExternalProject attempting to move from here to ${checkout_name}"
${tag_name}
WORKING_DIRECTORY "@work_dir@"
COMMAND_ERROR_IS_FATAL ANY
)
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git checkout "${checkout_name}"
WORKING_DIRECTORY "@work_dir@"
COMMAND_ERROR_IS_FATAL ANY
)
endif()
endif()
if(need_stash)
# Put back the stashed changes
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git stash pop --index --quiet
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
)
if(error_code)
# Stash pop --index failed: Try again dropping the index
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git reset --hard --quiet
WORKING_DIRECTORY "@work_dir@"
)
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git stash pop --quiet
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
)
if(error_code)
# Stash pop failed: Restore previous state.
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git reset --hard --quiet ${head_sha}
WORKING_DIRECTORY "@work_dir@"
)
execute_process(
COMMAND "@git_EXECUTABLE@" --git-dir=.git stash pop --index --quiet
WORKING_DIRECTORY "@work_dir@"
)
message(FATAL_ERROR "\nFailed to unstash changes in: '@work_dir@'."
"\nYou will have to resolve the conflicts manually")
endif()
endif()
endif()
set(init_submodules "@init_submodules@")
if(init_submodules)
execute_process(
COMMAND "@git_EXECUTABLE@"
--git-dir=.git @git_submodules_config_options@
submodule update @git_submodules_recurse@ --init @git_submodules@
WORKING_DIRECTORY "@work_dir@"
COMMAND_ERROR_IS_FATAL ANY
)
endif()

View File

@ -0,0 +1,49 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION 3.5)
if(EXISTS "@hgclone_stampfile@" AND EXISTS "@hgclone_infofile@" AND
"@hgclone_stampfile@" IS_NEWER_THAN "@hgclone_infofile@")
message(STATUS
"Avoiding repeated hg clone, stamp file is up to date: "
"'@hgclone_stampfile@'"
)
return()
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -E rm -rf "@source_dir@"
RESULT_VARIABLE error_code
)
if(error_code)
message(FATAL_ERROR "Failed to remove directory: '@source_dir@'")
endif()
execute_process(
COMMAND "@hg_EXECUTABLE@" clone -U "@hg_repository@" "@src_name@"
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
)
if(error_code)
message(FATAL_ERROR "Failed to clone repository: '@hg_repository@'")
endif()
execute_process(
COMMAND "@hg_EXECUTABLE@" update @hg_tag@
WORKING_DIRECTORY "@work_dir@/@src_name@"
RESULT_VARIABLE error_code
)
if(error_code)
message(FATAL_ERROR "Failed to checkout tag: '@hg_tag@'")
endif()
# Complete success, update the script-last-run stamp file:
#
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "@hgclone_infofile@" "@hgclone_stampfile@"
RESULT_VARIABLE error_code
)
if(error_code)
message(FATAL_ERROR "Failed to copy script-last-run stamp file: '@hgclone_stampfile@'")
endif()

View File

@ -0,0 +1,22 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION 3.5)
file(MAKE_DIRECTORY
"@source_dir@"
"@binary_dir@"
"@install_dir@"
"@tmp_dir@"
"@stamp_dir@"
"@download_dir@"
"@log_dir@"
)
set(configSubDirs @CMAKE_CONFIGURATION_TYPES@)
foreach(subDir IN LISTS configSubDirs)
file(MAKE_DIRECTORY "@stamp_dir@/${subDir}")
endforeach()
if(cfgdir)
file(MAKE_DIRECTORY "@stamp_dir@${cfgdir}") # cfgdir has leading slash
endif()

View File

@ -0,0 +1,182 @@
cmake_policy(VERSION 3.25)
# Determine the remote URL of the project containing the working_directory.
# This will leave output_variable unset if the URL can't be determined.
function(_ep_get_git_remote_url output_variable working_directory)
set("${output_variable}" "" PARENT_SCOPE)
find_package(Git QUIET REQUIRED)
execute_process(
COMMAND ${GIT_EXECUTABLE} symbolic-ref --short HEAD
WORKING_DIRECTORY "${working_directory}"
OUTPUT_VARIABLE git_symbolic_ref
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(NOT git_symbolic_ref STREQUAL "")
# We are potentially on a branch. See if that branch is associated with
# an upstream remote (might be just a local one or not a branch at all).
execute_process(
COMMAND ${GIT_EXECUTABLE} config branch.${git_symbolic_ref}.remote
WORKING_DIRECTORY "${working_directory}"
OUTPUT_VARIABLE git_remote_name
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
endif()
if(NOT git_remote_name)
# Can't select a remote based on a branch. If there's only one remote,
# or we have multiple remotes but one is called "origin", choose that.
execute_process(
COMMAND ${GIT_EXECUTABLE} remote
WORKING_DIRECTORY "${working_directory}"
OUTPUT_VARIABLE git_remote_list
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
string(REPLACE "\n" ";" git_remote_list "${git_remote_list}")
list(LENGTH git_remote_list git_remote_list_length)
if(git_remote_list_length EQUAL 0)
message(FATAL_ERROR "Git remote not found in parent project.")
elseif(git_remote_list_length EQUAL 1)
list(GET git_remote_list 0 git_remote_name)
else()
set(base_warning_msg "Multiple git remotes found for parent project")
if("origin" IN_LIST git_remote_list)
message(WARNING "${base_warning_msg}, defaulting to origin.")
set(git_remote_name "origin")
else()
message(FATAL_ERROR "${base_warning_msg}, none of which are origin.")
endif()
endif()
endif()
if(GIT_VERSION VERSION_LESS 1.7.5)
set(_git_remote_url_cmd_args config remote.${git_remote_name}.url)
elseif(GIT_VERSION VERSION_LESS 2.7)
set(_git_remote_url_cmd_args ls-remote --get-url ${git_remote_name})
else()
set(_git_remote_url_cmd_args remote get-url ${git_remote_name})
endif()
execute_process(
COMMAND ${GIT_EXECUTABLE} ${_git_remote_url_cmd_args}
WORKING_DIRECTORY "${working_directory}"
OUTPUT_VARIABLE git_remote_url
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL LAST
ENCODING UTF-8 # Needed to handle non-ascii characters in local paths
)
set("${output_variable}" "${git_remote_url}" PARENT_SCOPE)
endfunction()
function(_ep_is_relative_git_remote output_variable remote_url)
if(remote_url MATCHES "^\\.\\./")
set("${output_variable}" TRUE PARENT_SCOPE)
else()
set("${output_variable}" FALSE PARENT_SCOPE)
endif()
endfunction()
# Return an absolute remote URL given an existing remote URL and relative path.
# The output_variable will be set to an empty string if an absolute URL
# could not be computed (no error message is output).
function(_ep_resolve_relative_git_remote
output_variable
parent_remote_url
relative_remote_url
)
set("${output_variable}" "" PARENT_SCOPE)
if(parent_remote_url STREQUAL "")
return()
endif()
string(REGEX MATCH
"^(([A-Za-z0-9][A-Za-z0-9+.-]*)://)?(([^/@]+)@)?(\\[[A-Za-z0-9:]+\\]|[^/:]+)?([/:]/?)(.+(\\.git)?/?)$"
git_remote_url_components
"${parent_remote_url}"
)
set(protocol "${CMAKE_MATCH_1}")
set(auth "${CMAKE_MATCH_3}")
set(host "${CMAKE_MATCH_5}")
set(separator "${CMAKE_MATCH_6}")
set(path "${CMAKE_MATCH_7}")
string(REPLACE "/" ";" remote_path_components "${path}")
string(REPLACE "/" ";" relative_path_components "${relative_remote_url}")
foreach(relative_path_component IN LISTS relative_path_components)
if(NOT relative_path_component STREQUAL "..")
break()
endif()
list(LENGTH remote_path_components remote_path_component_count)
if(remote_path_component_count LESS 1)
return()
endif()
list(POP_BACK remote_path_components)
list(POP_FRONT relative_path_components)
endforeach()
list(APPEND final_path_components ${remote_path_components} ${relative_path_components})
list(JOIN final_path_components "/" path)
set("${output_variable}" "${protocol}${auth}${host}${separator}${path}" PARENT_SCOPE)
endfunction()
# The output_variable will be set to the original git_repository if it
# could not be resolved (no error message is output). The original value is
# also returned if it doesn't need to be resolved.
function(_ep_resolve_git_remote
output_variable
git_repository
cmp0150
cmp0150_old_base_dir
)
if(git_repository STREQUAL "")
set("${output_variable}" "" PARENT_SCOPE)
return()
endif()
_ep_is_relative_git_remote(_git_repository_is_relative "${git_repository}")
if(NOT _git_repository_is_relative)
set("${output_variable}" "${git_repository}" PARENT_SCOPE)
return()
endif()
if(cmp0150 STREQUAL "NEW")
_ep_get_git_remote_url(_parent_git_remote_url "${CMAKE_CURRENT_SOURCE_DIR}")
_ep_resolve_relative_git_remote(_resolved_git_remote_url "${_parent_git_remote_url}" "${git_repository}")
if(_resolved_git_remote_url STREQUAL "")
message(FATAL_ERROR
"Failed to resolve relative git remote URL:\n"
" Relative URL: ${git_repository}\n"
" Parent URL: ${_parent_git_remote_url}"
)
endif()
set("${output_variable}" "${_resolved_git_remote_url}" PARENT_SCOPE)
return()
elseif(cmp0150 STREQUAL "")
cmake_policy(GET_WARNING CMP0150 _cmp0150_warning)
message(AUTHOR_WARNING
"${_cmp0150_warning}\n"
"A relative GIT_REPOSITORY path was detected. "
"This will be interpreted as a local path to where the project is being cloned. "
"Set GIT_REPOSITORY to an absolute path or set policy CMP0150 to NEW to avoid "
"this warning."
)
endif()
set("${output_variable}" "${cmp0150_old_base_dir}/${git_repository}" PARENT_SCOPE)
endfunction()

View File

@ -0,0 +1,37 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION 3.5)
if("@LOCAL@" STREQUAL "")
message(FATAL_ERROR "LOCAL can't be empty")
endif()
if(NOT EXISTS "@LOCAL@")
message(FATAL_ERROR "File not found: @LOCAL@")
endif()
if("@ALGO@" STREQUAL "")
message(WARNING "File will not be verified since no URL_HASH specified")
return()
endif()
if("@EXPECT_VALUE@" STREQUAL "")
message(FATAL_ERROR "EXPECT_VALUE can't be empty")
endif()
message(STATUS "verifying file...
file='@LOCAL@'")
file("@ALGO@" "@LOCAL@" actual_value)
if(NOT "${actual_value}" STREQUAL "@EXPECT_VALUE@")
message(FATAL_ERROR "error: @ALGO@ hash of
@LOCAL@
does not match expected value
expected: '@EXPECT_VALUE@'
actual: '${actual_value}'
")
endif()
message(STATUS "verifying file... done")