From c3e266fc6d317fc0413a755ca28360c2f0875ec5 Mon Sep 17 00:00:00 2001 From: greatEndian Date: Wed, 19 Aug 2026 10:12:36 -0400 Subject: [PATCH] build: make depclean remove the userspace dependency files too depclean removed only 'depends'. Under BUILD_SYS=normal that directory holds the realtime dependency files; under the default BUILD_SYS=uspace 'depends' is never created at all. Every other dependency file is written next to its object as objects/**/*.d -- realtime included on a uspace build -- and depclean never touched them. On the default build that made depclean a complete no-op: it rm -rf'd a directory that never existed. That matters when a source file is renamed or moved. A stale dependency file still declares, say objects/hal/utils/halrmt.o: hal/utils/halrmt.c and gcc's -MP writes dummy targets for the *headers* only, never for the main source, so once hal/utils/halrmt.c is gone nothing can satisfy that prerequisite and the whole build stops with make: *** No rule to make target 'hal/utils/halrmt.c', needed by 'objects/hal/utils/halrmt.o'. Stop. The obvious remedy is 'make depclean', and it did not help: the only way out was 'make clean' and a full rebuild. Hit in practice on a run-in-place tree carried across the halrmt.c -> halrmt.cc rename and the src/libnml/posemath -> src/libposemath move; eight dependency files pointed at sources that no longer existed. Removing the files costs no recompilation -- nothing has a .d as a prerequisite, and UNREAD_DEPS is computed but never used -- so this only gives up header-dependency tracking until each object is next rebuilt, which is what asking for depclean means. The comment above modclean is corrected as well: 'clean' does remove the dependency files today, because genclean deletes objects/ wholesale. --- src/Makefile | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 03d5d76cd2f..d33ddc3dd88 100644 --- a/src/Makefile +++ b/src/Makefile @@ -526,8 +526,8 @@ endif # These rules clean things up. 'modclean' cleans files generated by 'modules' # (except that it doesn't remove the modules that were copied to rtlib) -# 'clean' cleans everything but dependency files, and 'depclean' cleans them -# too. +# 'clean' removes the build products (including, via 'objects', the +# dependency files), and 'depclean' removes the dependency files alone. modclean: find -name '.*.cmd' -or -name '*.ko' -or -name '*.mod.c' -or -name '*.mod.o' | xargs rm -f -rm -rf .tmp_versions @@ -535,8 +535,22 @@ modclean: -rm -f ../rtlib/*.ko -rm -f ../rtlib/*.so +# Dependency files land in two places: 'depends' for realtime under +# BUILD_SYS=normal, and beside their objects as objects/**/*.d for +# everything else, realtime included under BUILD_SYS=uspace, where +# 'depends' is never created at all. Both have to go. Dropping them +# forces no recompilation (nothing depends on a .d existing), but it does +# clear stale prerequisites -- a dependency file naming a source that has +# since been renamed or moved otherwise aborts the build with "No rule to +# make target", and there is no way out of that short of a full +# 'make clean'. +# This is a find rather than '$(RM) $(DEPS) $(RTDEPS)' because the files +# that break the build are precisely the ones whose source no longer +# exists, so they are absent from $(DEPS); and $(DEPS) is only defined +# when TRIVIAL_BUILD=no. The pure-make form would not fix the bug. depclean: -rm -rf depends + -find objects -name '*.d' -print0 2>/dev/null | xargs -0 -r rm -f clean: genclean depclean modclean genclean: