Subject: Re: bug#77897: "make clean" should do a"rm -rf .deps"

From: Sam Varshavchik <[email-masked]>
Date: Fri, 18 Apr 2025 23:16:52 -0400

Peter Johansson writes:

> I see the following at the end of configuring:
>
> checking dependency style of g++... (cached) gcc3
> checking that generated files are newer than configure... done
> configure: creating ./config.status
> config.status: creating Makefile
> config.status: executing depfiles commands
> + cat .deps/main.Po
> # dummy
> + make
> g++ -DPACKAGE_NAME=\"main\" -DPACKAGE_TARNAME=\"main\" - 
> DPACKAGE_VERSION=\"1\" -DPACKAGE_STRING=\"main\ 1\" -DPACKAGE_BUGREPORT=\"\"  
> -DPACKAGE_URL=\"\" -DPACKAGE=\"main\" -DVERSION=\"1\" -I.     -g -O2 -MT  
> main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.cc
> mv -f .deps/main.Tpo .deps/main.Po
> g++  -g -O2   -o main main.o
> + cat .deps/main.Po
> main.o: main.cc /usr/include/stdc-predef.h main.h
> /usr/include/stdc-predef.h:
> main.h:
>
> In other words, configure creates config.status and calls config.status  
> depfiles, which creates a dummy version of .deps/main.Po. If that didn't  
> happened make would complain about the 'include .deps/main.Po' in 'Makefile'  
> and I believe that only happens when .deps/main.Po does not already exist.  
> Then when g++ is creating main.o it also generates a proper version  
> of .deps/main.Po.

But if "make clean" should be undoing what "make" did, then, logically,  
"make clean" should end up putting the stub into .deps/main.Po, instead of  
leaving the real dependencies that "make" wrote in there.

Or, if configure did /not/ do anything, and, just somehow, .deps files were  
created automatically if they did not exist, and, if somehow, this was done  
before include hollered, then this would work.

> If 'make dist' were to remove the .deps files as you suggest, then 'make  
> clean; make all' would fail because a file included into the 'Makefile' at  
> the time of 'make all' that would be quite unexpected behavior.

Odd. I did not notice any difficulties in running "make" after running "rm - 
rf .deps" myself, after a "make clean".

Looks like there's a rule that creates the .deps files if they are missing,  
so there's no need to bother configure with this task. After "make clean",  
"rm -rf .deps", "make", then an immediate CTRL-C:

$ ls .deps | wc -l
47

I definitely did not just compile 47 files, didn't even get to the first  
base.

Looking at what I have in the Makefile, I see:

am__depfiles_remade = [ long list of ./$(DEPDIR) files ]

[ bunch of stuff ]

$(am__depfiles_remade):
        @$(MKDIR_P) $(@D)
        @echo '# dummy' >$@-t && $(am__mv) $@-t $@

So, it seems to me that configure can avoid dealing with depfiles at all,  
and it's safe to have "make clean" get rid of them, they'll just be remade  
on the next "make".

The only puzzle is that the [ bunch of stuff ] does have these includes, in  
fact they immediately precede the above rule. Yet, again, my "make clean"  
and "rm -rf .deps" did not break anything, the subsequent "make" rebuilt  
everything, despite the Makefile referencing a (temporarily) nonexistent  
include files.

After digging through make's documentation, a clue emerged:

#    If an included makefile cannot be found in any of these directories
# it is not an immediately fatal error; processing of the makefile
# containing the 'include' continues.  Once it has finished reading
# makefiles, 'make' will try to remake any that are out of date or don't
# exist.  *Note How Makefiles Are Remade: Remaking Makefiles.  Only after
# it has failed to find a rule to remake the makefile, or it found a rule
# but the recipe failed, will 'make' diagnose the missing makefile as a
# fatal error.

So, a nonexistent include is not an error if make can find a rule that  
builds it. It then gets suppressed.

Oh, and there's also a:

 -include FILENAMES…

which never complains about missing makefiles... how about that...