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

From: Peter Johansson <[email-masked]>
Date: Sat, 19 Apr 2025 12:49:54 +1000

On 4/19/25 11:21, Sam Varshavchik wrote:
> Peter Johansson writes:
>
>> Hi Sam,
>>
>> On 4/18/25 21:56, Sam Varshavchik wrote:
>>>
>>> Set up a minimal Makefile.am and configure.ac to build this. 
>>> Building this will create .deps/<filename> with a:
>>>
>>> main.o: main.h main.c
>>>
>> When I do this with GCC, the .deps/<filename> also contains a line
>>
>> main.h:
>>
>> and I have no problem removing main.h and the #include and just run 
>> 'make'. If you don't have that line (main.h:), it's bug in your 
>> compiler and I suggest you report it.
>
> I'm guilty of wasting a little bit of time with a simplified example.
>
> The real example involves a git repo and multiple branches, one branch 
> has C code, another branch has C++ code. They compile to the same 
> .o-s. That is, one branch has main.c compiling into main.o, and the 
> other branch has main.cpp compiling into main.o. Each branch has the 
> appropriate Makefile.am reflecting what's on that branch.
>
> So now when I switch branches things get stuck. What gets included 
> from .deps/filename are, basically:
>
> main.o: main.c main.h <a bunch of other header files>
>
> there's no main.c any more. This branch I'm now on has main.cpp. Even 
> though the Makefile.am now reflects that, things won't go anywhere 
> unless I manually rm -rf .deps.
>
> How about we try another contrived example. Just a main.c with
>
> int main()
> {
>    return 0;
> }
>
> and
>
> noinst_PROGRAMS=main
>
> main_SOURCES=main.c
>
> Let's now run make (in addition to automake/autoconf) and build this 
> successfully.
>
> Next, rename main.c to main.cpp and update Makefile.am to
>
> noinst_SOURCES=main.cpp
>
> What should happen right now by running "make":
>
> 1) Rules that build out of date Makefile.in and Makefile, from 
> Makefile.am get triggered. The new, correct, Makefile should get built 
> automatically, then
>
> 2) The existing dependency from .deps is going to get pulled in, 
> declaring main.o's dependency on main.c, which does not exist any 
> more. "make clean" won't help here.
>
>> As a rule of thumb 'make clean' does not remove things that were 
>> created during configure (or upstream), but obviously depends on how 
>> people write the Makefile.am.
>
> I'm just using old-fashioned autoconf+automake+libtool-generated 
> rules, nothing more.
>
> I don't see my .deps's contents getting created during configure. 

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.

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.

Peter