git_version.cmake
1 # Inspired by https://www.mattkeeter.com/blog/2018-01-06-versioning/ 2 3 # 4 # Include version.h in your code to use the auto-generated variables 5 # Make sure to update version.h if you ever add new ones! 6 # 7 8 set(GIT_CMD git) 9 set(GIT_ARGS_SHA describe --match ForceNone --abbrev=8 --always) 10 execute_process(COMMAND ${GIT_CMD} ${GIT_ARGS_SHA} 11 OUTPUT_VARIABLE GIT_SHA 12 OUTPUT_STRIP_TRAILING_WHITESPACE) 13 14 # Figure out if there are uncommitted/unstaged changes to git repo 15 # See https://stackoverflow.com/a/2659808 for more info 16 execute_process(COMMAND ${GIT_CMD} diff-index --quiet HEAD -- RESULT_VARIABLE IS_DIRTY) 17 if(IS_DIRTY) 18 set(DIRTY_STR "1") 19 else() 20 set(DIRTY_STR "0") 21 endif() 22 23 # if VERSION_STR wasn't passed as an argument, get it from git 24 if(NOT VERSION_STR) 25 set(GIT_ARGS_TAG describe --always --dirty --abbrev=8) 26 27 execute_process(COMMAND ${GIT_CMD} ${GIT_ARGS_TAG} 28 OUTPUT_VARIABLE VERSION_STR 29 OUTPUT_STRIP_TRAILING_WHITESPACE) 30 endif() 31 32 # Convert GIT_SHA from hex to decimal 33 math(EXPR GIT_SHA_DEC "0x${GIT_SHA}" OUTPUT_FORMAT DECIMAL) 34 35 set(NOTE_FW_STR "\n#ifdef HAS_NOTECARD\nconst char *NOTE_FW_STR = \"firmware::info:{") 36 set(NOTE_FW_STR "${NOTE_FW_STR}\\\"product\\\":\\\"Sunflower\\\",") 37 set(NOTE_FW_STR "${NOTE_FW_STR}\\\"firmware\\\":\\\"${VERSION_STR}\\\",") 38 39 # Default to eng build unless RELEASE=1 is passed in 40 if(RELEASE STREQUAL "1") 41 set(ENG_STR "0") 42 else () 43 set(ENG_STR "1") 44 endif() 45 46 if (VERSION_STR MATCHES "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)$") 47 # Extract version info from git tag 48 # Expects format vx.y.z with optional extra stuff in the end 49 set(MAJ_STR "${CMAKE_MATCH_1}") 50 set(MIN_STR "${CMAKE_MATCH_2}") 51 set(REV_STR "${CMAKE_MATCH_3}") 52 53 set(NOTE_FW_STR "${NOTE_FW_STR}\\\"ver_major\\\":${CMAKE_MATCH_1},") 54 set(NOTE_FW_STR "${NOTE_FW_STR}\\\"ver_minor\\\":${CMAKE_MATCH_2},") 55 set(NOTE_FW_STR "${NOTE_FW_STR}\\\"ver_patch\\\":${CMAKE_MATCH_3},") 56 57 set(MCUBOOT_VERSION_STR "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}+${GIT_SHA_DEC}") 58 59 # Don't allow invalid version strings when doing releases 60 # ENG- releases can have whatever 61 if(CMAKE_MATCH_4 AND RELEASE STREQUAL "1") 62 message(ERROR "Release versions MUST follow format: vx.x.x") 63 endif() 64 65 else() 66 message(WARNING "invalid version string!") 67 68 set(NOTE_FW_STR "${NOTE_FW_STR}\\\"ver_major\\\":0,") 69 set(NOTE_FW_STR "${NOTE_FW_STR}\\\"ver_minor\\\":0,") 70 set(NOTE_FW_STR "${NOTE_FW_STR}\\\"ver_patch\\\":0,") 71 72 set(MAJ_STR "0xFF") 73 set(MIN_STR "0xFF") 74 set(REV_STR "0xFF") 75 set(MCUBOOT_VERSION_STR "0.0.0+${GIT_SHA_DEC}") 76 endif() 77 78 # Safety checks 79 if(DIRTY_STR STREQUAL "1" AND RELEASE STREQUAL 1) 80 message( SEND_ERROR "Cannot have a release build with a dirty git repo!" ) 81 endif() 82 83 # Last item doesn't have a comma!!! 84 set(NOTE_FW_STR "${NOTE_FW_STR}\\\"ver_build\\\":${GIT_SHA_DEC}") 85 set(NOTE_FW_STR "${NOTE_FW_STR}}\";\n#endif\n") 86 87 # 88 # These arguments are passed as command line defines -DXYZ by caller 89 # 90 if(APP STREQUAL "bootloader") 91 set(IS_BOOTLOADER_STR "1") 92 else() 93 set(IS_BOOTLOADER_STR "0") 94 endif() 95 96 if(SIGN_IMAGES STREQUAL 1) 97 set(SIGN_IMAGES_STR "1") 98 else() 99 set(SIGN_IMAGES_STR "0") 100 endif() 101 102 if(ENCRYPT_IMAGES STREQUAL 1) 103 set(ENCRYPT_IMAGES_STR "1") 104 else() 105 set(ENCRYPT_IMAGES_STR "0") 106 endif() 107 108 string(LENGTH ${VERSION_STR} VERSION_STR_LEN) 109 110 string(CONCAT VERSION 111 "#include <stdbool.h>\n" 112 "#include <stdint.h>\n" 113 "#include \"version.h\"\n" 114 "\n" 115 "__attribute__ ((section(\".note.sofar.version\")))\n" 116 "const versionNote_t versionNote = {\n" 117 " .note = {\n" 118 " .namesz=sizeof(((versionNote_t *)0)->name),\n" 119 " .descsz=sizeof(versionInfo_t),\n" 120 " .type=0x10, // Arbitrarily large value so binutis won't get confused\n" 121 " },\n" 122 " .name=\"VERSION\",\n" 123 " .info = {\n" 124 " .magic = VERSION_MAGIC,\n" 125 " .gitSHA = 0x${GIT_SHA},\n" 126 " .maj = ${MAJ_STR},\n" 127 " .min = ${MIN_STR},\n" 128 " .rev = ${REV_STR},\n" 129 " .hwVersion = ${HW_VERSION},\n" 130 " .flags = (\n" 131 " (${ENG_STR} << VER_ENG_FLAG_OFFSET) |\n" 132 " (${DIRTY_STR} << VER_DIRTY_FLAG_OFFSET) |\n" 133 " (${IS_BOOTLOADER_STR} << VER_IS_BOOTLOADER_OFFSET) |\n" 134 " (${SIGN_IMAGES_STR} << VER_SIGNATURE_SUPPORT_OFFSET) |\n" 135 " (${ENCRYPT_IMAGES_STR} << VER_ENCRYPTION_SUPPORT_OFFSET)\n" 136 " ),\n" 137 " .versionStrLen = ${VERSION_STR_LEN},\n" 138 " .versionStr = \"${VERSION_STR}\",\n" 139 " },\n" 140 "};\n" 141 "${NOTE_FW_STR}\n" 142 ) 143 144 145 if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/version.c) 146 file(READ ${CMAKE_CURRENT_SOURCE_DIR}/version.c VERSION_) 147 else() 148 set(VERSION_ "") 149 endif() 150 151 if (NOT "${VERSION}" STREQUAL "${VERSION_}") 152 file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/version.c "${VERSION}") 153 endif() 154 155 if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/version_string) 156 file(READ ${CMAKE_CURRENT_SOURCE_DIR}/version_string MCUBOOT_VERSION_STR_) 157 else() 158 set(MCUBOOT_VERSION_STR_ "") 159 endif() 160 161 if (NOT "${MCUBOOT_VERSION_STR}" STREQUAL "${MCUBOOT_VERSION_STR_}") 162 file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/version_string "${MCUBOOT_VERSION_STR}") 163 endif() 164 165 message(STATUS "git version: ${VERSION_STR}")