Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does "$(@:%.o=%.d)" mean in a makefile?

I see below command options for GCC in a makefile:

... -MMD -MP -MF "$(@:%.o=%.d)" -MT "$(@:%.o=%.d)"  -o "$@" "$<"

How to interpret it?

I searched through the makefile document, but no luck so far.

(This is not just about Automatic Variables)

like image 434
smwikipedia Avatar asked Jul 06 '16 09:07

smwikipedia


2 Answers

$(:=) performs a string replacement.
$@ is the name of the file being generated (the target).
So $(@:%.o=%.d) is the name of the file, with the .o extension changed to .d.

This command line generates one .d dependency file for each .o file.

like image 80
Quentin Avatar answered Oct 13 '22 18:10

Quentin


(Thanks to @Quentin's clue. I just found it!)

It is called Substitution Reference

Some quote:

A substitution reference substitutes the value of a variable with alterations that you specify. It has the form ‘$(var:a=b)’ (or ‘${var:a=b}’) and its meaning is to take the value of the variable var, replace every a at the end of a word with b in that value, and substitute the resulting string.

When we say “at the end of a word”, we mean that a must appear either followed by whitespace or at the end of the value in order to be replaced; other occurrences of a in the value are unaltered. For example:

foo := a.o b.o c.o

bar := $(foo:.o=.c)

sets ‘bar’ to ‘a.c b.c c.c’. See Setting Variables.

A substitution reference is actually an abbreviation for use of the patsubst expansion function (see Functions for String Substitution and Analysis). We provide substitution references as well as patsubst for compatibility with other implementations of make.

So, the full interpretation of the following command:

... -MMD -MP -MF "$(@:%.o=%.d)" -MT "$(@:%.o=%.d)"  -o "$@" "$<"

is:

Use gcc to compile the 1st prerequisite file ($<) and generate the output file named after the current rule target's name (%@). And by the way, generate a makefile named as *.d containing a rule to describe the dependency of current rule target. And change the name of rule target in the generated *.d makefile from *.o to *.d.

like image 44
smwikipedia Avatar answered Oct 13 '22 19:10

smwikipedia