updated FindCUDA to version from cmake 2.8.1 for CUDA 2.3 support
[gromacs/rigid-bodies.git] / cmake / gmxGenerateVersionInfo.cmake
blob2403feb295c42241e3fef8a64834f5639b7b2b58
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 # Git_EXECUTABLE        - path to git binary
11 # Git_VERSION           - git version (if not defined it's assumed that >=1.5.3)
12 # PROJECT_VERSION       - hard-coded version string, should have the following structure: 
13 #                       VERSION[-dev-SUFFIX] where the VERSION can have any form and the suffix 
14 #                       is optional but should start with -dev
15 # PROJECT_SOURCE_DIR    - top level source directory (which has to be in git)
16 # VERSION_C_CMAKEIN     - path to the version.c.cmakein file 
17 # VERSION_C_OUT         - path to the version.c output file
19 # Output: 
20 # i)  Script mode: version.c configured from the input version.c.cmakein using 
21 # the variables listed below. 
22 # ii) Cache variable mode: the varables below are set in cache.
24 # GMX_PROJECT_VERSION_STR   - version string 
25 # GMX_GIT_HEAD_HASH         - git hash of current local HEAD 
26 # GMX_GIT_REMOTE_HASH       - git hash of the first ancestor commit from the 
27 #                             main Gromacs repository 
28
29 # Szilard Pall (pszilard@cbr.su.se) 
31 if(${PROJECT_VERSION} STREQUAL "")
32     message(FATAL_ERROR "PROJECT_VERSION undefined!")
33 endif()
34 set(VER ${PROJECT_VERSION})
36 # if we're generating variables for cache unset the variables 
37 if(GEN_VERSION_INFO_INTERNAL)
38     set(GMX_PROJECT_VERSION_STR)
39     set(GMX_GIT_HEAD_HASH)
40     set(GMX_GIT_REMOTE_HASH)
41 endif()
43 # bail if the source tree is not in a git repository  
44 if(NOT EXISTS "${PROJECT_SOURCE_DIR}/.git")
45     message(FATAL_ERROR " Project source directory ${PROJECT_SOURCE_DIR} not in git")
46 endif()
48 # if git executable xists and it's compatible version
49 # build the development version string 
50 if(EXISTS ${Git_EXECUTABLE} AND NOT Git_VERSION VERSION_LESS "1.5.1")
51     # refresh git index 
52     execute_process(COMMAND ${Git_EXECUTABLE} update-index -q --refresh
53         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
54         TIMEOUT 5
55         OUTPUT_QUIET
56         ERROR_VARIABLE EXEC_ERR
57         OUTPUT_STRIP_TRAILING_WHITESPACE
58     ) 
60    # get the full hash of the current HEAD 
61     execute_process(COMMAND ${Git_EXECUTABLE} rev-parse HEAD
62         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
63         OUTPUT_VARIABLE GMX_GIT_HEAD_HASH
64         ERROR_VARIABLE EXEC_ERR
65         OUTPUT_STRIP_TRAILING_WHITESPACE
66     )
67     # extract the shortened hash (7 char)
68     string(SUBSTRING ${GMX_GIT_HEAD_HASH} 0 5 HEAD_HASH_SHORT) 
70     # if there are local uncommitted changes, the build gets labeled "dirty"
71     execute_process(COMMAND ${Git_EXECUTABLE} diff-index --name-only HEAD
72         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
73         OUTPUT_VARIABLE SRC_LOCAL_CHANGES
74         ERROR_VARIABLE EXEC_ERR
75         OUTPUT_STRIP_TRAILING_WHITESPACE
76     )   
77     if(NOT ${SRC_LOCAL_CHANGES} STREQUAL "")
78         set(DIRTY_STR "-dirty")
79         set(GMX_GIT_HEAD_HASH "${GMX_GIT_HEAD_HASH} (dirty)")
80     endif()
82     # if git is older then 1.5.3 we need to extract the RFC2822 style date 
83     # and massage it, otherwise the ISO 8601 format is more trusworthy
84     if (NOT Git_VERSION STREQUAL "" AND Git_VERSION VERSION_LESS "1.5.3")
85         execute_process(COMMAND ${Git_EXECUTABLE} rev-list -n1 "--pretty=format:%cD" HEAD
86             WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
87             OUTPUT_VARIABLE HEAD_DATE
88             ERROR_VARIABLE EXEC_ERR
89             OUTPUT_STRIP_TRAILING_WHITESPACE
90         )
91         # date format: day, D Mmm YYYY  -> YYYY-MM-DD
92         # if the day is single sigit need to insert a "0"
93         string(REGEX REPLACE ".*(, )([0-9] )(.*)" "\\10\\2\\3" 
94             HEAD_DATE ${HEAD_DATE})
95         string(REGEX REPLACE ".*, ([0-9][0-9]) ([A-Z][a-z]+) ([0-9]+).*" "\\3\\2\\1" 
96             HEAD_DATE ${HEAD_DATE})
97         string(TOUPPER ${HEAD_DATE} HEAD_DATE)
98         string(REGEX REPLACE "JAN" "01" HEAD_DATE ${HEAD_DATE})
99         string(REGEX REPLACE "FEB" "02" HEAD_DATE ${HEAD_DATE})
100         string(REGEX REPLACE "MAR" "03" HEAD_DATE ${HEAD_DATE})
101         string(REGEX REPLACE "APR" "04" HEAD_DATE ${HEAD_DATE})
102         string(REGEX REPLACE "MAY" "05" HEAD_DATE ${HEAD_DATE})
103         string(REGEX REPLACE "JUN" "06" HEAD_DATE ${HEAD_DATE})
104         string(REGEX REPLACE "JUL" "07" HEAD_DATE ${HEAD_DATE})
105         string(REGEX REPLACE "AUG" "08" HEAD_DATE ${HEAD_DATE})
106         string(REGEX REPLACE "SEP" "09" HEAD_DATE ${HEAD_DATE})
107         string(REGEX REPLACE "OCT" "10" HEAD_DATE ${HEAD_DATE})
108         string(REGEX REPLACE "NOV" "11" HEAD_DATE ${HEAD_DATE})
109         string(REGEX REPLACE "DEC" "12" HEAD_DATE ${HEAD_DATE})
110     else()
111         # get the date of the HEAD commit
112         execute_process(COMMAND ${Git_EXECUTABLE} rev-list -n1 "--pretty=format:%ci" HEAD
113             WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
114             OUTPUT_VARIABLE HEAD_DATE
115             ERROR_VARIABLE EXEC_ERR
116             OUTPUT_STRIP_TRAILING_WHITESPACE
117         )
118         string(REGEX REPLACE "\n| " ";" HEAD_DATE ${HEAD_DATE})
119         list(GET HEAD_DATE 2 HEAD_DATE)
120         string(REGEX REPLACE "-" "" HEAD_DATE ${HEAD_DATE})
121     endif()
123     # compile the version string suffix
124     set(VERSION_STR_SUFFIX "${HEAD_DATE}-${HEAD_HASH_SHORT}${DIRTY_STR}") 
125     
126     # find the name of the remote which is located on the official gromacs git server
127     execute_process(COMMAND ${Git_EXECUTABLE} config --get-regexp 
128                     "remote\\..*\\.url" "git\\.gromacs\\.org[:|/]gromacs"
129         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
130         OUTPUT_VARIABLE GMX_REMOTE
131         ERROR_VARIABLE EXEC_ERR
132         OUTPUT_STRIP_TRAILING_WHITESPACE
133     )
134     # if there's a remote from the gromacs git, try to find ancestor commits of the 
135     # current HEAD from this remote; otherwise, label the buld "unknown"
136     if(GMX_REMOTE STREQUAL "")
137         set(VERSION_STR_SUFFIX "${VERSION_STR_SUFFIX}-unknown")
138         set(GMX_GIT_REMOTE_HASH "unknown")        
139     else()         
140         string(REGEX REPLACE "remote\\.(.*)\\.url.*" "\\1" GMX_REMOTE ${GMX_REMOTE})
141         # find the first ancestor in the list provided by rev-list (not 
142         # necessarily the last though) which is in GMX_REMOTE, extract the 
143         # hash and the number of commits HEAD is ahead with 
144         execute_process(COMMAND ${Git_EXECUTABLE} rev-list --max-count=100 HEAD
145             WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
146             OUTPUT_VARIABLE ANCESTOR_LIST
147         )
148         string(REGEX REPLACE "\n" ";" ANCESTOR_LIST ${ANCESTOR_LIST})
150         set(AHEAD 0)
151         set(GMX_GIT_REMOTE_HASH "")
152         foreach(OBJ ${ANCESTOR_LIST})
153             execute_process(COMMAND ${Git_EXECUTABLE} name-rev --refs=refs/remotes/${GMX_REMOTE}/* ${OBJ}
154                 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
155                 OUTPUT_VARIABLE HASH_AND_REVNAME
156                 OUTPUT_STRIP_TRAILING_WHITESPACE
157             )
158             string(REGEX REPLACE "\n" "" HASH_AND_REVNAME ${HASH_AND_REVNAME})
159             string(REGEX REPLACE " " ";" HASH_AND_REVNAME ${HASH_AND_REVNAME})
160             list(GET HASH_AND_REVNAME 0 GMX_GIT_REMOTE_HASH) 
161             list(GET HASH_AND_REVNAME 1 REVNAME)
162             # stop and set the hash if we have a hit, otherwise loop and count
163             # how far ahead is the local repo
164             if(${REVNAME} MATCHES "remotes/${GMX_REMOTE}/.*")
165                 set(GMX_GIT_REMOTE_HASH 
166                         "${GMX_GIT_REMOTE_HASH} (${AHEAD} newer local commits)")
167                 break()
168             else()
169                 math(EXPR AHEAD ${AHEAD}+1)
170             endif()
171         endforeach(OBJ)
172         # mark the build "local" if didn't find any commits that are from 
173         # remotes/${GMX_REMOTE}/*
174         if(${GMX_GIT_REMOTE_HASH} STREQUAL "")
175             set(GMX_GIT_REMOTE_HASH "unknown")
176             set(VERSION_STR_SUFFIX "${VERSION_STR_SUFFIX}-local") 
177         endif()
178     endif()
180     # compile final version string, if there is already a -dev suffix in VER 
181     # remove everything after this and replace it with the generated suffix
182     string(REGEX REPLACE "(.*)-dev.*" "\\1" VER ${VER})
183     set(GMX_PROJECT_VERSION_STR "${VER}-dev-${VERSION_STR_SUFFIX}")
184 else()
185     # the version has to be defined - if not we're not using version.h/.c and set 
186     # the GIT related information to "unknown"
187     message(WARNING " Source tree seems to be a repository, but no compatible git is available, using hard-coded version string")
188     set(GMX_PROJECT_VERSION_STR "${PROJECT_VERSION}")
189     set(GMX_GIT_HEAD_HASH "unknown")
190     set(GMX_GIT_REMOTE_HASH "unknown")
191 endif()
193 # if we're generating cache variables set these
194 # otherwise it's assumed that it's called in script mode to generate version.c 
195 if(GEN_VERSION_INFO_INTERNAL)
196     set(GMX_PROJECT_VERSION_STR ${GMX_PROJECT_VERSION_STR} 
197         CACHE STRING "Gromacs version string" FORCE)
198     set(GMX_GIT_HEAD_HASH ${GMX_GIT_HEAD_HASH}${DIRTY_STR}  
199         CACHE STRING "Current git HEAD commit object" FORCE)
200     set(GMX_GIT_REMOTE_HASH ${GMX_GIT_REMOTE_HASH} 
201         CACHE STRING "Commmit object of the nearest ancestor present in the Gromacs git repository" FORCE)
202     mark_as_advanced(GMX_GIT_HEAD_HASH GMX_GIT_REMOTE_HASH)
203 else()
204     if(${VERSION_C_CMAKEIN} STREQUAL "")
205         message(FATAL_ERROR "Missing input parameter VERSION_C_CMAKEIN!")
206     endif()
207     if(${VERSION_C_OUT} STREQUAL "")
208         message(FATAL_ERROR "Missing input parameter VERSION_C_OUT!")
209     endif()
210     # generate version.c
211    configure_file(${VERSION_C_CMAKEIN} ${VERSION_C_OUT})    
212 endif()