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)
This works very well.  Now, suppose that I comment out the implicit rule and
the order-only prerequisite (attached as example2.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 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
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)
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)
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)
#include <iostream>

int main(void)
{
    std::cout << "Hello, world!" << std::endl;
    return 0;
}
_______________________________________________
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make

Reply via email to