问题
I am having an issue with this makefile. I cannot figure out how to build the object files from their coresponding sources. Every obj gets built with the main source, instead of its one.
TARGET = af_optional
SOURCES := $(wildcard src/*.cpp)
OBJECTS := $(patsubst src/%.cpp,obj/%.o,$(SOURCES))
DEPENDS := $(patsubst src/%.cpp,obj/%.d,$(SOURCES))
CXXFLAGS = -g -I.
# ADD MORE WARNINGS!
WARNING := -Wall -Wextra
# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean
# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: bin/$(TARGET)
clean:
$(RM) $(OBJECTS) $(DEPENDS) $(TARGET)
# Linking the executable from the object files
bin/$(TARGET): $(OBJECTS)
@echo "target : $(TARGET)"
@echo "sources: $(SOURCES)"
@echo "objects: $(OBJECTS)"
@echo "depends: $(DEPENDS)"
@mkdir -p bin
$(CXX) $(WARNING) $(CXXFLAGS) $^ -o $@
-include $(DEPENDS)
$(OBJECTS): $(SOURCES) makefile
@mkdir -p obj
$(CXX) $(WARNING) $(CXXFLAGS) -MMD -MP -c $< -o $@
I have written this makefile while researching a while ago, but I broke something after I had got it working and I haven't noticed until now, since all the project's I've had to work with since were single source.
回答1:
This rule is wrong:
$(OBJECTS): $(SOURCES) makefile
What does this expand to? If you have sources src/foo.cpp
, src/bar.cpp
, and src/baz.cpp
then it will be this:
obj/foo.o obj/bar.o obj/baz.o : src/foo.cpp src/bar.cpp src/baz.cpp makefile
This is an extremely common problem: people seem to have this idea that make will somehow massage all these targets and prerequisites to match them up somehow so that each object file depends only on the corresponding source file.
But, make does NOT do that. The above rule is exactly identical to writing all these rules:
obj/foo.o : src/foo.cpp src/bar.cpp src/baz.cpp makefile
obj/bar.o : src/foo.cpp src/bar.cpp src/baz.cpp makefile
obj/baz.o : src/foo.cpp src/bar.cpp src/baz.cpp makefile
Now maybe you can see why you see the behavior you do: the first prerequisite for every target is exactly the same file src/foo.cpp
so when you use the $<
automatic variable, that's the one you always get.
You have to write ONE rule that builds ONE object, then let make figure out how to apply that rule for all the appropriate objects.
So, to build one object file from one source file you can use a pattern rule like this:
obj/%.o : src/%.cpp makefile
@mkdir -p obj
$(CXX) $(WARNING) $(CXXFLAGS) -MMD -MP -c $< -o $@
That's all you need.
来源:https://stackoverflow.com/questions/65647943/cannot-get-makefile-to-build-each-object-from-its-corresponding-source