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