[cmake-developers] added get_git_revision and get_git_branch commands as follow-up to cmake at cmake.org
Pascal Bach
pascal.bach at siemens.com
Mon Oct 5 09:35:31 EDT 2015
Hi Daniel
I just wanted to let you know that I was planing to bring a git versioning script upstream soon.
It is based on the following sequence of commands: https://github.com/bufferoverflow/proxyme/blob/master/CMakeLists.txt#L5
It tries to generate a version string of the following form: {git-tag} ({git-hash}-{dirty}).
It will try to do the best possible to figure out the tag:
- If on a valid tag: v1.1.0 (f567657)
- If no tag but clean workdir: undefined (f567657)
- If not tag and working tree with uncommited changes: undefined (f567657-dirty)
This -dirty convention is the same as used by u-boot and the linux kernel.
Maybe you can incorperate these ideas into your solution too.
Regards
Pascal
Am 05.10.2015 um 12:50 schrieb Daniel Wirtz:
> Hey all,
>
> thanks for the feedback, i've included most of it.
>
> Regarding the configure/build issue: that indeed is inconvenient and may cause irritation. on the other side, if there has been git activity fussing with any source files affecting the build, cmake will run again and hence capture the possibly new git info. so the case where you change the revision after configure to an extent where cmake will not automatically re-run is uncommon, at least for my guessing.
> however, i've included an explicit warning in the docs to raise awareness.
>
> i'm happy to provide a suitable procedure that is flexible enough; providing scripts that configure files (like with sprokit) seems too specific as people might want to have a single "config.h" file or so containing more than just the git info.
> i've thought about the possibility to generate an explicit "git_version.h" file to include, but that 1) restricts possible languages and 2) will require an extra build target that is run each build etc. any thoughts?
>
> Daniel
>
> Signed-off-by: Daniel Wirtz <daniel.wirtz at simtech.uni-stuttgart.de>
> ---
> Modules/FindGit.cmake | 145 +++++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 138 insertions(+), 7 deletions(-)
>
> diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake
> index b4f7b4b..e8a86f5 100644
> --- a/Modules/FindGit.cmake
> +++ b/Modules/FindGit.cmake
> @@ -2,28 +2,75 @@
> # FindGit
> # -------
> #
> +# This module helps finding a local Git_ installation and provides convenience functions for common Git queries.
> #
> +# .. _Git: http://git-scm.com/
> #
> -# The module defines the following variables:
> +# Defined variables
> +# """""""""""""""""
> #
> -# ::
> +# :variable:`GIT_EXECUTABLE`
> +# Path to Git_ command line client
> +# :variable:`GIT_FOUND`
> +# True if the Git_ command line client was found
> +# :variable:`GIT_VERSION_STRING`
> +# The version of Git_ found (since CMake 2.8.8)
> +#
> +# Defined functions
> +# """""""""""""""""
> +#
> +# For convenience, the module provides the additional functions
> +#
> +# :command:`git_get_revision`
> +# Get commit revision number information. +#
> +# :command:`git_get_branch` +# Get current branch information.
> #
> -# GIT_EXECUTABLE - path to git command line client
> -# GIT_FOUND - true if the command line client was found
> -# GIT_VERSION_STRING - the version of git found (since CMake 2.8.8)
> +# **WARNING**
> #
> -# Example usage:
> +# If you use those functions at *configure* time and checkout a different Git_ revision after running :manual:`cmake(1)`,
> +# the information from :command:`git_get_revision` or :command:`git_get_branch` will be outdated.
> +# If you need to be sure, we recommend using :command:`add_custom_command` or :command:`add_custom_target` in conjunction with
> +# the :manual:`cmake(1)` script mode (:code:`-P`) to ensure the Git_ information is obtained at *build* time. +# +#
> +# Example usage
> +# """""""""""""
> #
> # ::
> #
> # find_package(Git)
> # if(GIT_FOUND)
> # message("git found: ${GIT_EXECUTABLE}")
> +# git_get_branch(GITBRANCH)
> +# message("current branch at ${CMAKE_CURRENT_SOURCE_DIR}: ${GITBRANCH}")
> # endif()
> +#
> +# Details
> +# """""""
> +#
> +# .. variable:: GIT_EXECUTABLE
> +#
> +# Returns the full path to the Git_ executable to use in e.g. :command:`add_custom_command` like
> +#
> +# ::
> +#
> +# add_custom_command(COMMAND ${GIT_EXECUTABLE} clone https://github.com/myrepo mydir)
> +# +# .. variable:: GIT_FOUND
> +#
> +# Boolean variable set to TRUE if a local Git_ was found, FALSE else.
> +# +# .. variable:: GIT_VERSION_STRING
> +#
> +# The output of :code:`git --version`
> +
>
> #=============================================================================
> # Copyright 2010 Kitware, Inc.
> # Copyright 2012 Rolf Eike Beer <eike at sf-mail.de>
> +# Copyright 2015 Daniel Wirtz <daniel.wirtz at simtech-uni-stuttgart.de>
> #
> # Distributed under the OSI-approved BSD License (the "License");
> # see accompanying file Copyright.txt for details.
> @@ -73,7 +120,91 @@ endif()
> # Handle the QUIETLY and REQUIRED arguments and set GIT_FOUND to TRUE if
> # all listed variables are TRUE
> -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
> +include(FindPackageHandleStandardArgs)
> find_package_handle_standard_args(Git
> REQUIRED_VARS GIT_EXECUTABLE
> VERSION_VAR GIT_VERSION_STRING)
> +
> +# Convenience Git repo & branch information functions
> +
> +#.rst:
> +# .. command:: git_get_revision
> +#
> +# ::
> +#
> +# git_get_revision(VARNAME
> +# [SHORT]
> +# [GIT_OPTIONS] <string>
> +# [WORKING_DIRECTORY] <directory>)
> +#
> +# Obtain Git_ revision information using the rev-parse_ command. Effectively calls :code:`rev-parse [GIT_OPTIONS] --verify -q HEAD`.
> +#
> +# ``VARNAME``
> +# The workspace variable name to assign the result to.
> +#
> +# ``SHORT``
> +# Optional. If set to TRUE, the short revision string will be returned. Otherwise, the full revision hash is returned.
> +#
> +# ``GIT_OPTIONS``
> +# Optional. Specify a string like :code:`"--sq"` to add to the options of the rev-parse_ command.
> +#
> +# .. _rev-parse: https://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html
> +#
> +# ``WORKING_DIRECTORY``
> +# The working directory at which to execute the git commands.
> +# If not specified, :variable:`CMAKE_CURRENT_SOURCE_DIR` is assumed. +function(git_get_revision VARNAME)
> + if (NOT GIT_FOUND)
> + message(FATAL_ERROR "Cannot use git_get_revision: Git was not found.")
> + endif()
> + + cmake_parse_arguments(GIT "SHORT" "WORKING_DIRECTORY;GIT_OPTIONS" "" ${ARGN})
> + + if(NOT GIT_WORKING_DIRECTORY OR "${GIT_WORKING_DIRECTORY}" STREQUAL "")
> + set(GIT_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
> + endif()
> + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse ${GIT_OPTIONS} --verify -q HEAD
> + OUTPUT_VARIABLE RES
> + ERROR_VARIABLE ERR
> + OUTPUT_STRIP_TRAILING_WHITESPACE
> + WORKING_DIRECTORY ${GIT_WORKING_DIRECTORY})
> + set(${VARNAME} ${RES} PARENT_SCOPE)
> + if (ERR)
> + message(WARNING "Issuing Git command '${GIT_EXECUTABLE} rev-parse --verify -q HEAD' failed: ${ERR}")
> + endif()
> +endfunction()
> +
> +#.rst:
> +# .. command:: git_get_branch
> +#
> +# ::
> +#
> +# git_get_branch(VARNAME
> +# [WORKING_DIRECTORY] <directory>)
> +#
> +# ``VARNAME``
> +# The workspace variable name to assign the result to.
> +#
> +# ``WORKING_DIRECTORY``
> +# The working directory at which to execute the git commands.
> +# If not specified, :variable:`CMAKE_CURRENT_SOURCE_DIR` is assumed.
> +function(git_get_branch VARNAME)
> + if (NOT GIT_FOUND)
> + message(FATAL_ERROR "Cannot use git_get_branch: Git was not found.")
> + endif()
> + + cmake_parse_arguments(GIT "" "WORKING_DIRECTORY" "" ${ARGN})
> +
> + if(NOT GIT_WORKING_DIRECTORY OR "${GIT_WORKING_DIRECTORY}" STREQUAL "")
> + set(GIT_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
> + endif()
> + execute_process(COMMAND ${GIT_EXECUTABLE} symbolic-ref -q HEAD
> + OUTPUT_VARIABLE RES
> + ERROR_VARIABLE ERR
> + OUTPUT_STRIP_TRAILING_WHITESPACE
> + WORKING_DIRECTORY ${GIT_WORKING_DIRECTORY})
> + if (ERR)
> + message(WARNING "Issuing Git command '${GIT_EXECUTABLE} symbolic-ref -q HEAD' failed: ${ERR}")
> + endif()
> + set(${VARNAME} ${RES} PARENT_SCOPE)
> +endfunction()
> \ No newline at end of file
More information about the cmake-developers
mailing list