Skip to content

build: make depclean remove the userspace dependency files too - #4419

Open
greatEndian wants to merge 1 commit into
LinuxCNC:masterfrom
greatEndian:fix/depclean-userspace-deps
Open

build: make depclean remove the userspace dependency files too#4419
greatEndian wants to merge 1 commit into
LinuxCNC:masterfrom
greatEndian:fix/depclean-userspace-deps

Conversation

@greatEndian

Copy link
Copy Markdown
Contributor

Problem

src/Makefile's depclean target removes only depends, which holds the
realtime dependency files. The userspace ones are written next to their
objects as objects/**/*.d — see TODEPS (Makefile:229) and the
-MF "${@:.o=.d}" compile rules (Makefile:291, 301, 309, 317) — and survive
it. A typical run-in-place tree keeps 535 of them.

The target's own comment claims otherwise ("clean cleans everything but
dependency files, and depclean cleans them too"), and that comment is wrong
in both directions: clean does remove the userspace dependency files,
because genclean deletes objects/ wholesale.

Why it matters

A stale dependency file still declares its original source:

objects/hal/utils/halrmt.o: hal/utils/halrmt.c

gcc's -MP writes dummy targets for the headers only, never for the main
source, so once hal/utils/halrmt.c has been renamed the prerequisite cannot
be satisfied and the entire build stops:

make: *** No rule to make target 'hal/utils/halrmt.c',
needed by 'objects/hal/utils/halrmt.o'.  Stop.

The documented remedy for stale dependency information is make depclean
and it does not work. The only way out is make clean and a full rebuild.

This is not hypothetical. It was hit on a run-in-place tree carried across two
upstream changes: the halrmt.c -> halrmt.cc rename, and the
src/libnml/posemath -> src/libposemath move. Eight dependency files pointed
at sources that no longer existed, and the tree could not be built at all.

Fix

Have depclean remove objects/**/*.d as well, and correct the comment.

Removing them costs no recompilation: nothing takes a .d as a prerequisite,
and UNREAD_DEPS (Makefile:255) is computed but never used. The only thing
given up is header-dependency tracking until each object is next rebuilt,
which is precisely what asking for depclean means.

Verification

  • Planted a dependency file naming a since-renamed source and reproduced the
    failure verbatim, including the -MP subtlety (a first attempt that included
    a dummy rule for the main source did not reproduce it, which is what
    confirmed the mechanism).
  • Before the change: make depclean left all 535 objects/**/*.d in place and
    the build still aborted.
  • After the change: make depclean removed all 535, and the previously fatal
    target built normally.
  • No forced rebuild: a full make default immediately after a patched
    depclean on an up-to-date tree recompiled 0 files.

depclean removed only 'depends', which holds the realtime dependency
files. The userspace ones are written next to their objects as
objects/**/*.d (see TODEPS and the -MF "${@:.o=.d}" compile rules), and
survived it -- 535 of them in a typical run-in-place tree.

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 documented remedy for stale dependencies is exactly this target, and
it did not work: 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.

Verified by planting a dependency file naming a since-renamed source,
reproducing the failure verbatim, and confirming that depclean did not
clear it before this change and does after, with the build then
completing normally.

The comment above modclean is corrected as well: 'clean' does remove the
userspace dependency files today, because genclean deletes objects/
wholesale.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant