GenerateBuildInfo.cmake
1 # Copyright (c) 2023-present The Bitcoin Core developers 2 # Distributed under the MIT software license, see the accompanying 3 # file COPYING or https://opensource.org/license/mit/. 4 5 macro(fatal_error) 6 message(FATAL_ERROR "\n" 7 "Usage:\n" 8 " cmake -D BUILD_INFO_HEADER_PATH=<path> [-D SOURCE_DIR=<path>] -P ${CMAKE_CURRENT_LIST_FILE}\n" 9 "All specified paths must be absolute ones.\n" 10 ) 11 endmacro() 12 13 if(DEFINED BUILD_INFO_HEADER_PATH AND IS_ABSOLUTE "${BUILD_INFO_HEADER_PATH}") 14 if(EXISTS "${BUILD_INFO_HEADER_PATH}") 15 file(STRINGS ${BUILD_INFO_HEADER_PATH} INFO LIMIT_COUNT 1) 16 endif() 17 else() 18 fatal_error() 19 endif() 20 21 if(DEFINED SOURCE_DIR) 22 if(IS_ABSOLUTE "${SOURCE_DIR}" AND IS_DIRECTORY "${SOURCE_DIR}") 23 set(WORKING_DIR ${SOURCE_DIR}) 24 else() 25 fatal_error() 26 endif() 27 else() 28 set(WORKING_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 29 endif() 30 31 set(GIT_TAG) 32 set(GIT_COMMIT) 33 if(NOT "$ENV{BITCOIN_GENBUILD_NO_GIT}" STREQUAL "1") 34 find_package(Git QUIET) 35 if(Git_FOUND) 36 execute_process( 37 COMMAND ${GIT_EXECUTABLE} rev-parse --is-inside-work-tree 38 WORKING_DIRECTORY ${WORKING_DIR} 39 OUTPUT_VARIABLE IS_INSIDE_WORK_TREE 40 OUTPUT_STRIP_TRAILING_WHITESPACE 41 ERROR_QUIET 42 ) 43 if(IS_INSIDE_WORK_TREE) 44 # Clean 'dirty' status of touched files that haven't been modified. 45 execute_process( 46 COMMAND ${GIT_EXECUTABLE} diff 47 WORKING_DIRECTORY ${WORKING_DIR} 48 OUTPUT_QUIET 49 ERROR_QUIET 50 ) 51 52 execute_process( 53 COMMAND ${GIT_EXECUTABLE} describe --abbrev=0 54 WORKING_DIRECTORY ${WORKING_DIR} 55 OUTPUT_VARIABLE MOST_RECENT_TAG 56 OUTPUT_STRIP_TRAILING_WHITESPACE 57 ERROR_QUIET 58 ) 59 60 execute_process( 61 COMMAND ${GIT_EXECUTABLE} rev-list -1 ${MOST_RECENT_TAG} 62 WORKING_DIRECTORY ${WORKING_DIR} 63 OUTPUT_VARIABLE MOST_RECENT_TAG_COMMIT 64 OUTPUT_STRIP_TRAILING_WHITESPACE 65 ERROR_QUIET 66 ) 67 68 execute_process( 69 COMMAND ${GIT_EXECUTABLE} rev-parse HEAD 70 WORKING_DIRECTORY ${WORKING_DIR} 71 OUTPUT_VARIABLE HEAD_COMMIT 72 OUTPUT_STRIP_TRAILING_WHITESPACE 73 ERROR_QUIET 74 ) 75 76 execute_process( 77 COMMAND ${GIT_EXECUTABLE} diff-index --quiet HEAD -- 78 WORKING_DIRECTORY ${WORKING_DIR} 79 RESULT_VARIABLE IS_DIRTY 80 ) 81 82 if(HEAD_COMMIT STREQUAL MOST_RECENT_TAG_COMMIT AND NOT IS_DIRTY) 83 # If latest commit is tagged and not dirty, then use the tag name. 84 set(GIT_TAG ${MOST_RECENT_TAG}) 85 else() 86 # Otherwise, generate suffix from git, i.e. string like "0e0a5173fae3-dirty". 87 execute_process( 88 COMMAND ${GIT_EXECUTABLE} rev-parse --short=12 HEAD 89 WORKING_DIRECTORY ${WORKING_DIR} 90 OUTPUT_VARIABLE GIT_COMMIT 91 OUTPUT_STRIP_TRAILING_WHITESPACE 92 ERROR_QUIET 93 ) 94 if(IS_DIRTY) 95 string(APPEND GIT_COMMIT "-dirty") 96 endif() 97 endif() 98 endif() 99 endif() 100 endif() 101 102 if(GIT_TAG) 103 set(NEWINFO "#define BUILD_GIT_TAG \"${GIT_TAG}\"") 104 elseif(GIT_COMMIT) 105 set(NEWINFO "#define BUILD_GIT_COMMIT \"${GIT_COMMIT}\"") 106 else() 107 set(NEWINFO "// No build information available") 108 endif() 109 110 # Only update the header if necessary. 111 if(NOT "${INFO}" STREQUAL "${NEWINFO}") 112 file(WRITE ${BUILD_INFO_HEADER_PATH} "${NEWINFO}\n") 113 endif()