# HELPER FUNCTIONS function(get_commit_id) # get last commit hash execute_process( COMMAND ${GIT_EXECUTABLE} log -1 --abbrev=7 --date=short "--pretty=%h" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COM_ID ) if(NOT ${res_var} EQUAL 0) message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.") return() endif() string(REPLACE "\n" "" GIT_COM_ID "${GIT_COM_ID}") set(GIT_COMMIT_ID "${GIT_COM_ID}" PARENT_SCOPE ) set(PROJECT_VERSION_LABEL "custom(${GIT_COM_ID})" PARENT_SCOPE ) endfunction() function(get_commit_date) # get last commit date execute_process( COMMAND ${GIT_EXECUTABLE} log -1 --date=short "--pretty=%cd" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COM_DATE ) if(NOT ${res_var} EQUAL 0) message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.") return() endif() string(REPLACE "\n" "" GIT_COM_DATE "${GIT_COM_DATE}") set(GIT_COMMIT_DATE_FRIENDLY "${GIT_COM_DATE}" PARENT_SCOPE ) string(REPLACE "-" "" GIT_COM_DATE "${GIT_COM_DATE}") set(GIT_COMMIT_DATE "${GIT_COM_DATE}" PARENT_SCOPE ) endfunction() function(get_tag_name commit) if(${commit} STREQUAL "unknown") return() endif() execute_process( COMMAND ${GIT_EXECUTABLE} describe --exact-match --tags ${commit} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_TAG ERROR_VARIABLE GIT_TAG_ERR ) if((NOT ${res_var} EQUAL 0) OR (${GIT_TAG_ERR} MATCHES "fatal: no tag exactly matches.*")) message(STATUS "Commit is not a release or prerelease (no git tag found)") return() endif() string(REPLACE "\n" "" GIT_TAG "${GIT_TAG}") message(STATUS "Commit is a release or prerelease, git tag: ${GIT_TAG}") # Extract information from tag: # YYYY-MM-DD-Release-MAJ.MIN.PATCH # YYYY-MM-DD-Development-MAJ.MIN.PATCH-beta.X string(REPLACE "-" ";" GIT_TAG_EXPLODED "${GIT_TAG}") string(REPLACE "." ";" GIT_TAG_EXPLODED "${GIT_TAG_EXPLODED}") # Sanity checks: length list(LENGTH GIT_TAG_EXPLODED GIT_TAG_LISTCOUNT) if(${GIT_TAG_LISTCOUNT} LESS 7 OR ${GIT_TAG_LISTCOUNT} GREATER 9) message(WARNING "Invalid tag format, got ${GIT_TAG_LISTCOUNT} tokens") return() endif() # Year list(GET GIT_TAG_EXPLODED 0 GIT_TAG_YEAR) if(${GIT_TAG_YEAR} LESS 2017 OR ${GIT_TAG_LISTCOUNT} GREATER 2100) message(WARNING "Invalid tag year ${GIT_TAG_YEAR}") return() endif() # Month list(GET GIT_TAG_EXPLODED 1 GIT_TAG_MONTH) if(${GIT_TAG_MONTH} LESS 1 OR ${GIT_TAG_MONTH} GREATER 12) message(WARNING "Invalid tag month ${GIT_TAG_MONTH}") return() endif() # Day list(GET GIT_TAG_EXPLODED 2 GIT_TAG_DAY) if(${GIT_TAG_DAY} LESS 1 OR ${GIT_TAG_DAY} GREATER 31) message(WARNING "Invalid tag day ${GIT_TAG_DAY}") return() endif() # Type list(GET GIT_TAG_EXPLODED 3 GIT_TAG_TYPE) if(NOT (${GIT_TAG_TYPE} STREQUAL "Release" OR ${GIT_TAG_TYPE} STREQUAL "Development")) message(WARNING "Invalid tag type ${GIT_TAG_TYPE}") return() endif() # Major list(GET GIT_TAG_EXPLODED 4 GIT_TAG_MAJOR) if(${GIT_TAG_MAJOR} LESS 0 OR ${GIT_TAG_MAJOR} GREATER 99) message(WARNING "Invalid tag major version ${GIT_TAG_MAJOR}") return() endif() # Minor list(GET GIT_TAG_EXPLODED 5 GIT_TAG_MINOR) if(${GIT_TAG_MINOR} LESS 0 OR ${GIT_TAG_MINOR} GREATER 99) message(WARNING "Invalid tag minor version ${GIT_TAG_MINOR}") return() endif() # Patch list(GET GIT_TAG_EXPLODED 6 GIT_TAG_PATCH) if(${GIT_TAG_PATCH} LESS 0 OR ${GIT_TAG_PATCH} GREATER 99) message(WARNING "Invalid tag patch version ${GIT_TAG_PATCH}") return() endif() # Label # 7 = Stable release # 8 = Dev release, first beta so only "beta" attached # 9 = Dev release, subsequent beta so "beta.N" attached (N>=2) if(${GIT_TAG_LISTCOUNT} EQUAL 8) list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL) elseif(${GIT_TAG_LISTCOUNT} EQUAL 9) list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL) list(GET GIT_TAG_EXPLODED 8 GIT_TAG_LABEL_NUM) set(GIT_TAG_LABEL ${GIT_TAG_LABEL} ${GIT_TAG_LABEL_NUM}) string(REPLACE ";" "." GIT_TAG_LABEL "${GIT_TAG_LABEL}") else() set(GIT_TAG_LABEL "") endif() # Override hardcoded version with the informations from the tag set(PROJECT_VERSION_MAJOR ${GIT_TAG_MAJOR} PARENT_SCOPE ) set(PROJECT_VERSION_MINOR ${GIT_TAG_MINOR} PARENT_SCOPE ) set(PROJECT_VERSION_PATCH ${GIT_TAG_PATCH} PARENT_SCOPE ) set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} PARENT_SCOPE ) if(${GIT_TAG_TYPE} STREQUAL "Development") set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} PARENT_SCOPE ) elseif(${GIT_TAG_TYPE} STREQUAL "Release") set(PROJECT_VERSION_LABEL "" PARENT_SCOPE ) # set release name from env var set(PROJECT_VERSION_RELEASENAME "${GIT_TAG_RELEASENAME}" PARENT_SCOPE ) endif() endfunction() # START OF MAIN # fallback defaults set(GIT_COMMIT_ID "unknown") set(GIT_COMMIT_DATE "") set(GIT_COMMIT_DATE_FRIENDLY "") set(PROJECT_VERSION_LABEL "") set(PROJECT_VERSION_RELEASENAME "") find_package(Git) if(GIT_FOUND) get_commit_id() get_commit_date() get_tag_name(${GIT_COMMIT_ID}) else() message(WARNING "Git not found. Build will not contain git revision info.") endif() set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") if(PROJECT_VERSION_LABEL) set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_LABEL}") endif() set(PROJECT_VERSION_FRIENDLY "${PROJECT_VERSION} (${GIT_COMMIT_DATE_FRIENDLY})") # Format: [-ReleaseName]-MAJ.MIN.PATCH[-prerelease_label] set(PROJECT_VERSION_FILENAME "${PROJECT_NAME}") if(PROJECT_VERSION_RELEASENAME) set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION_RELEASENAME}") endif() set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION}") message(STATUS "Project version: ${PROJECT_VERSION}") message(STATUS "Friendly project version: ${PROJECT_VERSION_FRIENDLY}") message(STATUS "Project version filename: ${PROJECT_VERSION_FILENAME}")