Merge branch 'blender2.7'
[blender.git] / build_files / cmake / buildinfo.cmake
1 # This is called by cmake as an external process from
2 # ./source/creator/CMakeLists.txt to write ./source/creator/buildinfo.h
3 # Caller must define:
4 #   SOURCE_DIR
5 # Optional overrides:
6 #   BUILD_DATE
7 #   BUILD_TIME
8
9 # Extract working copy information for SOURCE_DIR into MY_XXX variables
10 # with a default in case anything fails, for example when using git-svn
11 set(MY_WC_HASH "unknown")
12 set(MY_WC_BRANCH "unknown")
13 set(MY_WC_COMMIT_TIMESTAMP 0)
14
15 # Guess if this is a git working copy and then look up the revision
16 if(EXISTS ${SOURCE_DIR}/.git)
17         execute_process(COMMAND git rev-parse --abbrev-ref HEAD
18                         WORKING_DIRECTORY ${SOURCE_DIR}
19                         OUTPUT_VARIABLE MY_WC_BRANCH
20                         OUTPUT_STRIP_TRAILING_WHITESPACE)
21
22         if(MY_WC_BRANCH STREQUAL "HEAD")
23                 # Detached HEAD, check whether commit hash is reachable
24                 # in the master branch
25                 execute_process(COMMAND git rev-parse --short=12 HEAD
26                                 WORKING_DIRECTORY ${SOURCE_DIR}
27                                 OUTPUT_VARIABLE MY_WC_HASH
28                                 OUTPUT_STRIP_TRAILING_WHITESPACE)
29
30                 execute_process(COMMAND git branch --list master blender-v* --contains ${MY_WC_HASH}
31                                 WORKING_DIRECTORY ${SOURCE_DIR}
32                                 OUTPUT_VARIABLE _git_contains_check
33                                 OUTPUT_STRIP_TRAILING_WHITESPACE)
34
35                 if(NOT _git_contains_check STREQUAL "")
36                         set(MY_WC_BRANCH "master")
37                 else()
38                         execute_process(COMMAND git show-ref --tags -d
39                                         WORKING_DIRECTORY ${SOURCE_DIR}
40                                         OUTPUT_VARIABLE _git_tag_hashes
41                                         OUTPUT_STRIP_TRAILING_WHITESPACE)
42
43                         execute_process(COMMAND git rev-parse HEAD
44                                         WORKING_DIRECTORY ${SOURCE_DIR}
45                                         OUTPUT_VARIABLE _git_head_hash
46                                         OUTPUT_STRIP_TRAILING_WHITESPACE)
47
48                         if(_git_tag_hashes MATCHES "${_git_head_hash}")
49                                 set(MY_WC_BRANCH "master")
50                         else()
51                                 execute_process(COMMAND git branch --contains ${MY_WC_HASH}
52                                                 WORKING_DIRECTORY ${SOURCE_DIR}
53                                                 OUTPUT_VARIABLE _git_contains_branches
54                                                 OUTPUT_STRIP_TRAILING_WHITESPACE)
55                                 string(REGEX REPLACE "^\\*[ \t]+" "" _git_contains_branches "${_git_contains_branches}")
56                                 string(REGEX REPLACE "[\r\n]+" ";" _git_contains_branches "${_git_contains_branches}")
57                                 string(REGEX REPLACE ";[ \t]+" ";" _git_contains_branches "${_git_contains_branches}")
58                                 foreach(_branch ${_git_contains_branches})
59                                         if(NOT "${_branch}" MATCHES "\\(HEAD.*")
60                                                 set(MY_WC_BRANCH "${_branch}")
61                                                 break()
62                                         endif()
63                                 endforeach()
64                                 unset(_branch)
65                                 unset(_git_contains_branches)
66                         endif()
67
68                         unset(_git_tag_hashes)
69                         unset(_git_head_hashs)
70                 endif()
71
72
73                 unset(_git_contains_check)
74         else()
75                 execute_process(COMMAND git log HEAD..@{u}
76                                 WORKING_DIRECTORY ${SOURCE_DIR}
77                                 OUTPUT_VARIABLE _git_below_check
78                                 OUTPUT_STRIP_TRAILING_WHITESPACE
79                                 ERROR_QUIET)
80                 if(NOT _git_below_check STREQUAL "")
81                         # If there're commits between HEAD and upstream this means
82                         # that we're reset-ed to older revision. Use it's hash then.
83                         execute_process(COMMAND git rev-parse --short=12 HEAD
84                                         WORKING_DIRECTORY ${SOURCE_DIR}
85                                         OUTPUT_VARIABLE MY_WC_HASH
86                                         OUTPUT_STRIP_TRAILING_WHITESPACE)
87                 else()
88                         execute_process(COMMAND git rev-parse --short=12 @{u}
89                                         WORKING_DIRECTORY ${SOURCE_DIR}
90                                         OUTPUT_VARIABLE MY_WC_HASH
91                                         OUTPUT_STRIP_TRAILING_WHITESPACE
92                                         ERROR_QUIET)
93
94                         if(MY_WC_HASH STREQUAL "")
95                                 # Local branch, not set to upstream.
96                                 # Well, let's use HEAD for now
97                                 execute_process(COMMAND git rev-parse --short=12 HEAD
98                                                 WORKING_DIRECTORY ${SOURCE_DIR}
99                                                 OUTPUT_VARIABLE MY_WC_HASH
100                                                 OUTPUT_STRIP_TRAILING_WHITESPACE)
101                         endif()
102                 endif()
103
104                 if(MY_WC_BRANCH MATCHES "^blender-v")
105                         set(MY_WC_BRANCH "master")
106                 endif()
107
108                 unset(_git_below_check)
109         endif()
110
111         execute_process(COMMAND git log -1 --format=%ct
112                         WORKING_DIRECTORY ${SOURCE_DIR}
113                         OUTPUT_VARIABLE MY_WC_COMMIT_TIMESTAMP
114                         OUTPUT_STRIP_TRAILING_WHITESPACE)
115         # May fail in rare cases
116         if(MY_WC_COMMIT_TIMESTAMP STREQUAL "")
117                 set(MY_WC_COMMIT_TIMESTAMP 0)
118         endif()
119
120         # Update GIT index before getting dirty files
121         execute_process(COMMAND git update-index -q --refresh
122                         WORKING_DIRECTORY ${SOURCE_DIR}
123                         OUTPUT_STRIP_TRAILING_WHITESPACE)
124
125         execute_process(COMMAND git diff-index --name-only HEAD --
126                         WORKING_DIRECTORY ${SOURCE_DIR}
127                         OUTPUT_VARIABLE _git_changed_files
128                         OUTPUT_STRIP_TRAILING_WHITESPACE)
129
130         if(NOT _git_changed_files STREQUAL "")
131                 set(MY_WC_BRANCH "${MY_WC_BRANCH} (modified)")
132         else()
133                 # Unpushed commits are also considered local modifications
134                 execute_process(COMMAND git log @{u}..
135                                 WORKING_DIRECTORY ${SOURCE_DIR}
136                                 OUTPUT_VARIABLE _git_unpushed_log
137                                 OUTPUT_STRIP_TRAILING_WHITESPACE
138                                 ERROR_QUIET)
139                 if(NOT _git_unpushed_log STREQUAL "")
140                         set(MY_WC_BRANCH "${MY_WC_BRANCH} (modified)")
141                 endif()
142                 unset(_git_unpushed_log)
143         endif()
144
145         unset(_git_changed_files)
146 endif()
147
148 # BUILD_PLATFORM and BUILD_PLATFORM are taken from CMake
149 # but BUILD_DATE and BUILD_TIME are platform dependent
150 if(UNIX)
151         if(NOT BUILD_DATE)
152                 execute_process(COMMAND date "+%Y-%m-%d" OUTPUT_VARIABLE BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
153         endif()
154         if(NOT BUILD_TIME)
155                 execute_process(COMMAND date "+%H:%M:%S" OUTPUT_VARIABLE BUILD_TIME OUTPUT_STRIP_TRAILING_WHITESPACE)
156         endif()
157 elseif(WIN32)
158         if(NOT BUILD_DATE)
159                 execute_process(COMMAND cmd /c date /t OUTPUT_VARIABLE BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
160         endif()
161         if(NOT BUILD_TIME)
162                 execute_process(COMMAND cmd /c time /t OUTPUT_VARIABLE BUILD_TIME OUTPUT_STRIP_TRAILING_WHITESPACE)
163         endif()
164 endif()
165
166 # Write a file with the BUILD_HASH define
167 file(WRITE buildinfo.h.txt
168         "#define BUILD_HASH \"${MY_WC_HASH}\"\n"
169         "#define BUILD_COMMIT_TIMESTAMP ${MY_WC_COMMIT_TIMESTAMP}\n"
170         "#define BUILD_BRANCH \"${MY_WC_BRANCH}\"\n"
171         "#define BUILD_DATE \"${BUILD_DATE}\"\n"
172         "#define BUILD_TIME \"${BUILD_TIME}\"\n"
173 )
174
175 # cleanup
176 unset(MY_WC_HASH)
177 unset(MY_WC_COMMIT_TIMESTAMP)
178 unset(MY_WC_BRANCH)
179 unset(BUILD_DATE)
180 unset(BUILD_TIME)
181
182
183 # Copy the file to the final header only if the version changes
184 # and avoid needless rebuilds
185 # TODO: verify this comment is true, as BUILD_TIME probably changes
186 execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
187                         buildinfo.h.txt buildinfo.h)