Cannot get makefile to build each object from its corresponding source

蹲街弑〆低调 提交于 2021-01-24 11:32:19

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!