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