1236769Sobrien:
2236769Sobrien# NAME:
3236769Sobrien#	boot-strap
4236769Sobrien#
5236769Sobrien# SYNOPSIS:
6246223Ssjg#	boot-strap ["options"]
7246223Ssjg#	boot-strap --prefix=/opt --install
8246223Ssjg#	boot-strap --prefix=$HOME --install-host-target -DWITH_PROG_VERSION
9246223Ssjg#	boot-strap ["options"] op=build
10246223Ssjg#	boot-strap ["options"] op=install
11236769Sobrien#
12236769Sobrien# DESCRIPTION:
13236769Sobrien#	This script is used to configure/build bmake it builds for
14246223Ssjg#	each host-target in a different subdir to keep the src clean.
15246223Ssjg#	There is no requirement for an existing make(1).
16236769Sobrien#
17246223Ssjg#	On successful completion if no '--install' flag is given,
18246223Ssjg#	it echos a command to do installation.
19246223Ssjg#
20246223Ssjg#	The variable "op" defaults to 'all', and is affected by
21246223Ssjg#	'--install' flag as above.
22246223Ssjg#	Other values include:
23246223Ssjg#
24246223Ssjg#	configure
25246223Ssjg#		Just run 'configure'
26246223Ssjg#
27246223Ssjg#	build
28246223Ssjg#		If 'configure' has not been done, do it, then
29246223Ssjg#		run the build script, and finally 'test'.
30246223Ssjg#
31246223Ssjg#	install
32246223Ssjg#		If 'build' has not been done, do it, 'test' then
33246223Ssjg#		install. 
34246223Ssjg#
35246223Ssjg#	clean
36246223Ssjg#		attempt to clean up
37246223Ssjg#
38246223Ssjg#	test
39246223Ssjg#		run the unit-tests.  Done automatically after 'build'
40246223Ssjg#		and before 'install'.
41246223Ssjg#
42246223Ssjg#	The above are leveraged by a trivial makefile for the benefit
43246223Ssjg#	of those that have './configure; make; make install' baked
44246223Ssjg#	into them.
45246223Ssjg#	
46236769Sobrien#	Options:
47236769Sobrien#
48236769Sobrien#	-c "rc"
49236769Sobrien#		Pick up settings from "rc".  
50236769Sobrien#		We look for '.bmake-boot-strap.rc' before processing
51246223Ssjg#		options (unless SKIP_RC is set in environment).
52236769Sobrien#
53236769Sobrien#	--share "share_dir"
54236769Sobrien#		Where to put man pages and mk files.
55236769Sobrien#		If $prefix ends in $HOST_TARGET, and $prefix/../share
56236769Sobrien#		exits, the default will be that rather than $prefix/share.
57236769Sobrien#
58236769Sobrien#	--mksrc "mksrc"
59236769Sobrien#		Indicate where the mk files can be found.
60246223Ssjg#		Default is $Mydir/mk
61236769Sobrien#
62246223Ssjg#	--install
63246223Ssjg#		If build and test work, run bmake install.
64246223Ssjg#		BINDIR=$prefix/bin
65246223Ssjg#		SHAREDIR=$prefix/share
66246223Ssjg#
67246223Ssjg#	--install-host-target
68246223Ssjg#		As for '--install' but BINDIR=$prefix/$HOST_TARGET/bin
69246223Ssjg#		This is useful when $prefix/ is shared by multiple
70246223Ssjg#		machines.
71246223Ssjg#
72246223Ssjg#	Flags relevant when installing:
73246223Ssjg#
74246223Ssjg#	-DWITHOUT_INSTALL_MK
75246223Ssjg#		Skip installing mk files.
76246223Ssjg#		By default they will be installed to $prefix/share/mk
77246223Ssjg#
78246223Ssjg#	-DWITH_PROG_VERSION
79246223Ssjg#		Install 'bmake' as 'bmake-$MAKE_VERSION'
80246223Ssjg#		A symlink will be made as 'bmake' unless
81246223Ssjg#		-DWITHOUT_PROG_LINK is set.
82246223Ssjg#
83236769Sobrien#	Possibly useful configure_args:
84236769Sobrien#
85236769Sobrien#	--without-meta
86236769Sobrien#		disable use of meta mode.
87236769Sobrien#
88236769Sobrien#	--without-filemon
89236769Sobrien#		disable use of filemon(9) which is currently only
90236769Sobrien#		available for NetBSD and FreeBSD.
91236769Sobrien#
92236769Sobrien#	--with-filemon="path/to/filemon.h"
93236769Sobrien#		enables use of filemon(9) by meta mode.
94236769Sobrien#		
95236769Sobrien#	--with-machine="machine"
96236769Sobrien#		set "machine" to override that determined by
97236769Sobrien#		machine.sh
98236769Sobrien#	
99236769Sobrien#	--with-force-machine="machine"
100236769Sobrien#		force "machine" even if uname(3) provides a value.
101236769Sobrien#
102236769Sobrien#	--with-machine_arch="machine_arch"
103236769Sobrien#		set "machine_arch" to override that determined by
104236769Sobrien#		machine.sh
105236769Sobrien#
106236769Sobrien#	--with-default-sys-path="syspath"
107236769Sobrien#		set an explicit default "syspath" which is where bmake
108236769Sobrien#		will look for sys.mk and friends.
109236769Sobrien#
110236769Sobrien# AUTHOR:
111236769Sobrien#	Simon J. Gerraty <sjg@crufty.net>
112236769Sobrien
113236769Sobrien# RCSid:
114321964Ssjg#	$Id: boot-strap,v 1.49 2016/05/29 00:09:14 sjg Exp $
115236769Sobrien#
116236769Sobrien#	@(#) Copyright (c) 2001 Simon J. Gerraty
117236769Sobrien#
118236769Sobrien#	This file is provided in the hope that it will
119236769Sobrien#	be of use.  There is absolutely NO WARRANTY.
120236769Sobrien#	Permission to copy, redistribute or otherwise
121236769Sobrien#	use this file is hereby granted provided that 
122236769Sobrien#	the above copyright notice and this notice are
123236769Sobrien#	left intact. 
124236769Sobrien#      
125236769Sobrien#	Please send copies of changes and bug-fixes to:
126236769Sobrien#	sjg@crufty.net
127236769Sobrien#
128236769Sobrien
129236769SobrienMydir=`dirname $0`
130236769Sobrien. "$Mydir/os.sh"
131236769Sobriencase "$Mydir" in
132236769Sobrien/*) ;;
133236769Sobrien*) Mydir=`cd "$Mydir" && 'pwd'`;;
134236769Sobrienesac
135236769Sobrien
136236769SobrienUsage() {
137236769Sobrien	[ "$1" ] && echo "ERROR: $@" >&2
138236769Sobrien	echo "Usage:" >&2
139246223Ssjg	echo "$0 [--<configure_arg> ...][<prefix>][--install]" >&2
140236769Sobrien	exit 1
141236769Sobrien}
142236769Sobrien
143236769SobrienError() {
144236769Sobrien	echo "ERROR: $@" >&2
145236769Sobrien	exit 1
146236769Sobrien}
147236769Sobrien
148236769Sobriensource_rc() {
149236769Sobrien	rc="$1"; shift
150236769Sobrien	for d in ${*:-""}
151236769Sobrien	do
152236769Sobrien		r="${d:+$d/}$rc"
153236769Sobrien		[ -f "$r" -a -s "$r" ] || continue
154236769Sobrien		echo "NOTE: reading $r"
155236769Sobrien		. "$r"
156236769Sobrien		break
157236769Sobrien	done
158236769Sobrien}
159236769Sobrien
160246223Ssjgcmd_args="$@"
161246223Ssjg
162249033Ssjg# clear some things from the environment that we care about
163249033Ssjgunset MAKEOBJDIR MAKEOBJDIRPREFIX
164249033Ssjg
165246223Ssjg# --install[-host-target] will set this
166246223SsjgINSTALL_PREFIX=
167246223Ssjg# other things we pass to install step
168246223SsjgINSTALL_ARGS=
169236769SobrienCONFIGURE_ARGS=
170236769SobrienMAKESYSPATH=
171236769Sobrien# pick a useful default prefix (for me at least ;-)
172236769Sobrienfor prefix in /opt/$HOST_TARGET "$HOME/$HOST_TARGET" /usr/pkg /usr/local ""
173236769Sobriendo
174246223Ssjg	[ -d "${prefix:-.}" ] || continue
175246223Ssjg	case "$prefix" in
176246223Ssjg	*/$HOST_TARGET)
177246223Ssjg		p=`dirname $prefix`
178246223Ssjg		if [ -d $p/share ]; then
179246223Ssjg			INSTALL_BIN=$HOST_TARGET/bin
180246223Ssjg			prefix=$p
181246223Ssjg		fi
182246223Ssjg		;;
183246223Ssjg	esac
184246223Ssjg        echo "NOTE: default prefix=$prefix ${INSTALL_BIN:+INSTALL_BIN=$INSTALL_BIN}"
185246223Ssjg	break
186236769Sobriendone
187246223Ssjgsrcdir=$Mydir
188246223Ssjgmksrc=$Mydir/mk
189236769Sobrienobjdir=
190236769Sobrienquiet=:
191236769Sobrien
192246223Ssjg${SKIP_RC:+:} source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME"
193236769Sobrien
194236769Sobrienget_optarg() {
195236769Sobrien	expr "x$1" : "x[^=]*=\\(.*\\)"
196236769Sobrien}
197236769Sobrien
198246223Ssjghere=`'pwd'`
199246223Ssjgif [ $here = $Mydir ]; then
200276305Sngie   # avoid pollution
201246223Ssjg   OBJROOT=../
202246223Ssjgfi
203246223Ssjg
204246223Ssjgop=all
205246223SsjgBMAKE=
206246223Ssjg
207236769Sobrienwhile :
208236769Sobriendo
209236769Sobrien	case "$1" in
210236769Sobrien	--) shift; break;;
211246223Ssjg        --help) sed -n -e "1d;/RCSid/,\$d" -e '/^#\.[a-z]/d' -e '/^#/s,^# *,,p' $0; exit 0;;
212236769Sobrien	--prefix) prefix="$2"; shift;;
213236769Sobrien	--prefix=*) prefix=`get_optarg "$1"`;;
214236769Sobrien	--src=*) srcdir=`get_optarg "$1"`;;
215236769Sobrien	--with-mksrc=*|--mksrc=*) mksrc=`get_optarg "$1"`;;
216236769Sobrien	--share=*) share_dir=`get_optarg "$1"`;;
217236769Sobrien	--share) share_dir="$2"; shift;;
218236769Sobrien	--with-default-sys-path=*)
219276305Sngie	    CONFIGURE_ARGS="$1";;
220236769Sobrien	--with-default-sys-path)
221276305Sngie	    CONFIGURE_ARGS="$1 $2";;
222246223Ssjg	--install) INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix};;
223246223Ssjg	--install-host-target)
224246223Ssjg                INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
225246223Ssjg                INSTALL_BIN=$HOST_TARGET/bin;;
226246223Ssjg	--install-destdir=*) INSTALL_DESTDIR=`get_optarg "$1"`;;
227246223Ssjg	--install-prefix=*) INSTALL_PREFIX=`get_optarg "$1"`;;
228246223Ssjg	-DWITH*) INSTALL_ARGS="$INSTALL_ARGS $1";;
229236769Sobrien	-s|--src) srcdir="$2"; shift;;
230236769Sobrien	-m|--mksrc) mksrc="$2"; shift;;
231236769Sobrien	-o|--objdir) objdir="$2"; shift;;
232236769Sobrien	-q) quiet=;;
233236769Sobrien	-c) source_rc "$2"; shift;;
234236769Sobrien	--*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1";;
235236769Sobrien	*=*) eval "$1"; export `expr "x$1" : "x\\(.[^=]*\\)=.*"`;;
236236769Sobrien	*) break;;
237236769Sobrien	esac
238236769Sobrien        shift
239236769Sobriendone
240236769Sobrien
241236769SobrienAddConfigure() {
242236769Sobrien	case " $CONFIGURE_ARGS " in
243236769Sobrien	*" $1"*) ;;
244236769Sobrien	*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1$2";;
245236769Sobrien	esac
246236769Sobrien}
247236769Sobrien
248236769SobrienGetDir() {
249236769Sobrien	match="$1"
250236769Sobrien	shift
251236769Sobrien	fmatch="$1"
252236769Sobrien	shift
253236769Sobrien	for dir in $*
254236769Sobrien	do
255236769Sobrien		[ -d "$dir" ] || continue
256236769Sobrien		case "/$dir/" in
257236769Sobrien		*$match*) ;;
258236769Sobrien		*) continue;;
259236769Sobrien		esac
260236769Sobrien		case "$fmatch" in
261236769Sobrien		.) ;;
262236769Sobrien		*) [ -s $dir/$fmatch ] || continue;;
263236769Sobrien		esac
264236769Sobrien		case "$dir/" in
265236769Sobrien		*./*) cd "$dir" && 'pwd';;
266236769Sobrien		/*) echo $dir;;
267236769Sobrien		*) cd "$dir" && 'pwd';;
268236769Sobrien		esac
269236769Sobrien		break
270236769Sobrien	done
271236769Sobrien}
272236769Sobrien
273236769SobrienFindHereOrAbove() {
274236769Sobrien    (
275236769Sobrien	_t=-s
276236769Sobrien	while :
277236769Sobrien	do
278236769Sobrien		case "$1" in
279236769Sobrien		-C) cd "$2"; shift; shift;;
280236769Sobrien		-?) _t=$1; shift;;
281236769Sobrien		*) break;;
282236769Sobrien		esac
283236769Sobrien	done
284236769Sobrien	case "$1" in	
285236769Sobrien	/*)	# we shouldn't be here
286236769Sobrien		[ $_t "$1" ] && echo "$1"
287236769Sobrien		return
288236769Sobrien		;;
289236769Sobrien	.../*) want=`echo "$1" | sed 's,^.../*,,'`;;
290236769Sobrien	*) want="$1";;
291236769Sobrien	esac
292236769Sobrien	here=`'pwd'`
293236769Sobrien	while :
294236769Sobrien	do
295236769Sobrien		if [ $_t "./$want" ]; then
296236769Sobrien			echo "$here/$want"
297236769Sobrien			return
298236769Sobrien		fi
299236769Sobrien		cd ..
300236769Sobrien		here=`'pwd'`
301236769Sobrien		case "$here" in
302236769Sobrien		/) return;;
303236769Sobrien		esac
304236769Sobrien	done
305236769Sobrien    )
306236769Sobrien}
307236769Sobrien
308236769Sobrien# is $1 missing from $2 (or PATH) ?
309236769Sobrienno_path() {
310236769Sobrien	eval "__p=\$${2:-PATH}"
311236769Sobrien	case ":$__p:" in *:"$1":*) return 1;; *) return 0;; esac
312236769Sobrien}
313236769Sobrien
314236769Sobrien# if $1 exists and is not in path, append it
315236769Sobrienadd_path () {
316236769Sobrien	case "$1" in
317236769Sobrien	-?) t=$1; shift;;
318236769Sobrien	*) t=-d;;
319236769Sobrien	esac
320236769Sobrien	case "$2,$1" in
321236769Sobrien	MAKESYSPATH,.../*) ;;
322236769Sobrien	*) [ $t ${1:-.} ] || return;;
323236769Sobrien	esac
324236769Sobrien	no_path $* && eval ${2:-PATH}="$__p${__p:+:}$1"
325236769Sobrien}
326236769Sobrien
327236769Sobrien
328236769Sobriensrcdir=`GetDir /bmake make-bootstrap.sh.in "$srcdir" "$2" "$Mydir" ./bmake* "$Mydir"/../bmake*`
329236769Sobrien[ -d "${srcdir:-/dev/null}" ] || Usage
330236769Sobriencase "$mksrc" in
331276305Sngienone|-) # we ignore this now
332276305Sngie	mksrc=$Mydir/mk
333236769Sobrien	;;
334236769Sobrien.../*)	# find here or above
335236769Sobrien	mksrc=`FindHereOrAbove -C "$Mydir" -s "$mksrc/sys.mk"`
336236769Sobrien	# that found a file
337236769Sobrien	mksrc=`dirname $mksrc`
338236769Sobrien	;;
339236769Sobrien*)	# guess we want mksrc...
340236769Sobrien	mksrc=`GetDir /mk sys.mk "$mksrc" "$3" ./mk* "$srcdir"/mk* "$srcdir"/../mk*`
341236769Sobrien	[ -d "${mksrc:-/dev/null}" ] || Usage "Use '-m none' to build without mksrc"
342236769Sobrien	;;
343236769Sobrienesac
344236769Sobrien
345236769Sobrien# Ok, get to work...
346246223Ssjgobjdir="${objdir:-$OBJROOT$HOST_TARGET}"
347236769Sobrien[ -d "$objdir" ] || mkdir -p "$objdir"
348236769Sobrien[ -d "$objdir" ] || mkdir "$objdir"
349236769Sobriencd "$objdir" || exit 1
350236769Sobrien# make it absolute
351236769Sobrienobjdir=`'pwd'`
352236769Sobrien
353236769SobrienShareDir() {
354236769Sobrien	case "/$1" in
355236769Sobrien	/) [ -d /share ] || return;;
356236769Sobrien	*/$HOST_TARGET)
357236769Sobrien		if [ -d "$1/../share" ]; then
358236769Sobrien			echo `dirname "$1"`/share
359236769Sobrien			return
360236769Sobrien		fi
361236769Sobrien		;;
362236769Sobrien	esac
363236769Sobrien	echo $1/share
364236769Sobrien}
365236769Sobrien
366236769Sobrien# make it easy to force prefix to use $HOST_TARGET
367236769Sobrien: looking at "$prefix"
368236769Sobriencase "$prefix" in
369236769Sobrien*/host?target) prefix=`echo "$prefix" | sed "s,host.target,${HOST_TARGET},"`;;
370236769Sobrienesac
371236769Sobrien
372236769Sobrienshare_dir="${share_dir:-`ShareDir $prefix`}"
373236769Sobrien
374236769SobrienAddConfigure --prefix= "$prefix"
375236769Sobriencase "$CONFIGURE_ARGS" in
376236769Sobrien*--with-*-sys-path*) ;; # skip
377236769Sobrien*) [ "$share_dir" ] && AddConfigure --with-default-sys-path= "$share_dir/mk";;
378236769Sobrienesac
379236769Sobrienif [ "$mksrc" ]; then
380236769Sobrien        AddConfigure --with-mksrc= "$mksrc"
381236769Sobrien        # not all cc's support this
382236769Sobrien        CFLAGS_MF= CFLAGS_MD=
383236769Sobrien        export CFLAGS_MF CFLAGS_MD
384236769Sobrienfi
385236769Sobrien
386246223Ssjg# this makes it easy to run the bmake we just built
387246223Ssjg# the :tA dance is needed because 'pwd' and even /bin/pwd
388246223Ssjg# may not give the same result as realpath().
389246223SsjgBmake() {
390246223Ssjg    (
391246223Ssjg	    cd $Mydir &&
392246223Ssjg	    MAKESYSPATH=$mksrc SRCTOP=$Mydir OBJTOP=$objdir \
393246223Ssjg	    MAKEOBJDIR='${.CURDIR:S,${SRCTOP:tA},${OBJTOP:tA},}' \
394246223Ssjg	    ${BMAKE:-$objdir/bmake} -f $Mydir/Makefile "$@"
395246223Ssjg    )
396246223Ssjg}
397246223Ssjg
398292068Ssjg# there is actually a shell where type is not a builtin
399292068Ssjg# if type is missing, which(1) had better exists!
400292068Ssjgif (type cat) > /dev/null 2>&1; then
401292068Ssjgwhich() {
402292068Ssjg        type "$@" | sed 's,[()],,g;s,^[^/][^/]*,,;q'
403292068Ssjg}
404292068Ssjgfi
405236769Sobrien# make sure test below uses the same diff that configure did
406292068SsjgTOOL_DIFF=`which diff`
407246223Ssjgexport TOOL_DIFF
408236769Sobrien
409246223Ssjgop_configure() {
410246223Ssjg	$srcdir/configure $CONFIGURE_ARGS || exit 1
411246223Ssjg}
412236769Sobrien
413246223Ssjgop_build() {
414246223Ssjg	[ -s make-bootstrap.sh ] || op_configure
415246223Ssjg	chmod 755 make-bootstrap.sh || exit 1
416246223Ssjg	./make-bootstrap.sh || exit 1
417246223Ssjg	case "$op" in
418246223Ssjg	build) op_test;;
419246223Ssjg	esac
420246223Ssjg}
421236769Sobrien
422246223Ssjgop_test() {
423246223Ssjg	[ -x bmake ] || op_build
424246223Ssjg	Bmake test || exit 1
425246223Ssjg}
426246223Ssjg
427246223Ssjgop_clean() {
428246223Ssjg	if [ -x bmake ]; then
429246223Ssjg		ln bmake bmake$$
430246223Ssjg		BMAKE=$objdir/bmake$$ Bmake clean
431246223Ssjg		rm -f bmake$$
432246223Ssjg	elif [ $objdir != $srcdir ]; then
433246223Ssjg		rm -rf *
434236769Sobrien	fi
435236769Sobrien}
436236769Sobrien
437246223Ssjgop_install() {
438246223Ssjg	op_test
439246223Ssjg	case "$INSTALL_PREFIX,$INSTALL_BIN,$prefix" in
440246223Ssjg	,$HOST_TARGET/bin,*/$HOST_TARGET)
441246223Ssjg		INSTALL_PREFIX=`dirname $prefix`
442246223Ssjg		;;
443246223Ssjg	esac
444246223Ssjg	INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
445246223Ssjg	Bmake install prefix=$INSTALL_PREFIX BINDIR=$INSTALL_PREFIX/${INSTALL_BIN:-bin} ${INSTALL_DESTDIR:+DESTDIR=$INSTALL_DESTDIR} $INSTALL_ARGS || exit 1
446246223Ssjg}
447236769Sobrien
448246223Ssjgop_all() {
449246223Ssjg	rm -f make-bootstrap.sh bmake *.o
450246223Ssjg	if [ -n "$INSTALL_PREFIX" ]; then
451246223Ssjg		op_install
452246223Ssjg	else
453246223Ssjg		op_test
454321964Ssjg		MAKE_VERSION=`sed -n '/^_MAKE_VERSION/ { s,.*=  *,,;p; }' $srcdir/Makefile`
455246223Ssjg		echo You can install by running:
456246223Ssjg		echo
457246223Ssjg		echo $0 $cmd_args op=install
458246223Ssjg		echo
459246223Ssjg		echo "Use --install-prefix=/something to install somewhere other than $prefix"
460246223Ssjg		echo "Use --install-destdir=/somewhere to set DESTDIR during install"
461246223Ssjg		echo "Use --install-host-target to use INSTALL_BIN=$HOST_TARGET/bin"
462246223Ssjg		echo "Use -DWITH_PROG_VERSION to install as bmake-$MAKE_VERSION"
463276305Sngie		echo "Use -DWITHOUT_PROG_LINK to suppress bmake -> bmake-$MAKE_VERSION symlink"
464246223Ssjg		echo "Use -DWITHOUT_INSTALL_MK to skip installing files to $prefix/share/mk"
465246223Ssjg	fi
466246223Ssjg}
467246223Ssjg
468246223Ssjgop_$op
469246223Ssjgexit 0
470