1
0
mirror of https://git.FreeBSD.org/src.git synced 2026-06-02 11:24:32 +00:00

build: introduce the notion of a build epoch

Idea and file format shamelessly stolen from CheriBSD, but reimplemented
in terms of the standard FreeBSD build system.  We'll use this in some
events that call for a deeper cleansing, typically reserved for
situations where the dependencies are too complicated to unwind.  This
notably does not preclude us from doing separate cleansing of world for
specific src.conf(5) knob changes that would require a rebuild.

In the FreeBSD version, we either stamp the OBJTOP we're cleaning
(bootstrap or the full OBJDIR) with the current epoch and bail out for
unstamped objdirs, or we compare and either `rm -rf` or `cleandir` as
necessary.

Reviewed by:	brooks, des
Differential Revision:	https://reviews.freebsd.org/D51848
This commit is contained in:
Kyle Evans
2025-08-14 23:43:42 -05:00
parent 10708fdc0b
commit 0090096e52
3 changed files with 93 additions and 4 deletions
+7
View File
@@ -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
+3 -2
View File
@@ -1082,7 +1082,7 @@ _cleanobj_fast_depend_hack: .PHONY
@echo ">>> Deleting stale dependencies..."; @echo ">>> Deleting stale dependencies...";
MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} \ MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} \
ALL_libcompats=${_ALL_libcompats:Q} \ ALL_libcompats=${_ALL_libcompats:Q} \
sh ${.CURDIR}/tools/build/depend-cleanup.sh ${OBJTOP} sh ${.CURDIR}/tools/build/depend-cleanup.sh ${OBJTOP} ${SRCTOP}
_cleanworldtmp: .PHONY _cleanworldtmp: .PHONY
.if ${MK_CLEAN} == "yes" .if ${MK_CLEAN} == "yes"
@@ -1175,7 +1175,8 @@ _cleanobj:
${_+_}cd ${.CURDIR}; ${LIB${LIBCOMPAT}WMAKE} _NO_INCLUDE_COMPILERMK=t -f Makefile.inc1 ${CLEANDIR} ${_+_}cd ${.CURDIR}; ${LIB${LIBCOMPAT}WMAKE} _NO_INCLUDE_COMPILERMK=t -f Makefile.inc1 ${CLEANDIR}
.endfor .endfor
.else .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" .endif # ${MK_CLEAN} == "yes"
_obj: _obj:
@echo @echo
+83 -2
View File
@@ -63,6 +63,10 @@
# if [ "$MACHINE_ARCH" = "amd64" ]; then # if [ "$MACHINE_ARCH" = "amd64" ]; then
# clean_dep lib/libc bcmp c # clean_dep lib/libc bcmp c
# fi # 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 -e
set -u set -u
@@ -80,7 +84,7 @@ err()
usage() usage()
{ {
echo "usage: $(basename $0) [-v] [-n] objtop" >&2 echo "usage: $(basename $0) [-v] [-n] objtop srctop" >&2
} }
VERBOSE= VERBOSE=
@@ -101,17 +105,31 @@ while getopts vn o; do
done done
shift $((OPTIND-1)) shift $((OPTIND-1))
if [ $# -ne 1 ]; then if [ $# -ne 2 ]; then
usage usage
exit 1 exit 1
fi fi
OBJTOP=$1 OBJTOP=$1
shift shift
SRCTOP=$1
shift
if [ ! -d "$OBJTOP" ]; then if [ ! -d "$OBJTOP" ]; then
err "$OBJTOP: Not a directory" err "$OBJTOP: Not a directory"
fi fi
if [ ! -d "$SRCTOP" -o ! -f "$SRCTOP/Makefile.inc1" ]; then
err "$SRCTOP: Not the root of a src tree"
fi
: ${CLEANMK=""}
if [ -n "$CLEANMK" ]; then
if [ -z "${MAKE+set}" ]; then
err "MAKE not set"
fi
fi
if [ -z "${MACHINE+set}" ]; then if [ -z "${MACHINE+set}" ]; then
err "MACHINE not set" err "MACHINE not set"
fi fi
@@ -151,6 +169,69 @@ clean_dep()
done done
} }
extract_epoch()
{
[ -s "$1" ] || return 0
awk 'int($1) > 0 { epoch = $1 } END { print epoch }' "$1"
}
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
# We don't assume that all callers will have grabbed the build epoch, so
# we'll do it here as needed. This will be useful if we add other
# non-epoch reasons to force clean.
if [ -z "$buildepoch" ]; then
buildepoch=$(extract_epoch "$SRCTOP"/.clean_build_epoch)
fi
mkdir -p "$OBJTOP"
echo "$buildepoch" > "$OBJTOP"/.clean_build_epoch
exit 0
}
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
# We don't discriminate between the varying degrees of difference
# between epochs. If it went backwards we could be bisecting across
# epochs, in which case the original need to clean likely still stands.
objepoch=$(extract_epoch "$OBJTOP"/.clean_build_epoch)
if [ -z "$objepoch" ] || [ "$srcepoch" -ne "$objepoch" ]; then
if [ "$VERBOSE" ]; then
echo "Cleaning - src epoch: $srcepoch, objdir epoch: ${objepoch:-unknown}"
fi
clean_world "$srcepoch"
# NORETURN
fi
}
check_epoch
#### Typical dependency cleanup begins here.
# Date Rev Description # Date Rev Description
# 20220326 fbc002cb72d2 move from bcmp.c to bcmp.S # 20220326 fbc002cb72d2 move from bcmp.c to bcmp.S