# # Sets RC_PROJECT_VERSION and RC_PACKAGE_VERSION # # Split a version number into separate components # version the version number to split # major variable name to store the major version in # minor variable name to store the minor version in # patch variable name to store the patch version in # extra variable name to store a version suffix in function(version_split version major minor patch extra) string(REGEX MATCH "([0-9]+)(\\.([0-9]+)(\\.([0-9]+)(.*)?)?)?" version_valid ${version}) if(version_valid) string(REPLACE "." ";" version_split ${version}) list(LENGTH version_split version_split_len) list(GET version_split 0 version_major) set(${major} ${version_major} PARENT_SCOPE) if (version_split_len GREATER "1") list(GET version_split 1 version_minor) set(${minor} ${version_minor} PARENT_SCOPE) endif() if (version_split_len GREATER "2") list(GET version_split 2 version_patch_extra) string(REGEX REPLACE "([0-9]+)(.*)" "\\1;\\2" version_patch_extra ${version_patch_extra}) list(GET version_patch_extra 0 version_patch) set(${patch} ${version_patch} PARENT_SCOPE) list(GET version_patch_extra 1 version_extra) set(${extra} ${version_extra} PARENT_SCOPE) endif() else(version_valid) message(AUTHOR_WARNING "Bad version ${version}; falling back to 0 (have you made an initial release?)") set(${major} "0" PARENT_SCOPE) set(${minor} "0" PARENT_SCOPE) set(${patch} "0" PARENT_SCOPE) set(${extra} "" PARENT_SCOPE) endif(version_valid) endfunction(version_split) # Bump a version number. The final component of the version number is bumped. # E.g.: 2.3 -> 2.4; 2 -> 3; 1.2.3 -> 1.2.4 # version_in the version to bump # version_out variable name to store the bumped version in function(version_bump version_in version_out) version_split(${version_in} major minor patch extra) if (patch MATCHES "^[0-9]+$") math(EXPR patch "${patch}+1") set(${version_out} "${major}.${minor}.${patch}" PARENT_SCOPE) elseif (minor MATCHES "^[0-9]+$") math(EXPR minor "${minor}+1") set(${version_out} "${major}.${minor}" PARENT_SCOPE) else() math(EXPR major "${major}+1") set(${version_out} "${major}" PARENT_SCOPE) endif() endfunction(version_bump) ########################## # get GIT_VERSION # and GIT_FULL_VERSION ########################## find_program(GIT_CMD git PATHS "C:/Program Files/Git/bin") mark_as_advanced(GIT_CMD) if (GIT_CMD) execute_process(COMMAND ${GIT_CMD} rev-parse --show-toplevel WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE GIT_TOPLEVEL ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) endif() if (GIT_CMD AND NOT "${GIT_TOPLEVEL}" STREQUAL "") execute_process(COMMAND ${GIT_CMD} rev-parse --short HEAD WORKING_DIRECTORY ${GIT_TOPLEVEL} OUTPUT_VARIABLE GIT_SHA1 OUTPUT_STRIP_TRAILING_WHITESPACE) #message(STATUS "GIT_SHA1: " ${GIT_SHA1}) execute_process(COMMAND ${GIT_CMD} describe --match "*[0-9].[0-9]*" HEAD WORKING_DIRECTORY ${GIT_TOPLEVEL} OUTPUT_VARIABLE GIT_DESCRIBE ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) #message(STATUS "GIT_DESCRIBE: " ${GIT_DESCRIBE}) if (GIT_DESCRIBE) string(REGEX REPLACE "v?([0-9.]+).*" "\\1" GIT_VERSION ${GIT_DESCRIBE}) message(STATUS "GIT_VERSION: " ${GIT_VERSION}) # as package version we use the full version from git describe: 1.7.1+7+ge324c81 if (GIT_DESCRIBE MATCHES ".*-g.*") # convert a git describe string to usable debian version, e.g. v1.7.1-7-ge324c81 to 1.7.1+7+ge324c81 string(REGEX REPLACE "v?([0-9]*.[0-9.]*).*-([0-9]*)-([a-g0-9]*)" "\\1+\\2+\\3" GIT_FULL_VERSION ${GIT_DESCRIBE}) else() # current HEAD is git tag (i.e. release), directly use the version set(GIT_FULL_VERSION ${GIT_VERSION}) endif() else () # no (suitable) tag found set(GIT_VERSION "0.0.0") # get number of commits in repo execute_process(COMMAND ${GIT_CMD} rev-list --count HEAD WORKING_DIRECTORY ${GIT_TOPLEVEL} OUTPUT_VARIABLE GIT_COMMIT_COUNT OUTPUT_STRIP_TRAILING_WHITESPACE) set(GIT_FULL_VERSION 0.0.0+${GIT_COMMIT_COUNT}+g${GIT_SHA1}) endif () # check if this is a shallow clone execute_process(COMMAND ${GIT_CMD} rev-parse --absolute-git-dir WORKING_DIRECTORY ${GIT_TOPLEVEL} OUTPUT_VARIABLE GIT_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) if (EXISTS "${GIT_DIR}/shallow") message(STATUS "Shallow git repo of depth ${GIT_COMMIT_COUNT}") set(GIT_REPO_IS_SHALLOW true) endif () endif () ######################### # get PACKAGE_XML_VERSION ######################### if (EXISTS "${PROJECT_SOURCE_DIR}/package.xml") file(STRINGS "${PROJECT_SOURCE_DIR}/package.xml" PACKAGE_XML_VERSION_LINE REGEX [0-9.]*) string(REGEX REPLACE .*\([0-9.]*\).* \\1 PACKAGE_XML_VERSION "${PACKAGE_XML_VERSION_LINE}") MESSAGE(STATUS "PACKAGE_XML_VERSION: " ${PACKAGE_XML_VERSION}) endif () ######################## # set RC_PROJECT_VERSION # priority: # - manually set # - git # - package.xml # - PROJECT_VERSION ######################## if (NOT RC_PROJECT_VERSION) # set RC_PROJECT_VERSION to MAJOR.MINOR.PATCH # RC_PACKAGE_VERSION can have extra info if (GIT_REPO_IS_SHALLOW AND PACKAGE_XML_VERSION) message(STATUS "Using PACKAGE_XML_VERSION as it is a shallow clone (e.g. on ROS buildfarm)") set(RC_PROJECT_VERSION ${PACKAGE_XML_VERSION}) set(RC_PACKAGE_VERSION ${RC_PROJECT_VERSION}) elseif (GIT_VERSION) set(RC_PROJECT_VERSION ${GIT_VERSION}) set(RC_PACKAGE_VERSION ${GIT_FULL_VERSION}) elseif (PACKAGE_XML_VERSION) set(RC_PROJECT_VERSION ${PACKAGE_XML_VERSION}) set(RC_PACKAGE_VERSION ${RC_PROJECT_VERSION}) elseif (PROJECT_VERSION) set(RC_PROJECT_VERSION ${PROJECT_VERSION}) else () message(WARNING "RC_PROJECT_VERSION not set. Defaulting to 0.0.0") set(RC_PROJECT_VERSION "0.0.0") endif () endif () if (NOT RC_PACKAGE_VERSION) message(WARNING "RC_PACKAGE_VERSION not set! Falling back to RC_PROJECT_VERSION (${RC_PROJECT_VERSION})") set(RC_PACKAGE_VERSION ${RC_PROJECT_VERSION}) endif () # warn if versions don't match if (GIT_VERSION AND NOT GIT_REPO_IS_SHALLOW AND NOT GIT_VERSION MATCHES ${RC_PROJECT_VERSION}) message(WARNING "Version from git (${GIT_VERSION}) doesn't match RC_PROJECT_VERSION (${RC_PROJECT_VERSION})") endif() if (PACKAGE_XML_VERSION AND NOT PACKAGE_XML_VERSION MATCHES ${RC_PROJECT_VERSION}) message(WARNING "Version from package.xml (${PACKAGE_XML_VERSION}) doesn't match RC_PROJECT_VERSION (${RC_PROJECT_VERSION})") endif() message(STATUS "RC_PROJECT_VERSION: " ${RC_PROJECT_VERSION}) message(STATUS "RC_PACKAGE_VERSION: " ${RC_PACKAGE_VERSION}) version_split(${RC_PROJECT_VERSION} PACKAGE_VERSION_MAJOR PACKAGE_VERSION_MINOR PACKAGE_VERSION_PATCH extra) #message(STATUS "PACKAGE_VERSION_MAJOR: " ${PACKAGE_VERSION_MAJOR}) #message(STATUS "PACKAGE_VERSION_MINOR: " ${PACKAGE_VERSION_MINOR}) #message(STATUS "PACKAGE_VERSION_PATCH: " ${PACKAGE_VERSION_PATCH}) # generate an integer version number: major * 10000 + minor * 100 + patch math(EXPR RC_PROJECT_VERSION_INT "${PACKAGE_VERSION_MAJOR} * 10000 + ${PACKAGE_VERSION_MINOR} * 100 + ${PACKAGE_VERSION_PATCH}") # make RC_PROJECT_VERSION available as define in the project source add_definitions(-DPROJECT_VERSION="${RC_PROJECT_VERSION}") add_definitions(-DPROJECT_VERSION_INT=${RC_PROJECT_VERSION_INT}) add_definitions(-DPACKAGE_VERSION="${RC_PACKAGE_VERSION}") add_definitions(-DPACKAGE_VERSION_MAJOR=${PACKAGE_VERSION_MAJOR}) add_definitions(-DPACKAGE_VERSION_MINOR=${PACKAGE_VERSION_MINOR}) add_definitions(-DPACKAGE_VERSION_PATCH=${PACKAGE_VERSION_PATCH}) # set ABI version to major.minor, which will be used for the SOVERSION set(abiversion "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}") # generate project_version.h and project_version.cc if the .in files exist # # These files provide compile-time and runtime version information about your project. # To offer the version info to the users of your library, you need to # adapt the following lines in your respective CMakeLists.txt: # add_library( SHARED ${CMAKE_CURRENT_BINARY_DIR}/project_version.cc) # install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/project_version.h COMPONENT dev DESTINATION include/) # To use it within your library or tests you need to add the include directory: # > target_include_directories(yourtarget PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}) if (EXISTS "${PROJECT_SOURCE_DIR}/cmake/project_version.h.in") string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER) configure_file(cmake/project_version.h.in ${PROJECT_NAME}/project_version.h @ONLY) configure_file(cmake/project_version.cc.in ${PROJECT_NAME}/project_version.cc @ONLY) endif ()