Reputation: 608
I'm learning make, and try to understand the following makefile from Prerequisite-Types
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
all: $(OBJS)
$(OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir $(OBJDIR)
The first rule confuses me. It's to be firstly applied. Since $(OBJDIR)
is not there, the last rule will be applied to mkdir objdir. Then, since there's nothing in the newly created directory, there's no stem.o, and correspondingly, no stem.c So the prerequisites and recipes seem to be meaningless.
The only thing that the first rule does is to make a directory, which seems to be unreal.
Upvotes: 0
Views: 115
Reputation: 99094
The first rule is a pattern rule, so it cannot be the default rule; it will not be the first applied unless you specify e.g. make thing.o
.
The first rule might not do what you expect. The recipe is $(COMPILE.c) $(OUTPUT_OPTION) $<
, but you don't assign a value to OUTPUT_OPTION
in the makefile; unless you provide a value from outside (e.g. make thing.o OPTION_OUTPUT=...
) this recipe has no special instructions about where to put the file it builds, it has never heard of objdir/
, and will use the compiler's default which is probably the working directory.
The last rule will build objdir
(if objdir
does not already exist, and if Make invokes that rule). The command make objdir
will work perfectly. If you try to build one of the object files listed in OBJS
, Make will construct the directory (if the directory does not exit) -- not because it needs a place to put the file, but because $(OBJDIR)
is a prerequisite of every member of $(OBJS)
, according to the third rule. It will not construct the directory if you try to build objdir/thing.o
, because $(OBJDIR)
is not a prerequisite of that target. You think Make should build it because it is obviously needed? Well, Make isn't that smart.
The first rule has a prerequisite pattern %.c
, and the recipe looks for the source file in the working directory, not in any newly constructed subdirectory. If there is no such source file in the working directory, Make will not run that rule.
Upvotes: 1
Reputation: 100836
I don't really follow your logic.
The first rule in your makefile is this:
all: $(OBJS)
so the default goal for this makefile (if you don't specify one on the command line) is all
.
all
depends on all the .o
files. All the .o
files have an order-only dependency on the directory. So, first the directory is created, then the .o
files are created, then all
is done (there is no recipe here to create a program or library or anything out of those .o
files).
Upvotes: 0