3 # Generate some basic versioning information which can be piped to a header.
5 # Copyright (c) 2006-2007 Luc Verhaegen <libv@skynet.be>
6 # Copyright (C) 2007 Hans Ulrich Niedermann <hun@n-dimensional.de>
8 # Permission is hereby granted, free of charge, to any person obtaining a
9 # copy of this software and associated documentation files (the "Software"),
10 # to deal in the Software without restriction, including without limitation
11 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 # and/or sell copies of the Software, and to permit persons to whom the
13 # Software is furnished to do so, subject to the following conditions:
15 # The above copyright notice and this permission notice shall be included in
16 # all copies or substantial portions of the Software.
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 # THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 # OTHER DEALINGS IN THE SOFTWARE.
26 # This script is based on the one written for xf86-video-unichrome by
27 # Luc Verhaegen, but was rewritten almost completely by Hans Ulrich
28 # Niedermann. The script contains a few bug fixes from Egbert Eich,
29 # Matthias Hopf, Joerg Sonnenberger, and possibly others.
31 # The author thanks the nice people on #git for the assistance.
33 # Simple testing of this script:
34 # /sbin/busybox sh git_version.sh --example > moo.c \
35 # && gcc -Wall -Wextra -Wno-unused -o moo moo.c \
37 # (bash should also do)
39 # For how to hook this up to your automake- and/or imake-based build
40 # system, best take a look at how the RadeonHD.am and/or RadeonHD.tmpl
41 # work in the xf86-video-radeonhd build system. For non-recursive make,
42 # you can probably make things a little bit simpler.
45 # * Uses hyphenated ("git-foo-bar") program names, which git upstream
46 # have declared deprecated.
53 -h, --help Print this help message.
55 -k, --keep-if-no-repo Keep old output file if no git repo found.
56 -o, --output FILENAME Set output file name.
57 -q, --quiet Quiet output.
58 -s, --srcdir DIRNAME Set source tree dir name.
59 -x, --example Print complete example program."
61 # The caller may have set these for us
68 self
="$(basename "$0")"
71 ifndef_symbol
="GIT_VERSION_H"
78 # Parse command line parameter, affecting defaults
79 while [ "x$1" != "x" ]
88 if [ "x$outfile" = "x-" ]; then
89 : # keep default ifndef_symbol
91 newdir
=$
(mktemp
-t -d git_version_XXXXXX
)
92 outfilenew
="$newdir/$1.new"
93 ifndef_symbol
=`basename "$outfile" | $SED 's|\.|_|g; s|[^A-Za-z0-9_]||g' | tr a-z A-Z`
96 echo "$self: Fatal: \"$1\" option requires parameter." >&2
104 echo "Usage: ${self} $USAGE"
105 [ -n "$LONG_USAGE" ] && echo "$LONG_USAGE"
108 -k|
--keep-if-no-repo)
113 if test -d "$1"; then
116 echo "$self: Fatal: \"$1\" not a directory." >&2
120 echo "$self: Fatal: \"$1\" option requires directory parameter." >&2
125 echo "$self: Fatal: Invalid command line paramenter: \"$1\"" >&2
132 # If not printing to stdout, redirect stdout to output file
133 rename_new_output
=false
134 if [ "x$outfile" = "x-" ]
136 : # keep using stdout
138 exec 1> "${outfilenew}"
141 # Done with creating output files, so we can change to source dir
142 abs_srcdir
="$(cd "$srcdir" && pwd)"
145 # Write program header
148 * Basic versioning gathered from the git repository.
149 * Automatically generated by $0.
152 #ifndef ${ifndef_symbol}
153 #define ${ifndef_symbol} 1
155 /* whether this is a dist tarball or not */
160 # Backwards compatibility hack for git 1.6.0 (and people running the
161 # latest pre-release version of git.)
163 # For now, we'll do this to support git 1.6, with minimal changes to
164 # the rest of this script, but no guarantees how long this will work.
165 # The hyphenated git-foo-bar names really are deprecated, and may
166 # disappear in the future as more of git gets rewritten as built-in C
167 # programs. Google summer of code students and other git developers
168 # are hard at work doing this, in order to make git more
169 # portable/usable for Windows users. As a result, some of the
170 # git-foo-bar programs, which will be moved to the exec-dir directory
171 # in git 1.6, may disappear altogether in the future. Hence the only
172 # truly safe and future-compatible way of running commands such as
173 # git-diff-files, git-rev-parse, etc., are "git diff-files" and
174 # "git rev-parse". Here endeth the git portability sermon, which
175 # I suspect will have as much effect as abstinence-only sex ed
176 # classes. :-) TYT, 2008-07-08
178 execdir
=$
(git
--exec-path 2> /dev
/null
)
179 if test -n "$execdir"; then
183 # Detect git tools (should work with old and new git versions)
185 for git_tool
in git-symbolic-ref git-rev-parse git-diff-files git-diff-index git git-describe
187 if [ x
`which $git_tool 2>/dev/null` = "x" ]; then
188 git_found
="'$git_tool' not found"
193 # Determine git specific defines
195 if [ "x$git_found" = "xyes" ]; then
196 git_version
=`git --version`
197 if [ "x$git_version" = "x" ]; then
198 git_errors
="${git_errors+${git_errors}; }error running 'git --version'"
203 # "git-rev-parse --git-dir" since git-0.99.7
204 git_repo_dir
="$(git-rev-parse --git-dir 2> /dev/null || true)"
205 abs_repo_dir
="$(cd "$git_repo_dir" && pwd)"
206 # Only accept the found git repo iff it is in our top srcdir, as determined
207 # by comparing absolute pathnames creaged by running pwd in the respective dir.
208 if [ "x$git_repo_dir" != "x" ] && [ "x${abs_repo_dir}" = "x${abs_srcdir}/.git" ]; then
210 if [ "x$git_found" = "xyes" ]; then
211 # git-1.4 and probably earlier understand "git-rev-parse HEAD"
212 git_shaid
=`git-describe --abbrev=12 --long 2>/dev/null ||
213 git-describe --abbrev=12 2>/dev/null ||
215 if [ "x$git_shaid" = "x" ]; then
216 git_errors
="${git_errors+${git_errors}; }error running 'git-rev-parse HEAD'"
218 # git-1.4 and probably earlier understand "git-symbolic-ref HEAD"
219 git_branch
=`git-symbolic-ref HEAD | $SED -n 's|^refs/heads/||p'`
220 if [ "x$git_branch" = "x" ]; then
221 # This happens, is OK, and "(no branch)" is what "git branch" prints.
222 git_branch
="(no branch)"
225 # git-1.4 does not understand "git-diff-files --quiet"
226 # git-1.4 does not understand "git-diff-index --cached --quiet HEAD"
227 if [ "x$(git-diff-files)" = "x" ] && [ "x$(git-diff-index --cached HEAD)" = "x" ]; then
233 # Write git specific defines
234 if [ "x$git_errors" = "x" ]; then
235 echo "/* No errors occured while running git */"
236 echo "#undef GIT_ERRORS"
238 echo "/* Some errors occured while running git */"
239 echo "#define GIT_ERRORS \"${git_errors}\""
243 if [ "x$git_found" = "xyes" ]; then
244 echo "/* git utilities found */"
245 echo "#undef GIT_NOT_FOUND"
246 echo "#define GIT_VERSION \"${git_version}\""
248 echo "/* git utilities not found */"
249 echo "#define GIT_NOT_FOUND \"${git_found}\""
250 echo "#undef GIT_VERSION"
254 if [ "x$git_repo" = "xno" ]; then
255 echo "/* No git repo found, probably building from dist tarball */"
256 echo "#undef GIT_REPO"
258 echo "/* git repo found */"
259 echo "#define GIT_REPO 1"
261 if [ "x$git_found" = "xyes" ]; then
262 echo "/* Git SHA ID of last commit */"
263 echo "#define GIT_SHAID \"${git_shaid}\""
266 echo "/* Branch this tree is on */"
267 echo "#define GIT_BRANCH \"$git_branch\""
270 # Any uncommitted changes we should know about?
271 # Or technically: Are the working tree or index dirty?
272 if [ "x$git_dirty" = "xno" ]; then
273 echo "/* SHA-ID uniquely defines the state of this code */"
274 echo "#undef GIT_DIRTY"
276 echo "/* Local changes might be breaking things */"
277 echo "#define GIT_DIRTY 1"
282 # Define a few immediately useful message strings
285 /* Define GIT_MESSAGE such that
286 * printf("%s: built from %s", argv[0], GIT_MESSAGE);
287 * forms a proper sentence.
291 # define GIT_DIRTY_MSG " + changes"
292 #else /* !GIT_DIRTY */
293 # define GIT_DIRTY_MSG ""
294 #endif /* GIT_DIRTY */
297 # define GIT_ERROR_MSG " with error: " GIT_ERRORS
298 #else /* !GIT_ERRORS */
299 # define GIT_ERROR_MSG ""
300 #endif /* GIT_ERRORS */
303 # define GIT_DIST_MSG "dist of "
304 #else /* !GIT_IS_DIST */
305 # define GIT_DIST_MSG ""
306 #endif /* GIT_IS_DIST */
309 # ifdef GIT_NOT_FOUND
310 # define GIT_MESSAGE GIT_DIST_MSG "git sources without git: " GIT_NOT_FOUND
311 # else /* !GIT_NOT_FOUND */
312 # define GIT_MESSAGE \\
314 "commit " GIT_SHAID GIT_DIRTY_MSG \\
316 # endif /* GIT_NOT_FOUND */
317 #else /* !GIT_REPO */
318 # define GIT_MESSAGE GIT_DIST_MSG "non-git sources" GIT_ERROR_MSG
319 #endif /* GIT_REPO */
321 #endif /* ${ifndef_symbol} */
329 /* example program demonstrating the use of git_version.sh output */
337 int main(int argc, char *argv[])
339 const char *const idx = strrchr(argv[0], '/');
340 const char *const prog = (idx)?(idx+1):(argv[0]);
341 #ifdef PACKAGE_VERSION
342 printf("%s: version %s, built from %s\n", prog, PACKAGE_VERSION, GIT_MESSAGE);
343 #elif defined(GIT_MESSAGE)
344 printf("%s: built from %s\n", prog, GIT_MESSAGE);
351 # Change back to working dir for the remaining output file manipulations.
354 # If necessary, overwrite outdated output file with new one
355 if [ "x$outfile" != "x-" ]
357 if [ -f "$outfile" ]; then
358 if [ "x$keep_if_no_repo" = "xyes" ] && [ "x$git_repo" = "xno" ]; then
359 "$quiet" ||
echo "$self: Not a git repo, keeping existing $outfile" >&2
361 elif cmp "$outfile" "$outfilenew" > /dev
/null
; then
362 "$quiet" ||
echo "$self: Output is unchanged, keeping $outfile" >&2
365 echo "$self: Output has changed, updating $outfile" >&2
366 mv -f "$outfilenew" "$outfile"
369 echo "$self: Output is new file, creating $outfile" >&2
370 mv -f "$outfilenew" "$outfile"