On Tue, 2025-05-06 at 21:58 +0800, lijh.8 wrote:
> I have been so confused for years everytime when I read the example
> in manual section 4.14 `Generating Prerequisites Automatically`.
> So, The rule in 4.14 tries to keep the `.d` files.
> When a `.d` file is deleted eg. from command line, the rule will
> regenerate it.
> Am i understanding it correctly?

I wouldn't say it as "the rule tries to keep the .d files".  Thinking
of it as "keeping" the files is perhaps confusing you.

There's no difference in how make considers these rules than any other
rule.  "Something" tells make that this file should become up to date.
Make follows its normal behavior: it looks for explicit or implicit
rules that can build that target.  It finds one, in the pattern rule. 
That pattern rule says: "if you want to build a .d file, you can build
it from a .c file".  So make checks the timestamp of the .c file and
compares it to the .d file.  If the .c file is newer, the .d file is
out of date and make runs its recipe to bring it up to date.

In addition, the sed command creates various .d files and these files
add extra prerequisites to the .d file target.  You can go look at the
contents of these .d files to see what they do.

This means that if any of those extra prerequisites (header files)
change, that will ALSO cause the .d file to be out of date and rebuilt.

This is all pretty standard make: no magic really.

The unusual/magic part is the "something that tells make that these
files should become up to date".  Normally that's done either by a
command-line goal (like "make all") or the default target.

But GNU Make also adds a special extra set of goals: all the makefiles
that were parsed.  Make will consider each of those as targets to be
built, before any other targets.  And the second magic bit is, if any
of those makefile targets are rebuilt, make will re-exec itself and
start all over again: re-read all the makefiles from scratch so that
the updated dependency information is used.

> Also the 4.14 example works with the first two style of the include
> in makefile.  Why the last two do not work?
> 
> -include $(patsubst %.cpp,%.d,$(wildcard *.cpp)) # ok
> -include $(sources:.c=.d) # ok
> -include $(wildcard *.d) # error
> -include *.d # error

It's not clear what you meany by "error" here.  make should not
generate any error messages for these lines.

However, the reason the last two will not do what what you want is
exactly the same reason that you can't write this rule:

   myprog : $(wildcard *.o)

and have it work the way you want: the wildcard / globbing pattern is
expanded when the makefile is parsed, and it just looks at the files
that exist on the disk at that time.

When you run your build with a clean directory, there are no .d files
and so the wildcard/include will include nothing.  Because nothing is
included, make will not try to rebuild anything (remember, make is only
rebuilding the makefiles that were included).  So, none of the .d files
will ever be created.

Reply via email to