xref: /freebsd/contrib/bmake/boot-strap (revision 3cbb4cc200f8a0ad7ed08233425ea54524a21f1c)
1:
2# NAME:
3#	boot-strap
4#
5# SYNOPSIS:
6#	boot-strap ["options"]
7#	boot-strap --prefix=/opt --install
8#	boot-strap --prefix=$HOME --install-host-target -DWITH_PROG_VERSION
9#	boot-strap ["options"] op=build
10#	boot-strap ["options"] op=install
11#
12# DESCRIPTION:
13#	This script is used to configure/build bmake it builds for
14#	each host-target in a different subdir to keep the src clean.
15#	There is no requirement for an existing make(1).
16#
17#	On successful completion if no '--install' flag is given,
18#	it echos a command to do installation.
19#
20#	The variable "op" defaults to 'all', and is affected by
21#	'--install' flag as above.
22#	Other values include:
23#
24#	configure
25#		Just run 'configure'
26#
27#	build
28#		If 'configure' has not been done, do it, then
29#		run the build script, and finally 'test'.
30#
31#	install
32#		If 'build' has not been done, do it, 'test' then
33#		install.
34#
35#	clean
36#		attempt to clean up
37#
38#	test
39#		run the unit-tests.  Done automatically after 'build'
40#		and before 'install'.
41#
42#	The above are leveraged by a trivial makefile for the benefit
43#	of those that have './configure; make; make install' baked
44#	into them.
45#
46#	Options:
47#
48#	-c "rc"
49#		Pick up settings from "rc".
50#		We look for '.bmake-boot-strap.rc' before processing
51#		options (unless SKIP_RC is set in environment).
52#
53#	--share "share_dir"
54#		Where to put man pages and mk files.
55#		If $prefix ends in $HOST_TARGET, and $prefix/../share
56#		exits, the default will be that rather than $prefix/share.
57#
58#	--mksrc "mksrc"
59#		Indicate where the mk files can be found.
60#		Default is $Mydir/mk
61#
62#	--install
63#		If build and test work, run bmake install.
64#		BINDIR=$prefix/bin
65#		SHAREDIR=$prefix/share
66#
67#	--install-host-target
68#		As for '--install' but BINDIR=$prefix/$HOST_TARGET/bin
69#		This is useful when $prefix/ is shared by multiple
70#		machines.
71#
72#	Flags relevant when installing:
73#
74#	-DWITHOUT_INSTALL_MK
75#		Skip installing mk files.
76#		By default they will be installed to $prefix/share/mk
77#
78#	-DWITH_PROG_VERSION
79#		Install 'bmake' as 'bmake-$MAKE_VERSION'
80#		A symlink will be made as 'bmake' unless
81#		-DWITHOUT_PROG_LINK is set.
82#
83#	Possibly useful configure_args:
84#
85#	--without-meta
86#		disable use of meta mode.
87#
88#	--without-filemon
89#		disable use of filemon(9) which is currently only
90#		available for NetBSD and FreeBSD.
91#
92#	--with-filemon=ktrace
93#		on NetBSD or others with fktrace(2), use ktrace
94#		version of filemon.
95#
96#	--with-filemon="path/to/filemon.h"
97#		enables use of filemon(9) by meta mode.
98#
99#	--with-machine="machine"
100#		set "machine" to override that determined by
101#		machine.sh
102#
103#	--with-force-machine="machine"
104#		force "machine" even if uname(3) provides a value.
105#
106#	--with-machine_arch="machine_arch"
107#		set "machine_arch" to override that determined by
108#		machine.sh
109#
110#	--with-default-sys-path="syspath"
111#		set an explicit default "syspath" which is where bmake
112#		will look for sys.mk and friends.
113#
114# AUTHOR:
115#	Simon J. Gerraty <sjg@crufty.net>
116
117# RCSid:
118#	$Id: boot-strap,v 1.53 2020/09/16 02:12:01 sjg Exp $
119#
120#	@(#) Copyright (c) 2001 Simon J. Gerraty
121#
122#	This file is provided in the hope that it will
123#	be of use.  There is absolutely NO WARRANTY.
124#	Permission to copy, redistribute or otherwise
125#	use this file is hereby granted provided that
126#	the above copyright notice and this notice are
127#	left intact.
128#
129#	Please send copies of changes and bug-fixes to:
130#	sjg@crufty.net
131#
132
133Mydir=`dirname $0`
134. "$Mydir/os.sh"
135case "$Mydir" in
136/*) ;;
137*) Mydir=`cd "$Mydir" && 'pwd'`;;
138esac
139
140Usage() {
141	[ "$1" ] && echo "ERROR: $@" >&2
142	echo "Usage:" >&2
143	echo "$0 [--<configure_arg> ...][<prefix>][--install]" >&2
144	exit 1
145}
146
147Error() {
148	echo "ERROR: $@" >&2
149	exit 1
150}
151
152source_rc() {
153	rc="$1"; shift
154	for d in ${*:-""}
155	do
156		r="${d:+$d/}$rc"
157		[ -f "$r" -a -s "$r" ] || continue
158		echo "NOTE: reading $r"
159		. "$r"
160		break
161	done
162}
163
164cmd_args="$@"
165
166# clear some things from the environment that we care about
167unset MAKEOBJDIR MAKEOBJDIRPREFIX
168# or that might be incompatible
169unset MAKE MAKEFLAGS
170
171# --install[-host-target] will set this
172INSTALL_PREFIX=
173# other things we pass to install step
174INSTALL_ARGS=
175CONFIGURE_ARGS=
176MAKESYSPATH=
177# pick a useful default prefix (for me at least ;-)
178for prefix in /opt/$HOST_TARGET "$HOME/$HOST_TARGET" /usr/pkg /usr/local ""
179do
180	[ -d "${prefix:-.}" ] || continue
181	case "$prefix" in
182	*/$HOST_TARGET)
183		p=`dirname $prefix`
184		if [ -d $p/share ]; then
185			INSTALL_BIN=$HOST_TARGET/bin
186			prefix=$p
187		fi
188		;;
189	esac
190        echo "NOTE: default prefix=$prefix ${INSTALL_BIN:+INSTALL_BIN=$INSTALL_BIN}"
191	break
192done
193srcdir=$Mydir
194mksrc=$Mydir/mk
195objdir=
196quiet=:
197
198${SKIP_RC:+:} source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME"
199
200get_optarg() {
201	expr "x$1" : "x[^=]*=\\(.*\\)"
202}
203
204here=`'pwd'`
205if [ $here = $Mydir ]; then
206   # avoid pollution
207   OBJROOT=../
208fi
209
210op=all
211BMAKE=
212
213while :
214do
215	case "$1" in
216	--) shift; break;;
217        --help) sed -n -e "1d;/RCSid/,\$d" -e '/^#\.[a-z]/d' -e '/^#/s,^# *,,p' $0; exit 0;;
218	--prefix) prefix="$2"; shift;;
219	--prefix=*) prefix=`get_optarg "$1"`;;
220	--src=*) srcdir=`get_optarg "$1"`;;
221	--with-mksrc=*|--mksrc=*) mksrc=`get_optarg "$1"`;;
222	--share=*) share_dir=`get_optarg "$1"`;;
223	--share) share_dir="$2"; shift;;
224	--with-default-sys-path=*)
225	    CONFIGURE_ARGS="$1";;
226	--with-default-sys-path)
227	    CONFIGURE_ARGS="$1 $2";;
228	--install) INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix};;
229	--install-host-target)
230                INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
231                INSTALL_BIN=$HOST_TARGET/bin;;
232	--install-destdir=*) INSTALL_DESTDIR=`get_optarg "$1"`;;
233	--install-prefix=*) INSTALL_PREFIX=`get_optarg "$1"`;;
234	-DWITH*) INSTALL_ARGS="$INSTALL_ARGS $1";;
235	-s|--src) srcdir="$2"; shift;;
236	-m|--mksrc) mksrc="$2"; shift;;
237	-o|--objdir) objdir="$2"; shift;;
238	-q) quiet=;;
239	-c) source_rc "$2"; shift;;
240	--*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1";;
241	*=*) eval "$1"; export `expr "x$1" : "x\\(.[^=]*\\)=.*"`;;
242	*) break;;
243	esac
244        shift
245done
246
247AddConfigure() {
248	case " $CONFIGURE_ARGS " in
249	*" $1"*) ;;
250	*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1$2";;
251	esac
252}
253
254GetDir() {
255	match="$1"
256	shift
257	fmatch="$1"
258	shift
259	for dir in $*
260	do
261		[ -d "$dir" ] || continue
262		case "/$dir/" in
263		*$match*) ;;
264		*) continue;;
265		esac
266		case "$fmatch" in
267		.) ;;
268		*) [ -s $dir/$fmatch ] || continue;;
269		esac
270		case "$dir/" in
271		*./*) cd "$dir" && 'pwd';;
272		/*) echo $dir;;
273		*) cd "$dir" && 'pwd';;
274		esac
275		break
276	done
277}
278
279FindHereOrAbove() {
280    (
281	_t=-s
282	while :
283	do
284		case "$1" in
285		-C) cd "$2"; shift; shift;;
286		-?) _t=$1; shift;;
287		*) break;;
288		esac
289	done
290	case "$1" in
291	/*)	# we shouldn't be here
292		[ $_t "$1" ] && echo "$1"
293		return
294		;;
295	.../*) want=`echo "$1" | sed 's,^.../*,,'`;;
296	*) want="$1";;
297	esac
298	here=`'pwd'`
299	while :
300	do
301		if [ $_t "./$want" ]; then
302			echo "$here/$want"
303			return
304		fi
305		cd ..
306		here=`'pwd'`
307		case "$here" in
308		/) return;;
309		esac
310	done
311    )
312}
313
314# is $1 missing from $2 (or PATH) ?
315no_path() {
316	eval "__p=\$${2:-PATH}"
317	case ":$__p:" in *:"$1":*) return 1;; *) return 0;; esac
318}
319
320# if $1 exists and is not in path, append it
321add_path () {
322	case "$1" in
323	-?) t=$1; shift;;
324	*) t=-d;;
325	esac
326	case "$2,$1" in
327	MAKESYSPATH,.../*) ;;
328	*) [ $t ${1:-.} ] || return;;
329	esac
330	no_path $* && eval ${2:-PATH}="$__p${__p:+:}$1"
331}
332
333
334srcdir=`GetDir /bmake make-bootstrap.sh.in "$srcdir" "$2" "$Mydir" ./bmake* "$Mydir"/../bmake*`
335[ -d "${srcdir:-/dev/null}" ] || Usage
336case "$mksrc" in
337none|-) # we ignore this now
338	mksrc=$Mydir/mk
339	;;
340.../*)	# find here or above
341	mksrc=`FindHereOrAbove -C "$Mydir" -s "$mksrc/sys.mk"`
342	# that found a file
343	mksrc=`dirname $mksrc`
344	;;
345*)	# guess we want mksrc...
346	mksrc=`GetDir /mk sys.mk "$mksrc" "$3" ./mk* "$srcdir"/mk* "$srcdir"/../mk*`
347	[ -d "${mksrc:-/dev/null}" ] || Usage "Use '-m none' to build without mksrc"
348	;;
349esac
350
351# Ok, get to work...
352objdir="${objdir:-$OBJROOT$HOST_TARGET}"
353[ -d "$objdir" ] || mkdir -p "$objdir"
354[ -d "$objdir" ] || mkdir "$objdir"
355cd "$objdir" || exit 1
356# make it absolute
357objdir=`'pwd'`
358
359ShareDir() {
360	case "/$1" in
361	/) [ -d /share ] || return;;
362	*/$HOST_TARGET)
363		if [ -d "$1/../share" ]; then
364			echo `dirname "$1"`/share
365			return
366		fi
367		;;
368	esac
369	echo $1/share
370}
371
372# make it easy to force prefix to use $HOST_TARGET
373: looking at "$prefix"
374case "$prefix" in
375*/host?target) prefix=`echo "$prefix" | sed "s,host.target,${HOST_TARGET},"`;;
376esac
377
378share_dir="${share_dir:-`ShareDir $prefix`}"
379
380AddConfigure --prefix= "$prefix"
381case "$CONFIGURE_ARGS" in
382*--with-*-sys-path*) ;; # skip
383*) [ "$share_dir" ] && AddConfigure --with-default-sys-path= "$share_dir/mk";;
384esac
385if [ "$mksrc" ]; then
386        AddConfigure --with-mksrc= "$mksrc"
387        # not all cc's support this
388        CFLAGS_MF= CFLAGS_MD=
389        export CFLAGS_MF CFLAGS_MD
390fi
391
392# this makes it easy to run the bmake we just built
393# the :tA dance is needed because 'pwd' and even /bin/pwd
394# may not give the same result as realpath().
395Bmake() {
396    (
397	    cd $Mydir &&
398	    MAKESYSPATH=$mksrc SRCTOP=$Mydir OBJTOP=$objdir \
399	    MAKEOBJDIR='${.CURDIR:S,${SRCTOP:tA},${OBJTOP:tA},}' \
400	    ${BMAKE:-$objdir/bmake} -f $Mydir/Makefile "$@"
401    )
402}
403
404# there is actually a shell where type is not a builtin
405# if type is missing, which(1) had better exists!
406if (type cat) > /dev/null 2>&1; then
407which() {
408        type "$@" | sed 's,[()],,g;s,^[^/][^/]*,,;q'
409}
410fi
411# make sure test below uses the same diff that configure did
412TOOL_DIFF=`which diff`
413export TOOL_DIFF
414
415op_configure() {
416	$srcdir/configure $CONFIGURE_ARGS || exit 1
417}
418
419op_build() {
420	[ -s make-bootstrap.sh ] || op_configure
421	chmod 755 make-bootstrap.sh || exit 1
422	./make-bootstrap.sh || exit 1
423	case "$op" in
424	build) op_test;;
425	esac
426}
427
428op_test() {
429	[ -x bmake ] || op_build
430	Bmake test || exit 1
431}
432
433op_clean() {
434	if [ -x bmake ]; then
435		ln bmake bmake$$
436		BMAKE=$objdir/bmake$$ Bmake clean
437		rm -f bmake$$
438	elif [ $objdir != $srcdir ]; then
439		rm -rf *
440	fi
441}
442
443op_install() {
444	op_test
445	case "$INSTALL_PREFIX,$INSTALL_BIN,$prefix" in
446	,$HOST_TARGET/bin,*/$HOST_TARGET)
447		INSTALL_PREFIX=`dirname $prefix`
448		;;
449	esac
450	INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
451	Bmake install prefix=$INSTALL_PREFIX BINDIR=$INSTALL_PREFIX/${INSTALL_BIN:-bin} ${INSTALL_DESTDIR:+DESTDIR=$INSTALL_DESTDIR} $INSTALL_ARGS || exit 1
452}
453
454op_all() {
455	rm -f make-bootstrap.sh bmake *.o
456	if [ -n "$INSTALL_PREFIX" ]; then
457		op_install
458	else
459		op_test
460		MAKE_VERSION=`sed -n '/^_MAKE_VERSION/ { s,.*=  *,,;p; }' $srcdir/Makefile`
461		cat << EOM
462You can install by running:
463
464$0 $cmd_args op=install
465
466Use --install-prefix=/something to install somewhere other than $prefix
467Use --install-destdir=/somewhere to set DESTDIR during install
468Use --install-host-target to use INSTALL_BIN=$HOST_TARGET/bin
469Use -DWITH_PROG_VERSION to install as bmake-$MAKE_VERSION
470Use -DWITHOUT_PROG_LINK to suppress bmake -> bmake-$MAKE_VERSION symlink
471Use -DWITHOUT_INSTALL_MK to skip installing files to $prefix/share/mk
472EOM
473	fi
474	cat << EOM
475
476Note: bmake.cat1 contains ANSI escape sequences.
477You may need the -r or -R option to more/less to view it correctly.
478
479EOM
480}
481
482op_$op
483exit 0
484