Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple colons and equal sign in makefile (need explanation)

Tags:

makefile

This is only a segment of a makefile. I don't quite understand what is going on.

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o)
$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)

All I understand is these lines compile .cpp files into .o, after 'print-opts', with 'cc-command'. But I don't understand the semantics.

If I expand the macro of 'OBJS', this line should be:

$(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) : $(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)

To me, it looks like in '$(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o)', it claims all .cpp in $(SRC) would come to .o in $(OBJ), but this would depend on $(OBJ)/%.o, which depends on $(SRC)/%.cpp. This doesn't make sense...

I don't understand what is the meaning of equal sign here, and what multiple colons mean.

like image 521
qinsoon Avatar asked Jul 11 '12 05:07

qinsoon


People also ask

Can you have multiple rules in a makefile?

There can only be one recipe to be executed for a file. If more than one rule gives a recipe for the same file, make uses the last one given and prints an error message.

What does colon mean in makefile?

In the first line, the list of target names is terminated by a colon. This, in turn, is followed by the dependency list, if there is one. If several targets are listed, this indicates that each such target is to be built independently using the rule supplied.

What is :: In makefile?

indicates to set the KDIR variable only if it's not set/doesn't have a value. For example: KDIR ?= "foo" KDIR ?= "bar" test: echo $(KDIR)

What are the three parts of a makefile rule?

A makefile consists of three sections: target, dependencies, and rules. The target is normally either an executable or object file name. The dependencies are source code or other things needed to make the target. The rules are the commands needed to make the target.


1 Answers

Suppose you've defined these three variables (and if you haven't, the rule won't work very well):

SRC = source_dir
OBJ = object_dir
SRCS = source_dir/foo.cpp source_dir/bar.cpp

Now consider the assignment

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o)

This is a substitution reference; it says "for anything in $(SRCS) that has the form $(SRC)/%.cpp, change it to $(OBJ)/%.o". So OBJS will evaluate to object_dir/foo.o object_dir/bar.o.

Now the rule:

$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)

Thuis is a static pattern rule. It specifies a list of targets ($(OBJS)), a target pattern ($(OBJ)/%.o) and a prerequisite pattern ($(SRC)/%.cpp). Make matches a target to the target pattern, and uses that to construct the prerequisite name. So if Make used this rule to build object_dir/foo.o, the stem would be foo and the prerequisite would be source_dir/foo.cpp.

(You didn't ask about | print-opts, so I assume that it's already clear.)

like image 184
Beta Avatar answered Sep 20 '22 23:09

Beta