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.
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.
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.
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)
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.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With