added missing VERSION prefix to _gmx_ver_string
[gromacs/rigid-bodies.git] / cmake / gmxGenerateVersionInfo.cmake
blob59094d20870e149e6418ca31e706df367c4cea4a
1 # Generate Gromacs development build version information.
3 # The script generates version information for a build from a development 
4 # source tree based on git repository information. 
5 # It is assumed that by default the script is run in cmake script mode.
6 # If *not* called in script mode but used in generating cache variables,  
7 # GEN_VERSION_INFO_INTERNAL has to be set ON.
9 # The following variables have to be previously defined: 
10 # PROJECT_VERSION       - hard-coded version string 
11 # PROJECT_SOURCE_DIR    - top level source directory 
12 # VERSION_C_CMAKEIN     - path to the version.c.cmakein file 
13 # VERSION_C_OUT         - path to the version.c output file
15 # Output: 
16 # i)  Script mode: version.c configured from the input version.c.cmakein using 
17 # the variables listed below. 
18 # ii) Cache variable mode: the varables below are set in cache.
20 # GMX_PROJECT_VERSION_STR   - version string 
21 # GMX_GIT_HEAD_HASH         - git hash of current local HEAD 
22 # GMX_GIT_REMOTE_HASH       - git hash of the first ancestor commit from the 
23 #                             main Gromacs repository 
26 if(${PROJECT_VERSION} STREQUAL "")
27     message(FATAL_ERROR "PROJECT_VERSION undefined!")
28 endif()
29 set(VER ${PROJECT_VERSION})
31 # if we're generating variables for cache unset the variables 
32 if(GEN_VERSION_INFO_INTERNAL)
33     unset(GMX_PROJECT_VERSION_STR CACHE)
34     unset(GMX_GIT_HEAD_HASH CACHE)
35     unset(GMX_GIT_REMOTE_HASH CACHE)
36     unset(USE_VERSION_H CACHE)
37 endif()
39 unset(GIT_BIN)
40 find_program(GIT_BIN "git")
41 mark_as_advanced(GIT_BIN)
43 # if the source tree is a git repository extract the necessary information for  
44 # building the development version string 
45 if(NOT "${GIT_BIN}" MATCHES ".*-NOTFOUND" 
46    AND IS_DIRECTORY "${PROJECT_SOURCE_DIR}/.git")
47     # refresh git index 
48     execute_process(COMMAND ${GIT_BIN} update-index -q --refresh
49         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
50         TIMEOUT 5
51         OUTPUT_QUIET
52         ERROR_VARIABLE EXEC_ERR
53         OUTPUT_STRIP_TRAILING_WHITESPACE
54     ) 
56    # get the full hash of the current HEAD 
57     execute_process(COMMAND ${GIT_BIN} rev-parse -q HEAD
58         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
59         TIMEOUT 5
60         OUTPUT_VARIABLE GMX_GIT_HEAD_HASH
61         ERROR_VARIABLE EXEC_ERR
62         OUTPUT_STRIP_TRAILING_WHITESPACE
63     )
64     # extract the shortened hash (7 char)
65     string(SUBSTRING ${GMX_GIT_HEAD_HASH} 0 5 HEAD_HASH_SHORT) 
67     # if there are local uncommitted changes, the build gets labeled "dirty"
68     execute_process(COMMAND ${GIT_BIN} diff-index --name-only HEAD
69         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
70         TIMEOUT 5
71         OUTPUT_VARIABLE SRC_LOCAL_CHANGES
72         ERROR_VARIABLE EXEC_ERR
73         OUTPUT_STRIP_TRAILING_WHITESPACE
74     )   
75     if(NOT ${SRC_LOCAL_CHANGES} STREQUAL "")
76         set(DIRTY_STR "-dirty")
77         set(GMX_GIT_HEAD_HASH "${GMX_GIT_HEAD_HASH} (dirty)")
78     endif()
80     # get the date of the HEAD commit
81     execute_process(COMMAND ${GIT_BIN} rev-list -n1 "--pretty=format:%ci" HEAD
82         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
83         TIMEOUT 5
84         OUTPUT_VARIABLE HEAD_DATE
85         ERROR_VARIABLE EXEC_ERR
86         OUTPUT_STRIP_TRAILING_WHITESPACE
87     )
88     string(REGEX REPLACE "\n| " ";" HEAD_DATE ${HEAD_DATE})
89     list(GET HEAD_DATE 2 HEAD_DATE)
90     string(REGEX REPLACE "-" "" HEAD_DATE ${HEAD_DATE})
92     # compile the version string suffix
93     set(VERSION_STR_SUFFIX "${HEAD_DATE}-${HEAD_HASH_SHORT}${DIRTY_STR}") 
94     
95     # find the name of the remote which is located on the official gromacs git server
96     execute_process(COMMAND ${GIT_BIN} config --get-regexp 
97                     "remote\\..*\\.url" "git\\.gromacs\\.org[:|/]gromacs"
98         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
99         TIMEOUT 5
100         OUTPUT_VARIABLE GMX_REMOTE
101         ERROR_VARIABLE EXEC_ERR
102         OUTPUT_STRIP_TRAILING_WHITESPACE
103     )
104     # if there's a remote from the gromacs git, try to find ancestor commits of the 
105     # current HEAD from this remote; otherwise, label the buld "unknown"
106     if(GMX_REMOTE STREQUAL "")
107         set(VERSION_STR_SUFFIX "${VERSION_STR_SUFFIX}-unknown")
108         set(GMX_GIT_REMOTE_HASH "unknown")        
109     else()         
110         string(REGEX REPLACE "remote\\.(.*)\\.url.*" "\\1" GMX_REMOTE ${GMX_REMOTE})
111         # find the first ancestor in the list provided by rev-list (not 
112         # necessarily the last though) which is in GMX_REMOTE, extract the 
113         # hash and the number of commits HEAD is ahead with 
114         execute_process(COMMAND ${GIT_BIN} rev-list --max-count=100 HEAD
115             WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
116             TIMEOUT 5
117             OUTPUT_VARIABLE ANCESTOR_LIST
118         )
119         string(REGEX REPLACE "\n" ";" ANCESTOR_LIST ${ANCESTOR_LIST})
121         set(AHEAD 0)
122         set(GMX_GIT_REMOTE_HASH "")
123         foreach(OBJ ${ANCESTOR_LIST})
124             execute_process(COMMAND ${GIT_BIN} name-rev --refs=refs/remotes/${GMX_REMOTE}/* ${OBJ}
125                 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
126                 TIMEOUT 5
127                 OUTPUT_VARIABLE HASH_AND_REVNAME
128                 OUTPUT_STRIP_TRAILING_WHITESPACE
129             )
130             string(REGEX REPLACE "\n" "" HASH_AND_REVNAME ${HASH_AND_REVNAME})
131             string(REGEX REPLACE " " ";" HASH_AND_REVNAME ${HASH_AND_REVNAME})
132             list(GET HASH_AND_REVNAME 0 GMX_GIT_REMOTE_HASH) 
133             list(GET HASH_AND_REVNAME 1 REVNAME)
134             # stop and set the hash if we have a hit, otherwise loop and count
135             # how far ahead is the local repo
136             if(${REVNAME} MATCHES "remotes/${GMX_REMOTE}/.*")
137                 set(GMX_GIT_REMOTE_HASH 
138                         "${GMX_GIT_REMOTE_HASH} (${AHEAD} newer local commits)")
139                 break()
140             else()
141                 math(EXPR AHEAD ${AHEAD}+1)
142             endif()
143         endforeach(OBJ)
144         # mark the build "local" if didn't find any commits that are from 
145         # remotes/${GMX_REMOTE}/*
146         if(${GMX_GIT_REMOTE_HASH} STREQUAL "")
147             set(GMX_GIT_REMOTE_HASH "unknown")
148             set(VERSION_STR_SUFFIX "${VERSION_STR_SUFFIX}-local") 
149         endif()
150     endif()
152     # compile final version string, if there is already a -dev suffix in VER 
153     # remove everything after this and replace it with the generated suffix
154     string(REGEX REPLACE "(.*)-dev.*" "\\1" VER ${VER})
155     set(GMX_PROJECT_VERSION_STR "${VER}-dev-${VERSION_STR_SUFFIX}")
156 else()
157     # the version has to be defined 
158     message(WARNING " Not a git repository and/or git not found, using hard-coded version.")
159     set(GMX_PROJECT_VERSION_STR "${PROJECT_VERSION}")
160     set(GMX_GIT_HEAD_HASH "unknown")
161     set(GMX_GIT_REMOTE_HASH "unknown")    
162 endif()
164 # if we're generating cache variables set these
165 # otherwise it's assumed that it's called in script mode to generate version.c 
166 if(GEN_VERSION_INFO_INTERNAL)
167     set(GMX_PROJECT_VERSION_STR ${GMX_PROJECT_VERSION_STR} 
168         CACHE STRING "Gromacs version string" FORCE)
169     set(GMX_GIT_HEAD_HASH ${GMX_GIT_HEAD_HASH}${DIRTY_STR}  
170         CACHE STRING "Current git HEAD commit object" FORCE)
171     set(GMX_GIT_REMOTE_HASH ${GMX_GIT_REMOTE_HASH} 
172         CACHE STRING "Commmit object of the nearest ancestor present in the Gromacs git repository" FORCE)
173     mark_as_advanced(GMX_GIT_HEAD_HASH GMX_GIT_REMOTE_HASH USE_VERSION_H)
174 else()
175     if(${VERSION_C_CMAKEIN} STREQUAL "")
176         message(FATAL_ERROR "Missing input parameter VERSION_C_CMAKEIN!")
177     endif()
178     if(${VERSION_C_OUT} STREQUAL "")
179         message(FATAL_ERROR "Missing input parameter VERSION_C_OUT!")
180     endif()
181     # generate version.c
182    configure_file(${VERSION_C_CMAKEIN} ${VERSION_C_OUT})    
183 endif()