diff --git a/.gitattributes b/.gitattributes index c9cf4a7d9cd..25303e742a7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ src/clientversion.cpp export-subst +src/CMakeLists.txt export-subst diff --git a/cmake/script/GenerateBuildInfo.cmake b/cmake/script/GenerateBuildInfo.cmake index d3ee2eb0621..62773a3a543 100644 --- a/cmake/script/GenerateBuildInfo.cmake +++ b/cmake/script/GenerateBuildInfo.cmake @@ -5,7 +5,7 @@ macro(fatal_error) message(FATAL_ERROR "\n" "Usage:\n" - " cmake -D BUILD_INFO_HEADER_PATH= [-D SOURCE_DIR=] -P ${CMAKE_CURRENT_LIST_FILE}\n" + " cmake -D BUILD_INFO_HEADER_PATH= -D GIT_EXECUTABLE= [-D SOURCE_DIR=] -P ${CMAKE_CURRENT_LIST_FILE}\n" "All specified paths must be absolute ones.\n" ) endmacro() @@ -28,72 +28,69 @@ else() set(WORKING_DIR ${CMAKE_CURRENT_SOURCE_DIR}) endif() -set(GIT_TAG) -set(GIT_COMMIT) -if(NOT "$ENV{BITCOIN_GENBUILD_NO_GIT}" STREQUAL "1") - find_package(Git QUIET) - if(Git_FOUND) +set(GIT_TAG "") +set(GIT_COMMIT "") +if(GIT_EXECUTABLE) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --is-inside-work-tree + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE IS_INSIDE_WORK_TREE + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if(IS_INSIDE_WORK_TREE) + # Clean 'dirty' status of touched files that haven't been modified. execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --is-inside-work-tree + COMMAND ${GIT_EXECUTABLE} diff WORKING_DIRECTORY ${WORKING_DIR} - OUTPUT_VARIABLE IS_INSIDE_WORK_TREE + OUTPUT_QUIET + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --abbrev=0 + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE MOST_RECENT_TAG OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) - if(IS_INSIDE_WORK_TREE) - # Clean 'dirty' status of touched files that haven't been modified. - execute_process( - COMMAND ${GIT_EXECUTABLE} diff - WORKING_DIRECTORY ${WORKING_DIR} - OUTPUT_QUIET - ERROR_QUIET - ) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-list -1 ${MOST_RECENT_TAG} + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE MOST_RECENT_TAG_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE HEAD_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} diff-index --quiet HEAD -- + WORKING_DIRECTORY ${WORKING_DIR} + RESULT_VARIABLE IS_DIRTY + ) + + if(HEAD_COMMIT STREQUAL MOST_RECENT_TAG_COMMIT AND NOT IS_DIRTY) + # If latest commit is tagged and not dirty, then use the tag name. + set(GIT_TAG ${MOST_RECENT_TAG}) + else() + # Otherwise, generate suffix from git, i.e. string like "0e0a5173fae3-dirty". execute_process( - COMMAND ${GIT_EXECUTABLE} describe --abbrev=0 + COMMAND ${GIT_EXECUTABLE} rev-parse --short=12 HEAD WORKING_DIRECTORY ${WORKING_DIR} - OUTPUT_VARIABLE MOST_RECENT_TAG + OUTPUT_VARIABLE GIT_COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) - - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-list -1 ${MOST_RECENT_TAG} - WORKING_DIRECTORY ${WORKING_DIR} - OUTPUT_VARIABLE MOST_RECENT_TAG_COMMIT - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse HEAD - WORKING_DIRECTORY ${WORKING_DIR} - OUTPUT_VARIABLE HEAD_COMMIT - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - - execute_process( - COMMAND ${GIT_EXECUTABLE} diff-index --quiet HEAD -- - WORKING_DIRECTORY ${WORKING_DIR} - RESULT_VARIABLE IS_DIRTY - ) - - if(HEAD_COMMIT STREQUAL MOST_RECENT_TAG_COMMIT AND NOT IS_DIRTY) - # If latest commit is tagged and not dirty, then use the tag name. - set(GIT_TAG ${MOST_RECENT_TAG}) - else() - # Otherwise, generate suffix from git, i.e. string like "0e0a5173fae3-dirty". - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --short=12 HEAD - WORKING_DIRECTORY ${WORKING_DIR} - OUTPUT_VARIABLE GIT_COMMIT - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - if(IS_DIRTY) - string(APPEND GIT_COMMIT "-dirty") - endif() + if(IS_DIRTY) + string(APPEND GIT_COMMIT "-dirty") endif() endif() endif() diff --git a/doc/release-notes-32220.md b/doc/release-notes-32220.md new file mode 100644 index 00000000000..c2527157155 --- /dev/null +++ b/doc/release-notes-32220.md @@ -0,0 +1,9 @@ +### Build System + +- The undocumented `BITCOIN_GENBUILD_NO_GIT` environment variable is no longer + required and has been removed. The build system now automatically detects + when it is being built from a source archive or as a subproject of a git-aware + parent project and skips git metadata fetching. + + Users who need to disable git execution explicitly can still do so by + configuring with `-DCMAKE_DISABLE_FIND_PACKAGE_Git=ON`. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b37f3c8ca5c..439239962ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,9 +37,15 @@ if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) endif() +set(IS_SOURCE_TARBALL FALSE) +# git will expand the next line to "set(IS_SOURCE_TARBALL TRUE)" inside archives: +#$Format:%nset(IS_SOURCE_TARBALL TRUE)$ +if(NOT IS_SOURCE_TARBALL AND PROJECT_IS_TOP_LEVEL) + find_package(Git QUIET) +endif() add_custom_target(generate_build_info BYPRODUCTS ${PROJECT_BINARY_DIR}/src/bitcoin-build-info.h - COMMAND ${CMAKE_COMMAND} -DBUILD_INFO_HEADER_PATH=${PROJECT_BINARY_DIR}/src/bitcoin-build-info.h -DSOURCE_DIR=${PROJECT_SOURCE_DIR} -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateBuildInfo.cmake + COMMAND ${CMAKE_COMMAND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DBUILD_INFO_HEADER_PATH=${PROJECT_BINARY_DIR}/src/bitcoin-build-info.h -DSOURCE_DIR=${PROJECT_SOURCE_DIR} -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateBuildInfo.cmake COMMENT "Generating bitcoin-build-info.h" VERBATIM )