1#!/bin/sh
2#
3# This script generates a project-wide version identifier for use by
4# the `elftc_version()' API.
5#
6# $Id: make-toolchain-version 3731 2019-04-06 14:28:34Z jkoshy $
7
8#
9# Defaults.
10#
11buildhost=`uname -s`
12elftcname="elftoolchain"
13options="e:h:o:r:t:"
14top=""
15version="HEAD"
16versionfile="elftc_version.c"
17progname=`basename ${0}`
18
19usage()
20{
21    exec >&2
22
23    # Print a message, if supplied.
24    if [ -n "${*}" ]; then echo "##${@}"; fi
25
26    echo "Usage: ${progname} [options]"
27    echo "	Generate a toolchain-wide version number"
28    echo "	-e PROJECTNAME Set the project name [default: ${elftcname}]."
29    echo "	-h HOSTOS      Set the build OS [default: ${buildhost}]."
30    echo "	-o OUTPUT      Set the output file [default: ${versionfile}]."
31    echo "	-r VERSION     Set the version string [default: ${version}]."
32    echo "	-t TOPDIR      Set the top-of-tree directory [required]."
33    exit 1
34}
35
36# Determine the revision number for the source tree.
37#
38# - If CVS is detected, we use the string `unknown'.
39# - If SVN is detected, we use the `svninfo' tool to determine the
40#   in-tree revision number.
41# - Otherwise, we use `git --describe'.
42get_revision_string()
43{
44    v="unknown:unknown"
45    if [ -d CVS ]; then     # Look for CVS (NetBSD).
46        v="cvs:unknown"
47    elif [ -d .svn ]; then  # An SVN checkout (SourceForge or FreeBSD).
48        svnversion="$(svnversion 2>/dev/null)"
49        if [ -n "${svnversion}" ]; then
50            v="svn:${svnversion}"
51        fi
52    else        # Try git (DragonflyBSD).
53        gitversion="$(git describe --all --dirty --long 2> /dev/null)"
54        if [ -n "${gitversion}" ]; then
55            v="git:${gitversion}"
56	fi
57    fi
58
59    echo "${v}"
60}
61
62#
63# Parse options.
64#
65
66while getopts ${options} option
67do
68    case ${option} in
69	'e') elftcname="${OPTARG}"   ;;
70	'h') buildhost="${OPTARG}"   ;;
71	'o') versionfile="${OPTARG}" ;;
72	'r') version="${OPTARG}"      ;;
73	't') top="${OPTARG}"         ;;
74	'?') usage                   ;;
75    esac
76done
77
78[ -n "${top}" ] || usage
79
80curdir=`pwd`
81cd ${top} || usage "ERROR: Cannot change directory to \"${top}\"."
82
83# Determine the in-tree revision number.
84versionstring="$(get_revision_string)" || {
85    echo "ERROR: cannot determine a revision number." 1>&2;
86    exit 1
87}
88
89cd ${curdir} || usage "Cannot change back to ${curdir}."
90
91#
92# Only replace the source file if its content has changed.
93#
94tmpfile=`mktemp ${TMPDIR:-/tmp}/MV.XXXXXXX`
95trap "rm -f ${tmpfile};" 0 1 2 3 15
96
97cat > ${tmpfile} <<EOF
98/* WARNING: Generated by "${progname}". */
99
100#include <sys/types.h>
101#include <libelftc.h>
102
103const char *
104elftc_version(void)
105{
106	return "${elftcname} ${version} ${buildhost} ${versionstring}";
107}
108EOF
109
110if ! cmp -s ${tmpfile} ${versionfile}; then
111    echo "@ ${progname}: building \"${versionfile}\"."
112    cp ${tmpfile} ${versionfile} || exit ${?}
113fi
114