xref: /netbsd-src/sys/conf/newvers.sh (revision fb5eed702691094bd687fbf1ded189c87457cd35)
1#!/bin/sh -
2#
3#	$NetBSD: newvers.sh,v 1.62 2017/04/08 18:24:09 christos Exp $
4#
5# Copyright (c) 1984, 1986, 1990, 1993
6#	The Regents of the University of California.  All rights reserved.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11# 1. Redistributions of source code must retain the above copyright
12#    notice, this list of conditions and the following disclaimer.
13# 2. Redistributions in binary form must reproduce the above copyright
14#    notice, this list of conditions and the following disclaimer in the
15#    documentation and/or other materials provided with the distribution.
16# 3. Neither the name of the University nor the names of its contributors
17#    may be used to endorse or promote products derived from this software
18#    without specific prior written permission.
19#
20# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30# SUCH DAMAGE.
31#
32#	@(#)newvers.sh	8.1 (Berkeley) 4/20/94
33
34# newvers.sh -- Create a "vers.c" file containing version information.
35#
36# The "vers.c" file in the current directory is the primary output.  It
37# contains C source code with several variables containing information
38# about the build.  This file is expected to be incorporated into a
39# kernel, and when that kernel is booted then the information can be
40# queried by the uname(8) command.
41#
42# Command line options:
43#
44#     -R                Reproducible build: Do not embed directory
45#                       names, user names, time stamps, or other dynamic
46#                       information into the output file.  This intended
47#                       to allow two builds done at different times and
48#                       even by different people on different hosts to
49#                       produce identical output.
50#
51#     -r <timestamp>    Reproducible build: Embed fixed information to
52#			the output file.
53#			This intended to allow two builds done at different
54#			times and even by different people on different
55#			hosts to produce identical output.
56#
57#     -m <machine>      Use the specified string as the value of the
58#                       machine variable
59#
60#     -i <id>           Use the specified string as the value of the
61#                       kernel_ident variable
62#
63#     -n                Do not include an ELF note section in the output
64#                       file.
65# Environment variables:
66#
67#     BUILDID		If defined, ${BUILDID} is appended to the
68#			default value of the kernel_ident string.
69#			(If the -i command line option is used, then
70#			BUILDID is not appended.)
71#
72#     BUILDINFO		A string to be stored in the kernel's buildinfo
73#			variable.  ${BUILDINFO} may be a multi-line string,
74#			and may use C-style backslash escapes.
75#			Lines may be separated by either literal newlines
76#			or "\n" escape sequences.
77#
78# Output files:
79#
80#     vers.c            The "vers.c" file in the current directory is
81#                       the primary output.
82#
83#     version           The "version" file in the current directory
84#                       is both an input and an output.  See the
85#                       description under "Input files".
86#
87# Input files:
88#
89#     version           The "version" file in the current directory
90#                       contains an integer counter, representing the
91#                       number of times this script has been executed in
92#                       this directory, starting with "0" if the file
93#                       does not exist.  The serial number in the file
94#                       is incremented after the file is read. so that
95#                       the incremented serial number is an output from
96#                       the present build and an input to the next build
97#                       that is performed in the same directory.
98#
99#     copyright         The "copyright" file (in the same directory as
100#                       this script itself) contains a copyright notice,
101#                       which is embedded in the copyright variable in
102#                       the output file.
103#
104#     ident             The "ident" file in the current directory is optional.
105#			If this file exists, then its contents override the
106#			default value of the kernel_ident string.
107#
108# Input from external commands:
109#
110#     osrelease.sh      This script is expected to print the OS revision.
111#                       The result is stored in the osrelease variable.
112#
113
114# FUNCTIONS
115
116# source_lines [input] --
117#
118# Convert a multi-line string to a format that's suitable for inclusion in
119# C source code.  The result should look like this:
120#
121# "first line\n"
122# "second line\n"
123#
124# with <backslash><letter n> inside the quotes for each line,
125# literal quotation marks around each line,
126# and a literal newline separating one line from the next.
127#
128# Input is from "$1" if that is defined, or from stdin if $1 is not defined.
129#
130source_lines()
131{
132	if [ -n "${1+set}" ]; then
133		printf "%s" "$1"
134	else
135		cat
136	fi \
137	| awk '{
138		# awk does not care about whether or not the last line
139		# of input ends with a newline.
140		# Convert <backslash> to <backslash><backslash>.
141		gsub("\\\\","\\\\");
142		# Convert <quote> to <backslash><quote>
143		gsub("\"","\\\"");
144		# Add <backslash><letter n> to the end of each line,
145		# and wrap each line in double quotes.
146		printf("\"%s\\n\"\n", $0);
147	}'
148}
149
150# MAIN PROGRAM
151
152if [ ! -e version ]; then
153	echo 0 > version
154fi
155
156Rflag=false
157nflag=false
158timestamp=
159pwd=$(pwd)
160
161while getopts "Rr:m:i:n" OPT; do
162	case $OPT in
163	R)
164		# -R: Reproducible build
165		Rflag=true
166		;;
167	r)
168		# -r <timestamp>: timestamp
169		timestamp="$OPTARG"
170		;;
171	m)
172		# -m <machine>: machine
173		machine="$OPTARG"
174		;;
175	i)
176		# -i <id>: Use the secified string as the
177		# value of the kernel_ident variable
178		id="$OPTARG"
179		;;
180	n)
181		# -n: Do not include a ELF note section in the output file.
182		nflag=true
183		;;
184	*)	echo "Usage: newvers.sh [-Rn] [-r <timestamp>] [-m <machine>] [-i <kernel>]" >&2
185		exit 1;;
186	esac
187done
188
189if [ -z "${id}" ]; then
190	if [ -f ident ]; then
191		id="$(cat ident)"
192	else
193		id=$(basename "${pwd}")
194	fi
195	# Append ".${BUILDID}" to the default value of <id>.
196	# If the "-i <id>" command line option was used then this
197	# branch is not taken, so the command-line value of <id>
198	# is used without change.
199	if [ -n "${BUILDID}" ]; then
200		id="${id}.${BUILDID}"
201	fi
202fi
203
204if ${Rflag}; then
205	reproversion=
206else
207	if [ -z "${timestamp}" ]; then
208		v=$(cat version)
209		t=$(LC_ALL=C date)
210		u=${USER-root}
211		h=$(hostname)
212		d=$(pwd)
213		# Increment the serial number in the version file
214		echo $(expr ${v} + 1) > version
215	else
216		v=0
217		t=$(LC_ALL=C TZ=UTC date -r "${timestamp}")
218		u=mkrepro
219		h=mkrepro.NetBSD.org
220		d="/usr/src/sys/arch/${machine}/compile/${id}"
221	fi
222	reproversion=" #${v}: ${t}\n\t${u}@${h}:${d}"
223fi
224
225cwd=$(dirname "$0")
226copyright="$(cat "${cwd}/copyright")"
227osrelcmd=${cwd}/osrelease.sh
228
229ost="NetBSD"
230osr=$(sh $osrelcmd)
231
232fullversion="${ost} ${osr} (${id})${reproversion}\n"
233
234# Convert multi-line strings to C source code.
235# Also add an extra blank line to copyright.
236#
237copyright_source="$(printf "%s\n\n" "${copyright}" | source_lines)"
238fullversion_source="$(printf "%b" "${fullversion}" | source_lines)"
239buildinfo_source="$(printf "%b" "${BUILDINFO}" | source_lines)"
240
241# work around escaping issues with different shells
242emptyq='""'
243
244cat << _EOF > vers.c
245/*
246 * Automatically generated file from $0
247 * Do not edit.
248 */
249#include <sys/cdefs.h>
250#include <sys/types.h>
251#include <sys/param.h>
252#include <sys/exec.h>
253#include <sys/exec_elf.h>
254
255const char ostype[] = "${ost}";
256const char osrelease[] = "${osr}";
257const char sccs[] = "@(#)" ${fullversion_source};
258const char version[] = ${fullversion_source};
259const char buildinfo[] = ${buildinfo_source:-${emptyq}};
260const char kernel_ident[] = "${id}";
261const char copyright[] = ${copyright_source};
262_EOF
263
264${nflag} && exit 0
265
266cat << _EOF >> vers.c
267
268/*
269 * NetBSD identity note.
270 */
271#ifdef __arm__
272#define _SHT_NOTE	%note
273#else
274#define _SHT_NOTE	@note
275#endif
276
277#define	_S(TAG)	__STRING(TAG)
278__asm(
279	".section\t\".note.netbsd.ident\", \"\"," _S(_SHT_NOTE) "\n"
280	"\t.p2align\t2\n"
281	"\t.long\t" _S(ELF_NOTE_NETBSD_NAMESZ) "\n"
282	"\t.long\t" _S(ELF_NOTE_NETBSD_DESCSZ) "\n"
283	"\t.long\t" _S(ELF_NOTE_TYPE_NETBSD_TAG) "\n"
284	"\t.ascii\t" _S(ELF_NOTE_NETBSD_NAME) "\n"
285	"\t.long\t" _S(__NetBSD_Version__) "\n"
286	"\t.p2align\t2\n"
287);
288
289_EOF
290