1

I have a folder structure where all my source files are in ./src/, and all my object files are in ./obj/ (with the same internal directory structure, mirrored using path substitutions). I've created the following makefile:

$(EXECUTABLE): $(OBJECTS)
    @echo Linking $(EXECUTABLE)...
    $(CXX) $(LDLIBS) $(OBJECTS) -o $(EXECUTABLE)

%.o: $(subst o,cpp,$(subst obj/,src/,$@))
    @echo Building $@...
    $(CXX) $(CPPFLAGS) -c $(subst o,cpp,$(subst obj/,src/,$@)) -o $@

Which doesn't work! Make keeps claiming that the object files are up to date, even when the source file is actually older than the object file. On the other hand, if I do this:

obj/main.o: src/main.cpp
    @echo Building $@...
    $(CXX) $(CPPFLAGS) -c src/main.cpp -o $@

For every source file, it works perfectly. I checked, and the two subst give the same result (obj/main.o becomes src/main.cpp as expected). Yet Make doesn't accept the dependency for some reason.

This is giving me a lot of grief, can somebody explain where I am going wrong? I don't understand what is going on, I thought my substitution would work the same since it gives the same output. Am I not allowed to use subst, or $@ in the dependencies or something?

4

1 回答 1

7

You can't use $@ in the prerequisites, only in the commands.

But you can do this:

$(OBJECTS): obj/%.o : src/%.cpp
    @echo Building $@ from $<...
    $(CXX) $(CPPFLAGS) -c $< -o $@
于 2012-12-07T03:30:33.673 回答