1125208Sache:
2125208Sache# NAME:
3125208Sache#	boot-strap
4125208Sache#
5125208Sache# SYNOPSIS:
6125208Sache#	boot-strap ["options"]
7125208Sache#	boot-strap --prefix=/opt --install
8125208Sache#	boot-strap --prefix=$HOME --install-host-target -DWITH_PROG_VERSION
9125208Sache#	boot-strap ["options"] op=build
10125208Sache#	boot-strap ["options"] op=install
11125208Sache#
12125208Sache# 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="path/to/filemon.h"
93#		enables use of filemon(9) by meta mode.
94#		
95#	--with-machine="machine"
96#		set "machine" to override that determined by
97#		machine.sh
98#	
99#	--with-force-machine="machine"
100#		force "machine" even if uname(3) provides a value.
101#
102#	--with-machine_arch="machine_arch"
103#		set "machine_arch" to override that determined by
104#		machine.sh
105#
106#	--with-default-sys-path="syspath"
107#		set an explicit default "syspath" which is where bmake
108#		will look for sys.mk and friends.
109#
110# AUTHOR:
111#	Simon J. Gerraty <sjg@crufty.net>
112
113# RCSid:
114#	$Id: boot-strap,v 1.43 2013/03/02 18:55:23 sjg Exp $
115#
116#	@(#) Copyright (c) 2001 Simon J. Gerraty
117#
118#	This file is provided in the hope that it will
119#	be of use.  There is absolutely NO WARRANTY.
120#	Permission to copy, redistribute or otherwise
121#	use this file is hereby granted provided that 
122#	the above copyright notice and this notice are
123#	left intact. 
124#      
125#	Please send copies of changes and bug-fixes to:
126#	sjg@crufty.net
127#
128
129Mydir=`dirname $0`
130. "$Mydir/os.sh"
131case "$Mydir" in
132/*) ;;
133*) Mydir=`cd "$Mydir" && 'pwd'`;;
134esac
135
136Usage() {
137	[ "$1" ] && echo "ERROR: $@" >&2
138	echo "Usage:" >&2
139	echo "$0 [--<configure_arg> ...][<prefix>][--install]" >&2
140	exit 1
141}
142
143Error() {
144	echo "ERROR: $@" >&2
145	exit 1
146}
147
148source_rc() {
149	rc="$1"; shift
150	for d in ${*:-""}
151	do
152		r="${d:+$d/}$rc"
153		[ -f "$r" -a -s "$r" ] || continue
154		echo "NOTE: reading $r"
155		. "$r"
156		break
157	done
158}
159
160cmd_args="$@"
161
162# clear some things from the environment that we care about
163unset MAKEOBJDIR MAKEOBJDIRPREFIX
164
165# --install[-host-target] will set this
166INSTALL_PREFIX=
167# other things we pass to install step
168INSTALL_ARGS=
169CONFIGURE_ARGS=
170MAKESYSPATH=
171# pick a useful default prefix (for me at least ;-)
172for prefix in /opt/$HOST_TARGET "$HOME/$HOST_TARGET" /usr/pkg /usr/local ""
173do
174	[ -d "${prefix:-.}" ] || continue
175	case "$prefix" in
176	*/$HOST_TARGET)
177		p=`dirname $prefix`
178		if [ -d $p/share ]; then
179			INSTALL_BIN=$HOST_TARGET/bin
180			prefix=$p
181		fi
182		;;
183	esac
184        echo "NOTE: default prefix=$prefix ${INSTALL_BIN:+INSTALL_BIN=$INSTALL_BIN}"
185	break
186done
187srcdir=$Mydir
188mksrc=$Mydir/mk
189objdir=
190quiet=:
191
192${SKIP_RC:+:} source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME"
193
194get_optarg() {
195	expr "x$1" : "x[^=]*=\\(.*\\)"
196}
197
198here=`'pwd'`
199if [ $here = $Mydir ]; then
200   # avoid polution
201   OBJROOT=../
202fi
203
204op=all
205BMAKE=
206
207while :
208do
209	case "$1" in
210	--) shift; break;;
211        --help) sed -n -e "1d;/RCSid/,\$d" -e '/^#\.[a-z]/d' -e '/^#/s,^# *,,p' $0; exit 0;;
212	--prefix) prefix="$2"; shift;;
213	--prefix=*) prefix=`get_optarg "$1"`;;
214	--src=*) srcdir=`get_optarg "$1"`;;
215	--with-mksrc=*|--mksrc=*) mksrc=`get_optarg "$1"`;;
216	--share=*) share_dir=`get_optarg "$1"`;;
217	--share) share_dir="$2"; shift;;
218	--with-default-sys-path=*)
219	    CONFIGURE_ARGS="$1"
220	    MAKESYSPATH=`get_optarg "$1"`;;
221	--with-default-sys-path)
222	    CONFIGURE_ARGS="$1 $2"
223	    MAKESYSPATH="$2"; shift;;
224	--install) INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix};;
225	--install-host-target)
226                INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
227                INSTALL_BIN=$HOST_TARGET/bin;;
228	--install-destdir=*) INSTALL_DESTDIR=`get_optarg "$1"`;;
229	--install-prefix=*) INSTALL_PREFIX=`get_optarg "$1"`;;
230	-DWITH*) INSTALL_ARGS="$INSTALL_ARGS $1";;
231	-s|--src) srcdir="$2"; shift;;
232	-m|--mksrc) mksrc="$2"; shift;;
233	-o|--objdir) objdir="$2"; shift;;
234	-q) quiet=;;
235	-c) source_rc "$2"; shift;;
236	--*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1";;
237	*=*) eval "$1"; export `expr "x$1" : "x\\(.[^=]*\\)=.*"`;;
238	*) break;;
239	esac
240        shift
241done
242
243AddConfigure() {
244	case " $CONFIGURE_ARGS " in
245	*" $1"*) ;;
246	*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1$2";;
247	esac
248}
249
250GetDir() {
251	match="$1"
252	shift
253	fmatch="$1"
254	shift
255	for dir in $*
256	do
257		[ -d "$dir" ] || continue
258		case "/$dir/" in
259		*$match*) ;;
260		*) continue;;
261		esac
262		case "$fmatch" in
263		.) ;;
264		*) [ -s $dir/$fmatch ] || continue;;
265		esac
266		case "$dir/" in
267		*./*) cd "$dir" && 'pwd';;
268		/*) echo $dir;;
269		*) cd "$dir" && 'pwd';;
270		esac
271		break
272	done
273}
274
275FindHereOrAbove() {
276    (
277	_t=-s
278	while :
279	do
280		case "$1" in
281		-C) cd "$2"; shift; shift;;
282		-?) _t=$1; shift;;
283		*) break;;
284		esac
285	done
286	case "$1" in	
287	/*)	# we shouldn't be here
288		[ $_t "$1" ] && echo "$1"
289		return
290		;;
291	.../*) want=`echo "$1" | sed 's,^.../*,,'`;;
292	*) want="$1";;
293	esac
294	here=`'pwd'`
295	while :
296	do
297		if [ $_t "./$want" ]; then
298			echo "$here/$want"
299			return
300		fi
301		cd ..
302		here=`'pwd'`
303		case "$here" in
304		/) return;;
305		esac
306	done
307    )
308}
309
310# is $1 missing from $2 (or PATH) ?
311no_path() {
312	eval "__p=\$${2:-PATH}"
313	case ":$__p:" in *:"$1":*) return 1;; *) return 0;; esac
314}
315
316# if $1 exists and is not in path, append it
317add_path () {
318	case "$1" in
319	-?) t=$1; shift;;
320	*) t=-d;;
321	esac
322	case "$2,$1" in
323	MAKESYSPATH,.../*) ;;
324	*) [ $t ${1:-.} ] || return;;
325	esac
326	no_path $* && eval ${2:-PATH}="$__p${__p:+:}$1"
327}
328
329
330srcdir=`GetDir /bmake make-bootstrap.sh.in "$srcdir" "$2" "$Mydir" ./bmake* "$Mydir"/../bmake*`
331[ -d "${srcdir:-/dev/null}" ] || Usage
332case "$mksrc" in
333none|-) # we don't want it
334	mksrc=
335	;;
336.../*)	# find here or above
337	mksrc=`FindHereOrAbove -C "$Mydir" -s "$mksrc/sys.mk"`
338	# that found a file
339	mksrc=`dirname $mksrc`
340	;;
341*)	# guess we want mksrc...
342	mksrc=`GetDir /mk sys.mk "$mksrc" "$3" ./mk* "$srcdir"/mk* "$srcdir"/../mk*`
343	[ -d "${mksrc:-/dev/null}" ] || Usage "Use '-m none' to build without mksrc"
344	;;
345esac
346
347# Ok, get to work...
348objdir="${objdir:-$OBJROOT$HOST_TARGET}"
349[ -d "$objdir" ] || mkdir -p "$objdir"
350[ -d "$objdir" ] || mkdir "$objdir"
351cd "$objdir" || exit 1
352# make it absolute
353objdir=`'pwd'`
354
355ShareDir() {
356	case "/$1" in
357	/) [ -d /share ] || return;;
358	*/$HOST_TARGET)
359		if [ -d "$1/../share" ]; then
360			echo `dirname "$1"`/share
361			return
362		fi
363		;;
364	esac
365	echo $1/share
366}
367
368# make it easy to force prefix to use $HOST_TARGET
369: looking at "$prefix"
370case "$prefix" in
371*/host?target) prefix=`echo "$prefix" | sed "s,host.target,${HOST_TARGET},"`;;
372esac
373
374share_dir="${share_dir:-`ShareDir $prefix`}"
375
376AddConfigure --prefix= "$prefix"
377case "$CONFIGURE_ARGS" in
378*--with-*-sys-path*) ;; # skip
379*) [ "$share_dir" ] && AddConfigure --with-default-sys-path= "$share_dir/mk";;
380esac
381if [ "$mksrc" ]; then
382        AddConfigure --with-mksrc= "$mksrc"
383        # not all cc's support this
384        CFLAGS_MF= CFLAGS_MD=
385        export CFLAGS_MF CFLAGS_MD
386fi
387
388# this makes it easy to run the bmake we just built
389# the :tA dance is needed because 'pwd' and even /bin/pwd
390# may not give the same result as realpath().
391Bmake() {
392    (
393	    cd $Mydir &&
394	    MAKESYSPATH=$mksrc SRCTOP=$Mydir OBJTOP=$objdir \
395	    MAKEOBJDIR='${.CURDIR:S,${SRCTOP:tA},${OBJTOP:tA},}' \
396	    ${BMAKE:-$objdir/bmake} -f $Mydir/Makefile "$@"
397    )
398}
399
400# make sure test below uses the same diff that configure did
401TOOL_DIFF=`type diff | sed 's,[()],,g;s,^[^/][^/]*,,;q'`
402export TOOL_DIFF
403
404op_configure() {
405	$srcdir/configure $CONFIGURE_ARGS || exit 1
406}
407
408op_build() {
409	[ -s make-bootstrap.sh ] || op_configure
410	chmod 755 make-bootstrap.sh || exit 1
411	./make-bootstrap.sh || exit 1
412	case "$op" in
413	build) op_test;;
414	esac
415}
416
417op_test() {
418	[ -x bmake ] || op_build
419	Bmake test || exit 1
420}
421
422op_clean() {
423	if [ -x bmake ]; then
424		ln bmake bmake$$
425		BMAKE=$objdir/bmake$$ Bmake clean
426		rm -f bmake$$
427	elif [ $objdir != $srcdir ]; then
428		rm -rf *
429	fi
430}
431
432op_install() {
433	op_test
434	case "$INSTALL_PREFIX,$INSTALL_BIN,$prefix" in
435	,$HOST_TARGET/bin,*/$HOST_TARGET)
436		INSTALL_PREFIX=`dirname $prefix`
437		;;
438	esac
439	INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
440	Bmake install prefix=$INSTALL_PREFIX BINDIR=$INSTALL_PREFIX/${INSTALL_BIN:-bin} ${INSTALL_DESTDIR:+DESTDIR=$INSTALL_DESTDIR} $INSTALL_ARGS || exit 1
441}
442
443op_all() {
444	rm -f make-bootstrap.sh bmake *.o
445	if [ -n "$INSTALL_PREFIX" ]; then
446		op_install
447	else
448		op_test
449		MAKE_VERSION=`sed -n '/^MAKE_VERSION/ { s,.*=  *,,;p; }' $srcdir/Makefile`
450		echo You can install by running:
451		echo
452		echo $0 $cmd_args op=install
453		echo
454		echo "Use --install-prefix=/something to install somewhere other than $prefix"
455		echo "Use --install-destdir=/somewhere to set DESTDIR during install"
456		echo "Use --install-host-target to use INSTALL_BIN=$HOST_TARGET/bin"
457		echo "Use -DWITH_PROG_VERSION to install as bmake-$MAKE_VERSION"
458		echo "Use -DWITHOUT_PROG_LINK to supress bmake -> bmake-$MAKE_VERSION symlink"
459		echo "Use -DWITHOUT_INSTALL_MK to skip installing files to $prefix/share/mk"
460	fi
461}
462
463op_$op
464exit 0
465