Question

I'm reading a big Makefile, part of which I don't understand:

$(IREJECTION): $(IREJECTION:%$(MACH64).o=%.cpp)
        $(CPP) $(CPPDLIBOPTS) -c $(@:%$(MACH64).o=%.cpp) -o $@

In this script (note that I removed unnecessary variables to avoid verbosity), what does the following mean

  • $(IREJECTION:%$(MACH64).o=%.cpp) (on the first line)
  • $(@:%$(MACH64).o=%.cpp) ? (on the second line)

Also, what does this form A: B mean? As in :

 $(IREJECTION): $(IREJECTION:%$(MACH64).o=%.cpp)   #on the first line
 <---- A ---->  <------------ B --------------->   #first instance of A: B
                <--- A ----> <-------- B ------>   #second instance of A: B

As you see, there are two instances of the form A:B — the second one is inside B itself. I see similar thing here as well:

$(@:%$(MACH64).o=%.cpp)   #on the second line
 <A> <---------B------->

Please help me understand this.

Was it helpful?

Solution

You got quite complex example I think. It has many things in it.

Rule / Recipe

A: B
    <command>
  • A - target
  • B - dependency
  • <command> - command to be executed to build A ("Recipe")

target: dependency is called a 'rule'. So all in all, above example is 'rule' with appropriate 'recipe'.

(to make A, which depends on B, one needs to execute <command>)

make compares modifications dates of B and A. If B is newer, then it executes <command>


Variables

$(IREJECTION) is make's variable (it should be defined somewhere before in the file, like IREJECTION:=somefile.o)

During make execution $(IREJECTION) is replaced to actual value of the variable.



Variable substitution

From link below:

$(var:a=b) <..> 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.

And:

For example:

 foo := a.o b.o c.o
 bar := $(foo:%.o=%.c)

sets bar to a.c b.c c.c.

In your case $(IREJECTION:%$(MACH64).o=%.cpp), it takes variable named IREJECTION, tries to find $(MACH64).o (which also references variable MACH64) at the end of the word and replace it with .cpp.



Automatic variable

$@ is called automatic variable. It is reference to the 'target'.



Futher reading

http://www.gnu.org/software/make/manual/make.html

OTHER TIPS

A: B meant that you add a make target A that depends on B. That means when B was changed, it has to be run before A is done. You can use the target A by calling make A.

I'll go tep by step:

lets say you have some object file irejection.mach64.o and the source file irejection.cpp

to generate object from source you typically write a rule smth like

irejection.mach64.o : irejection.cpp # means target : dependencies
    $(CC) irejection.cpp -o $@ # $@ is a special variable - the target (output)

Now lets say $(MACH64) is .mach64 and $(IREJECTION) is irejection$(MACH64).o, ie irejection.mach64.o

$(IREJECTION:%$(MACH64).o=%.cpp) will expand to irejection.cpp

$(@:%$(MACH64).o=%.cpp) will expand to the same, since $@ is $(IREJECTION)

In essence, given object file target with a architecture extensions, rewrite the file name to its source file counterpart.

Seems unncessearily convoluted to me tho. Cleaner way would be smth like:

%$(MACH64).o : %.cpp
    $(CC) -c $@ $<

% are "wildcards", $< is the first dependency, $@ is the output

see: http://www.gnu.org/software/make/manual/make.html#Automatic-Variables

http://www.gnu.org/software/make/manual/make.html#Pattern-Rules

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top