diff options
author | Joel Rosdahl <joel@rosdahl.net> | 2020-09-30 17:13:48 +0200 |
---|---|---|
committer | Joel Rosdahl <joel@rosdahl.net> | 2020-10-01 09:45:54 +0200 |
commit | 3c33c79548874e97a3553bf6943c89638326e6f2 (patch) | |
tree | 102a40c595039db713dfc045cf49d977e761913e /cmake | |
parent | 2bcea18451b3f2d1114435f4b42cc42afde5aaa8 (diff) | |
download | ccache-3c33c79548874e97a3553bf6943c89638326e6f2.tar.gz |
Make it possible to build from “git archive” source archives
The ccache CMake scripts currently support building from an official
release archive or in a Git repository but not from a source archive
created by “git archive”.
Improve this by adding directives so that “git archive” substitutes
needed information when exporting the source tree.
Closes #667.
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/.gitattributes | 1 | ||||
-rw-r--r-- | cmake/CcacheVersion.cmake | 66 | ||||
-rw-r--r-- | cmake/GenerateVersionFile.cmake | 54 |
3 files changed, 68 insertions, 53 deletions
diff --git a/cmake/.gitattributes b/cmake/.gitattributes new file mode 100644 index 00000000..c217b7df --- /dev/null +++ b/cmake/.gitattributes @@ -0,0 +1 @@ +CcacheVersion.cmake export-subst diff --git a/cmake/CcacheVersion.cmake b/cmake/CcacheVersion.cmake new file mode 100644 index 00000000..ee338168 --- /dev/null +++ b/cmake/CcacheVersion.cmake @@ -0,0 +1,66 @@ +# There are four main scenarios: +# +# 1. Building from an official source code release archive. In this case the +# version is unconditionally read from the file VERSION in the top level +# directory and the code below won't be executed. +# 2. Building from an unofficial source code archive generated by "git +# archive", e.g. from a GitHub "archive download" +# (https://github.com/ccache/ccache/archive/$VERSION.tar.gz). In this case +# the version_info info string below will be substituted because of +# export-subst in the .gitattributes file. The version will then be correct +# if $VERSION refers to a tagged commit. If the commit is not tagged the +# version will be set to the commit hash instead. +# 3. Building from an unofficial source code archive not generated by "git +# archive" (i.e., version_info has not been substituted). In this case we +# fail the configuration. +# 4. Building from a Git repository. In this case the version will be a proper +# version if building a tagged commit, otherwise "branch.hash(+dirty)". + +set(version_info "$Format:%H %D$") + +if(version_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])[0-9a-f]* (.*)") + # Scenario 2. + set(hash "${CMAKE_MATCH_1}") + set(ref_names "${CMAKE_MATCH_2}") + if(ref_names MATCHES "tag: v([^,]+)") + # Tagged commit. + set(VERSION "${CMAKE_MATCH_1}") + else() + # Untagged commit. + set(VERSION "${hash}") + endif() +elseif(EXISTS "${CMAKE_SOURCE_DIR}/.git") + # Scenario 4. + find_package(Git QUIET) + if(NOT GIT_FOUND) + message(SEND_ERROR "Could not find git") + endif() + + macro(git) + execute_process( + COMMAND "${GIT_EXECUTABLE}" ${ARGN} + OUTPUT_VARIABLE git_stdout OUTPUT_STRIP_TRAILING_WHITESPACE) + endmacro() + + git(describe --abbrev=8 --dirty) + if(git_stdout MATCHES "^v([^-]+)(-dirty)?$") + set(VERSION "${CMAKE_MATCH_1}") + if(NOT "${CMAKE_MATCH_2}" STREQUAL "") + set(VERSION "${VERSION}+dirty") + endif() + elseif(git_stdout MATCHES "^v[^-]+-[0-9]+-g([0-9a-f]+)(-dirty)?$") + set(hash "${CMAKE_MATCH_1}") + set(dirty "${CMAKE_MATCH_2}") + string(REPLACE "-" "+" dirty "${dirty}") + + git(rev-parse --abbrev-ref HEAD) + set(branch "${git_stdout}") + + set(VERSION "${branch}.${hash}${dirty}") + endif() # else: fail below +endif() + +if(VERSION STREQUAL "") + # Scenario 3 or unexpected error. + message(SEND_ERROR "Cannot determine Ccache version") +endif() diff --git a/cmake/GenerateVersionFile.cmake b/cmake/GenerateVersionFile.cmake index 37baa9ee..66a86b37 100644 --- a/cmake/GenerateVersionFile.cmake +++ b/cmake/GenerateVersionFile.cmake @@ -1,62 +1,10 @@ -# Determine VERSION from a Git repository. VERSION_ERROR is set to a non-empty -# string on error. -function(get_version_from_git) - set(VERSION_ERROR "" PARENT_SCOPE) - - find_package(Git) - if(NOT GIT_FOUND) - set(VERSION_ERROR "Git not found" PARENT_SCOPE) - return() - endif() - - execute_process( - COMMAND git describe --exact-match - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE git_tag - ERROR_VARIABLE git_tag_error # silence error - RESULT_VARIABLE cmd_result - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if(cmd_result EQUAL 0) - set(VERSION ${git_tag} PARENT_SCOPE) - return() - endif() - - execute_process( - COMMAND git rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE git_branch OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE git_branch_error - RESULT_VARIABLE cmd_branch_result) - if(NOT cmd_branch_result EQUAL 0) - set(VERSION_ERROR "Failed to run Git: ${git_branch_error}" PARENT_SCOPE) - return() - endif() - - execute_process( - COMMAND git rev-parse --short=8 HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE git_hash OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE git_hash_error - RESULT_VARIABLE cmd_hash_result) - if(NOT cmd_hash_result EQUAL 0) - set(VERSION_ERROR "Failed to run Git: ${git_hash_error}" PARENT_SCOPE) - return() - endif() - - set(VERSION "${git_branch}.${git_hash}" PARENT_SCOPE) -endfunction() - set(version_file ${CMAKE_SOURCE_DIR}/VERSION) if(EXISTS ${version_file}) file(READ ${version_file} VERSION) string(STRIP ${VERSION} VERSION) else() - get_version_from_git() - if(NOT ${VERSION_ERROR} STREQUAL "") - message(SEND_ERROR "Cannot determine ccache version: ${VERSION_ERROR}") - endif() + include(CcacheVersion) endif() configure_file( |