xref: /freebsd/targets/pseudo/bootstrap-packages/bootstrap-packages.sh (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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
121no_plus() {
122    case "$1" in
123    *+*) echo "$1" | sed 's,+,\\\\+,g';;
124    *) echo "$1";;
125    esac
126}
127
128find_opt() {
129    mf=$1
130    sub="`no_plus $2`"
131    shift 2
132    egrep "$@" "^[^#].*[[:space:]]$sub([[:space:]]|\$)" $mf |
133    tr '{' '\n' |
134    sed -n 's,^MK_\([^}]*\).*,\1,p' |
135    tr '\n' ' '
136}
137
138start_depend $PACKAGES/Makefile.depend || exit 1
139sort -t= -k2 "$@" | sed 's,/Makefile:PACKAGE=, ,' |
140(
141    lpackage=
142    while read reldir package
143    do
144	# use these below
145	dname=${reldir%/*}
146	bname=${reldir##*/}
147	# check parent does not have it commented out
148	# otherwise we should ignore it.
149	# if the parent makefile does not exist, we will skip it.
150	pmf=$SRCTOP/$dname/Makefile
151	egrep -q "^[^#].*[[:space:]]`no_plus $bname`([[:space:]]|\$)" $pmf 2> /dev/null || continue
152	: reldir=$reldir
153	case "$reldir" in
154	*lib/*) sub=${reldir#*lib/};;
155	*bin/*) sub=${reldir#*bin/};;
156	*libexec/*) sub=${reldir#*libexec/};;
157	*) opt= sub=;;
158	esac
159	if [ -n "$sub" ]; then
160	    smf=${SRCTOP}/${reldir%/$sub}/Makefile
161	    # now we need just the immediate subdir
162	    sub=${sub%%/*}
163	    # SUBDIR.${MK_OPT}+= sub
164	    opt=`find_opt $smf $sub`
165	    # .if ${MK_OPT} == "yes"
166	    # SUBDIR+= sub
167	    opt=${opt:-`find_opt $smf $sub -B2`}
168	fi
169	case "$reldir" in
170	*/tests|*/tests/*) opt=${opt:-TESTS};;
171	esac
172	# PACKAGES is set to either a simple string like 'runtime'
173	# or for some libraries 'lib${LIB}'
174	# or even 'lib${LIB:tl}' when LIB contains upper case
175	# the majority of libs in FreeBSD use lib${LIB} for their dirname
176	# but we allow for just ${LIB} too.
177	: package=$package
178	case "$package" in \
179	lib?{LIB*) package=`echo lib${bname#lib} | tr 'A-Z' 'a-z'`;;
180	esac
181	if test "$package" != "$lpackage"; then \
182	    test -z "$lpackage" || end_depend $ddeps
183	    target=$PACKAGES/$package
184	    ddeps=$target/Makefile.depend
185	    odeps=$ddeps.options
186	    rm -f $odeps
187	    start_depend $ddeps
188	    lpackage=$package
189	    echo "	$target \\"
190	fi
191	if [ -n "$opt" ]; then
192	    [ -s $odeps ] || start_options $odeps
193	    {
194		case " $opts " in
195		*" $opt "*) ;;
196		*)  echo DIRDEPS_OPTIONS+= $opt
197		    opts="$opts $opt"
198		    eq==
199		    ;;
200		esac
201		for o in $opt
202		do
203		    echo DIRDEPS.$o.yes$eq $reldir
204		done
205		eq=+=
206	    } >> $odeps
207	else
208	    echo "	$reldir \\" >> $ddeps
209	fi
210    done
211    end_depend $ddeps
212) | to_reldir >> $PACKAGES/Makefile.depend
213end_depend $PACKAGES/Makefile.depend
214