xref: /freebsd/targets/pseudo/bootstrap-packages/bootstrap-packages.sh (revision 2bdd404abe2cdf9f52ddc45202afbde637f97292)
1#!/bin/sh
2
3# SPDX-License-Identifier: BSD-2-Clause
4
5# Our input is the output of something like:
6#
7#	(cd ${SRCTOP} &&
8#	find *bin etc lib* -name Makefile |
9#	xargs grep '^PACKAGE[[:space:]]*=' )
10#
11# With some cleanup and looks like:
12#
13#	usr.bin/ofed/libibverbs/Makefile:PACKAGE=FreeBSD-rdma
14#	usr.bin/last/Makefile:PACKAGE=acct
15#	usr.bin/lastcomm/Makefile:PACKAGE=acct
16#	usr.bin/users/Makefile:PACKAGE=acct
17#	usr.bin/who/Makefile:PACKAGE=acct
18#	usr.sbin/ac/Makefile:PACKAGE=acct
19#	usr.sbin/accton/Makefile:PACKAGE=acct
20#	usr.sbin/lastlogin/Makefile:PACKAGE=acct
21#	..
22#
23# which we use to populate $PACKAGES/*/Makefile.depend
24# and $PACKAGES/Makefile.depend to make it easier to keep
25# Makefile.depend files throughout the tree up-to-date.
26#
27# We attempt to handle MK_* knobs that impact DIRDEPS, by
28# identifying the intermediate *bin and *lib Makefiles and
29# checking if they had a subdir for the current reldir via a construct
30# like:
31#
32# 	SUBDIR.${MK_OPT}+= sub
33#
34# in which case we extract the option OPT and add the reldir
35# to a Makefile.depend.options file in targets/packages/sub/
36#
37# Of course the above is only *one* way optional SUBDIRs are handled
38# in the tree.  We also attempt to handle:
39#
40#	.if ${MK_OPT} == "yes"
41#	SUBDIR+= sub
42#	.endif
43#
44
45Mydir=`dirname $0`
46
47SKIP_LOG=return
48
49while :
50do
51    case "$1" in
52    *=*) eval "$1"; shift;;
53    -v) SKIP_LOG=:; shift;;
54    *) break;;
55    esac
56done
57
58to_reldir() {
59    sed "s,$SRCTOP/,,"
60}
61
62SRCTOP=${SRCTOP:-$(realpath $Mydir/../../..)}
63. ${SRCTOP}/libexec/rc/debug.sh
64DebugOn bootstrap-packages
65
66PACKAGES=${PACKAGES:-$(realpath $Mydir/../..)}
67case "$PACKAGES" in
68/*) ;;
69*) PACKAGES=$SRCTOP/$PACKAGES;;
70esac
71
72script_name=$(realpath $0 | to_reldir)
73
74log() {
75    $SKIP_LOG 0
76    echo $1 | to_reldir >&2
77}
78
79start_depend() {
80    depfile=$1
81
82    log $1
83    mkdir -p ${depfile%/*}
84    cat <<EOF > $depfile
85# Generated by $script_name
86
87DIRDEPS= \\
88EOF
89}
90
91end_depend() {
92    end_options $1.options
93    cat <<EOF >> $1
94
95.include <dirdeps.mk>
96EOF
97}
98
99start_options() {
100    ofile=$1
101
102    log $1
103    mkdir -p ${ofile%/*}
104    opts=$opt
105    eq==
106    cat <<EOF > $ofile
107# Generated by $script_name
108
109DIRDEPS_OPTIONS= $opt
110EOF
111}
112
113end_options() {
114    test -s $1 || return
115    cat <<EOF >> $1
116
117.include <dirdeps-options.mk>
118EOF
119}
120
121find_opt() {
122    mf=$1
123    sub=$2
124    shift 2
125    case "$sub" in
126    *+*) sub=`echo "$sub" | sed 's,+,\\\\+,g'`;;
127    esac
128    egrep "$@" "^[^#].*[[:space:]]$sub([[:space:]]|\$)" $mf |
129    tr '{' '\n' |
130    sed -n 's,^MK_\([^}]*\).*,\1,p' |
131    tr '\n' ' '
132}
133
134start_depend $PACKAGES/Makefile.depend || exit 1
135sort -t= -k2 "$@" | sed 's,/Makefile:PACKAGE=, ,' |
136(
137    lpackage=
138    while read reldir package
139    do
140	# use these below
141	dname=${reldir%/*}
142	bname=${reldir##*/}
143	# check parent does not have it commented out
144	# otherwise we should ignore it.
145	pmf=$SRCTOP/$dname/Makefile
146	egrep -q "^[^#].*[[:space:]]$bname([[:space:]]|\$)" $pmf || continue
147	: reldir=$reldir
148	case "$reldir" in
149	*lib/*) sub=${reldir#*lib/};;
150	*bin/*) sub=${reldir#*bin/};;
151	*libexec/*) sub=${reldir#*libexec/};;
152	*) opt= sub=;;
153	esac
154	if [ -n "$sub" ]; then
155	    smf=${SRCTOP}/${reldir%/$sub}/Makefile
156	    # now we need just the immediate subdir
157	    sub=${sub%%/*}
158	    # SUBDIR.${MK_OPT}+= sub
159	    opt=`find_opt $smf $sub`
160	    # .if ${MK_OPT} == "yes"
161	    # SUBDIR+= sub
162	    opt=${opt:-`find_opt $smf $sub -B2`}
163	fi
164	case "$reldir" in
165	*/tests|*/tests/*) opt=${opt:-TESTS};;
166	esac
167	# PACKAGES is set to either a simple string like 'runtime'
168	# or for some libraries 'lib${LIB}'
169	# or even 'lib${LIB:tl}' when LIB contains upper case
170	# the majority of libs in FreeBSD use lib${LIB} for their dirname
171	# but we allow for just ${LIB} too.
172	: package=$package
173	case "$package" in \
174	lib?{LIB*) package=`echo lib${bname#lib} | tr 'A-Z' 'a-z'`;;
175	esac
176	if test "$package" != "$lpackage"; then \
177	    test -z "$lpackage" || end_depend $ddeps
178	    target=$PACKAGES/$package
179	    ddeps=$target/Makefile.depend
180	    odeps=$ddeps.options
181	    rm -f $odeps
182	    start_depend $ddeps
183	    lpackage=$package
184	    echo "	$target \\"
185	fi
186	if [ -n "$opt" ]; then
187	    [ -s $odeps ] || start_options $odeps
188	    {
189		case " $opts " in
190		*" $opt "*) ;;
191		*)  echo DIRDEPS_OPTIONS+= $opt
192		    opts="$opts $opt"
193		    eq==
194		    ;;
195		esac
196		for o in $opt
197		do
198		    echo DIRDEPS.$o.yes$eq $reldir
199		done
200		eq=+=
201	    } >> $odeps
202	else
203	    echo "	$reldir \\" >> $ddeps
204	fi
205    done
206    end_depend $ddeps
207) | to_reldir >> $PACKAGES/Makefile.depend
208end_depend $PACKAGES/Makefile.depend
209