Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
252 views
in Technique[技术] by (71.8m points)

c++ - Cannot get makefile to build each object from its corresponding source

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.

question from:https://stackoverflow.com/questions/65647943/cannot-get-makefile-to-build-each-object-from-its-corresponding-source

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...