My targets live in a different directory than my source, and so I want to ensure that the target directory exists before building the target. This can be accomplished in lots of ways, but one way that I thought of was to use order-only prerequisites for this (actually, originally I just was using normal prerequisites, but I quickly found out that $^ was getting polluted). A scaled down example appears below (and also is attached as
example1.mk, as my email client does not handle tabs very well):
DERIVED_OBJ_DIR = _linux
#$(DERIVED_OBJ_DIR)/%.o: %.cc
# g++ -o $@ $<
.PHONY: all
all: $(DERIVED_OBJ_DIR)/test.o
$(DERIVED_OBJ_DIR):
mkdir -p $(DERIVED_OBJ_DIR)
#$(DERIVED_OBJ_DIR)/test.o: | $(DERIVED_OBJ_DIR)
Make correctly dies with:
gmake: *** No rule to make target `_linux/test.o', needed by `all'. Stop.
Now, if I uncomment out the order-only prerequisite (
example3.mk):
DERIVED_OBJ_DIR = _linux
#$(DERIVED_OBJ_DIR)/%.o: %.cc
# g++ -o $@ $<
.PHONY: all
all: $(DERIVED_OBJ_DIR)/test.o
$(DERIVED_OBJ_DIR):
mkdir -p $(DERIVED_OBJ_DIR)
$(DERIVED_OBJ_DIR)/test.o: | $(DERIVED_OBJ_DIR)
Make exits successfully, but does *not* build anything (because it does not know how to build $(DERIVED_OBJECT)/test.o, since test.cc (attached) is in the current directory. Specifying the order-only prerequisite, even though it is not a "real" rule (in that there is no command, and I have not specified any normal prerequisites for $(DERIVED_OBJECT)/test.o) has given make the idea that it knows how to build $(DERIVED_OBJECT)/test.o, even though it has no more idea than before. I think that make should exit with the same error code in the second and third examples (that a target just having order-only prerequisites should not count as a "real" rule to make). Thank you!
Tony