diff --git a/.clean_build_epoch b/.clean_build_epoch new file mode 100644 --- /dev/null +++ b/.clean_build_epoch @@ -0,0 +1,7 @@ +# Add a new line containing a larger number than the last (e.g. YYYYMMDD) for +# every change that breaks ABI or requires a full rebuild for some other reason. +# Only the last entry is required, but having the full list may be useful for +# looking at frequency of ABI breakage, etc. + +# 4757b351ea9: openssl: Import version 3.5.1 +20250807 # All OpenSSL-using bits need rebuilt diff --git a/Makefile.inc1 b/Makefile.inc1 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1083,7 +1083,7 @@ @echo ">>> Deleting stale dependencies..."; MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} \ ALL_libcompats=${_ALL_libcompats:Q} \ - sh ${.CURDIR}/tools/build/depend-cleanup.sh ${OBJTOP} + sh ${.CURDIR}/tools/build/depend-cleanup.sh ${OBJTOP} ${SRCTOP} _cleanworldtmp: .PHONY .if ${MK_CLEAN} == "yes" @@ -1176,7 +1176,8 @@ ${_+_}cd ${.CURDIR}; ${LIB${LIBCOMPAT}WMAKE} _NO_INCLUDE_COMPILERMK=t -f Makefile.inc1 ${CLEANDIR} .endfor .else - ${_+_}cd ${.CURDIR}; ${WMAKE} _NO_INCLUDE_COMPILERMK=t _cleanobj_fast_depend_hack + ${_+_}cd ${.CURDIR}; env CLEANMK="_NO_INCLUDE_COMPILERMK=t ${CLEANDIR}" \ + MAKE=${MAKE} ${WMAKE} _cleanobj_fast_depend_hack .endif # ${MK_CLEAN} == "yes" _obj: @echo diff --git a/tools/build/depend-cleanup.sh b/tools/build/depend-cleanup.sh --- a/tools/build/depend-cleanup.sh +++ b/tools/build/depend-cleanup.sh @@ -63,6 +63,10 @@ # if [ "$MACHINE_ARCH" = "amd64" ]; then # clean_dep lib/libc bcmp c # fi +# +# We also have a big hammer at the top of the tree, .clean_build_epoch, to be +# used in severe cases where we can't surgically remove just the parts that +# need rebuilt. This should be used sparingly. set -e set -u @@ -80,7 +84,7 @@ usage() { - echo "usage: $(basename $0) [-v] [-n] objtop" >&2 + echo "usage: $(basename $0) [-v] [-n] objtop srctop" >&2 } VERBOSE= @@ -101,17 +105,31 @@ done shift $((OPTIND-1)) -if [ $# -ne 1 ]; then +if [ $# -ne 2 ]; then usage exit 1 fi OBJTOP=$1 shift +SRCTOP=$1 +shift + if [ ! -d "$OBJTOP" ]; then err "$OBJTOP: Not a directory" fi +if [ ! -d "$SRCTOP" ]; then + err "$SRCTOP: Not a directory" +fi + +: ${CLEANMK=""} +if [ -n "$CLEANMK" ]; then + if [ -z "${MAKE+set}" ]; then + err "MAKE not set" + fi +fi + if [ -z "${MACHINE+set}" ]; then err "MACHINE not set" fi @@ -151,6 +169,84 @@ done } +clean_world() +{ + local buildepoch="$1" + + # The caller may set CLEANMK in the environment to make target(s) that + # should be invoked instead of just destroying everything. This is + # generally used after legacy/bootstrap tools to avoid over-cleansing + # since we're generally in the temporary tree's ancestor. + if [ -n "$CLEANMK" ]; then + echo "Cleaning up the object tree" + run $MAKE -C "$SRCTOP" -f "$SRCTOP"/Makefile.inc1 $CLEANMK + else + echo "Cleaning up the temporary build tree" + run rm -rf "$OBJTOP" + fi + + # Preemptively stamp the new objdir with the epoch at time of cleaning, + # so that we can pick up a subsequent need to clean under the assumption + # that this build will complete. We don't assume that all callers will + # have grabbed the build epoch, so we'll do it here as needed. + if [ -z "$buildepoch" ]; then + buildepoch=$(extract_epoch "$SRCTOP"/.clean_build_epoch) + fi + + mkdir -p "$OBJTOP" + echo "$buildepoch" > "$OBJTOP"/.clean_build_epoch + + exit 0 +} + +extract_epoch() +{ + local epochfile="$1" + + grep -ve '^#' -e '^$' "$epochfile" | tail -1 | cut -f1 | egrep '^[0-9]+$' +} + +check_epoch() +{ + local srcepoch objepoch + + srcepoch=$(extract_epoch "$SRCTOP"/.clean_build_epoch) + if [ -z "$srcepoch" ]; then + err "Malformed .clean_build_epoch; please validate the last line" + fi + + if [ -s "$OBJTOP"/.clean_build_epoch ]; then + objepoch=$(extract_epoch "$OBJTOP"/.clean_build_epoch) + + if [ "$VERBOSE" ]; then + echo "src epoch: $srcepoch, objdir epoch: $objepoch" + fi + else + # If we don't have an epoch, we can't really tell anything about + # the current objdir. We have no choice but to just stamp it + # with the current build and hope it works. + if [ "$VERBOSE" ]; then + echo "Stamping fresh .clean_build_epoch" + fi + + echo "$srcepoch" > "$OBJTOP"/.clean_build_epoch + return + fi + + if [ "$srcepoch" -gt "$objepoch" ]; then + if [ "$VERBOSE" ]; then + echo "objdir epoch is older than src; cleaning" + fi + + clean_world "$srcepoch" + # NORETURN + elif [ "$srcepoch" -lt "$objepoch" ]; then + err ".clean_build_epoch appears to have gone backwards; please validate the last line" + fi +} + +check_epoch + # Date Rev Description # 20220326 fbc002cb72d2 move from bcmp.c to bcmp.S