git: 2bdd404abe2c - main - bootstrap-packages handle optional DIRDEPS

From: Simon J. Gerraty <sjg_at_FreeBSD.org>
Date: Mon, 14 Oct 2024 21:58:59 UTC
The branch main has been updated by sjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=2bdd404abe2cdf9f52ddc45202afbde637f97292

commit 2bdd404abe2cdf9f52ddc45202afbde637f97292
Author:     Simon J. Gerraty <sjg@FreeBSD.org>
AuthorDate: 2024-10-14 21:58:12 +0000
Commit:     Simon J. Gerraty <sjg@FreeBSD.org>
CommitDate: 2024-10-14 21:58:12 +0000

    bootstrap-packages handle optional DIRDEPS
    
    Add logic to bootstrap-packages.sh to handle constructs like:
    
    SUBDIR.${MK_OPT}+= sub
    
    and:
    
    .if ${MK_OPT} == "yes"
    SUBDIR+= sub
    .endif
    
    there are other methods used in various makefiles
    so this will be better than nothing, but not complete coverage.
    
    In either case a reldir will be added to
    targets/packages/$package/Makefile.depend.options
    rather than
    targets/packages/$package/Makefile.depend
    
    It does not matter that in many cases the Makefile.depend will end up
    with no DIRDEPS.
    
    Also check that parent Makefile does not have a subdir commented out,
    before including it.
    
    If BOOTSTRAP_PACKAGES_FLAGS is -v we report each Makefile.depend[.options]
    we create.
    
    Reviewed by:    stevek
---
 targets/pseudo/bootstrap-packages/Makefile         |   3 +-
 .../bootstrap-packages/bootstrap-packages.sh       | 134 +++++++++++++++++++--
 2 files changed, 125 insertions(+), 12 deletions(-)

diff --git a/targets/pseudo/bootstrap-packages/Makefile b/targets/pseudo/bootstrap-packages/Makefile
index 6523e88f84db..d3385fb1e7e0 100644
--- a/targets/pseudo/bootstrap-packages/Makefile
+++ b/targets/pseudo/bootstrap-packages/Makefile
@@ -13,7 +13,8 @@ all: packages
 PACKAGES?= ${.CURDIR:H:H}/packages
 
 packages: package-makefile.list
-	@${.CURDIR}/bootstrap-packages.sh PACKAGES=${PACKAGES} ${.ALLSRC}
+	@${.CURDIR}/bootstrap-packages.sh ${BOOTSTRAP_PACKAGES_FLAGS} \
+	PACKAGES=${PACKAGES} ${.ALLSRC}
 
 package-makefile.list:
 	@(cd ${SRCTOP} && \
diff --git a/targets/pseudo/bootstrap-packages/bootstrap-packages.sh b/targets/pseudo/bootstrap-packages/bootstrap-packages.sh
index a2fe250d68a3..58b2843a9422 100755
--- a/targets/pseudo/bootstrap-packages/bootstrap-packages.sh
+++ b/targets/pseudo/bootstrap-packages/bootstrap-packages.sh
@@ -24,16 +24,33 @@
 # and $PACKAGES/Makefile.depend to make it easier to keep
 # Makefile.depend files throughout the tree up-to-date.
 #
-# The result is not ideal, as we do not (yet) take into account all
-# the MK_* knobs that can impact DIRDEPS.
+# We attempt to handle MK_* knobs that impact DIRDEPS, by
+# identifying the intermediate *bin and *lib Makefiles and
+# checking if they had a subdir for the current reldir via a construct
+# like:
+#
+# 	SUBDIR.${MK_OPT}+= sub
+#
+# in which case we extract the option OPT and add the reldir
+# to a Makefile.depend.options file in targets/packages/sub/
+#
+# Of course the above is only *one* way optional SUBDIRs are handled
+# in the tree.  We also attempt to handle:
+#
+#	.if ${MK_OPT} == "yes"
+#	SUBDIR+= sub
+#	.endif
 #
 
 Mydir=`dirname $0`
 
+SKIP_LOG=return
+
 while :
 do
     case "$1" in
     *=*) eval "$1"; shift;;
+    -v) SKIP_LOG=:; shift;;
     *) break;;
     esac
 done
@@ -43,6 +60,9 @@ to_reldir() {
 }
 
 SRCTOP=${SRCTOP:-$(realpath $Mydir/../../..)}
+. ${SRCTOP}/libexec/rc/debug.sh
+DebugOn bootstrap-packages
+
 PACKAGES=${PACKAGES:-$(realpath $Mydir/../..)}
 case "$PACKAGES" in
 /*) ;;
@@ -51,9 +71,15 @@ esac
 
 script_name=$(realpath $0 | to_reldir)
 
+log() {
+    $SKIP_LOG 0
+    echo $1 | to_reldir >&2
+}
+
 start_depend() {
     depfile=$1
 
+    log $1
     mkdir -p ${depfile%/*}
     cat <<EOF > $depfile
 # Generated by $script_name
@@ -63,33 +89,119 @@ EOF
 }
 
 end_depend() {
-    depfile=$1
-
-    cat <<EOF >> $depfile
+    end_options $1.options
+    cat <<EOF >> $1
 
 .include <dirdeps.mk>
 EOF
 }
 
+start_options() {
+    ofile=$1
+
+    log $1
+    mkdir -p ${ofile%/*}
+    opts=$opt
+    eq==
+    cat <<EOF > $ofile
+# Generated by $script_name
+
+DIRDEPS_OPTIONS= $opt
+EOF
+}
+
+end_options() {
+    test -s $1 || return
+    cat <<EOF >> $1
+
+.include <dirdeps-options.mk>
+EOF
+}
+
+find_opt() {
+    mf=$1
+    sub=$2
+    shift 2
+    case "$sub" in
+    *+*) sub=`echo "$sub" | sed 's,+,\\\\+,g'`;;
+    esac
+    egrep "$@" "^[^#].*[[:space:]]$sub([[:space:]]|\$)" $mf |
+    tr '{' '\n' |
+    sed -n 's,^MK_\([^}]*\).*,\1,p' |
+    tr '\n' ' '
+}
+
 start_depend $PACKAGES/Makefile.depend || exit 1
 sort -t= -k2 "$@" | sed 's,/Makefile:PACKAGE=, ,' |
 (
     lpackage=
     while read reldir package
     do
-        case "$package" in \
-	lib?{LIB}) package=${reldir##*/};;
-	lib?{LIB:tl}) package=`echo ${reldir##*/} | tr 'A-Z' 'a-z'`;;
+	# use these below
+	dname=${reldir%/*}
+	bname=${reldir##*/}
+	# check parent does not have it commented out
+	# otherwise we should ignore it.
+	pmf=$SRCTOP/$dname/Makefile
+	egrep -q "^[^#].*[[:space:]]$bname([[:space:]]|\$)" $pmf || continue
+	: reldir=$reldir
+	case "$reldir" in
+	*lib/*) sub=${reldir#*lib/};;
+	*bin/*) sub=${reldir#*bin/};;
+	*libexec/*) sub=${reldir#*libexec/};;
+	*) opt= sub=;;
+	esac
+	if [ -n "$sub" ]; then
+	    smf=${SRCTOP}/${reldir%/$sub}/Makefile
+	    # now we need just the immediate subdir
+	    sub=${sub%%/*}
+	    # SUBDIR.${MK_OPT}+= sub
+	    opt=`find_opt $smf $sub`
+	    # .if ${MK_OPT} == "yes"
+	    # SUBDIR+= sub
+	    opt=${opt:-`find_opt $smf $sub -B2`}
+	fi
+	case "$reldir" in
+	*/tests|*/tests/*) opt=${opt:-TESTS};;
+	esac
+	# PACKAGES is set to either a simple string like 'runtime'
+	# or for some libraries 'lib${LIB}'
+	# or even 'lib${LIB:tl}' when LIB contains upper case
+	# the majority of libs in FreeBSD use lib${LIB} for their dirname
+	# but we allow for just ${LIB} too.
+	: package=$package
+	case "$package" in \
+	lib?{LIB*) package=`echo lib${bname#lib} | tr 'A-Z' 'a-z'`;;
 	esac
 	if test "$package" != "$lpackage"; then \
 	    test -z "$lpackage" || end_depend $ddeps
 	    target=$PACKAGES/$package
-            ddeps=$target/Makefile.depend
-            start_depend $ddeps
+	    ddeps=$target/Makefile.depend
+	    odeps=$ddeps.options
+	    rm -f $odeps
+	    start_depend $ddeps
 	    lpackage=$package
 	    echo "	$target \\"
 	fi
-	echo "	$reldir \\" >> $ddeps
+	if [ -n "$opt" ]; then
+	    [ -s $odeps ] || start_options $odeps
+	    {
+		case " $opts " in
+		*" $opt "*) ;;
+		*)  echo DIRDEPS_OPTIONS+= $opt
+		    opts="$opts $opt"
+		    eq==
+		    ;;
+		esac
+		for o in $opt
+		do
+		    echo DIRDEPS.$o.yes$eq $reldir
+		done
+		eq=+=
+	    } >> $odeps
+	else
+	    echo "	$reldir \\" >> $ddeps
+	fi
     done
     end_depend $ddeps
 ) | to_reldir >> $PACKAGES/Makefile.depend