Makefile无法正常工作

时间:2014-05-27 09:16:56

标签: makefile

我是这个文件夹结构

project
|_src
| |_test
|   |_main.cpp
|_Makefile

这是我的makefile(试图改编自this link):

CC = g++
RM = rm
WFLAGS = -c -Wall -W
LDFLAGS =
SRCTESTD = src/test
EXECUTABLE = test

OBJD = .obj
DEPD = .dep
SRCSTEST = $(SRCTESTD)/main.cpp
OBJECTSTEST = $(patsubst %.cpp, $(OBJD)/test/%.o, $(notdir $(SRCSTEST)))
DEPDSTEST = $(patsubst %.cpp, $(DEPD)/test/%.d, $(notdir $(SRCSTEST)))

all: $(SRCSTEST) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTSTEST)
    $(CC)  $(LDFLAGS) $(OBJECTSTEST) -o $@

.cpp.o:
    $(CC) $(WFLAGS) $< -o $@

它不起作用,我发现了这个错误

make: *** No rule to make target `.obj/test/main.o', needed by `test'.  Stop.

我做错了什么?对不起琐碎的问题,但我是一个新手。

2 个答案:

答案 0 :(得分:2)

错误意味着make无法找到构建目标文件的正确规则。您的树结构缺少一些信息:只有一个文件?其他人在哪里?无论如何,这里有一些提示:

在最后两行中,您使用的是obsolete feature make:后缀规则。我建议您切换到pattern rule,这是功能相当的。 说出类似的话:

%.o: %.cpp
    $(CXX) $(CXXFLAGS) $< -o $@

另一件事(这不应该是一个问题):您正在使用内部定义为默认C编译器的变量CC。没关系,因为你重新定义它,但由于你的源似乎是C ++文件,为什么不使用变量CXX,即internally defined作为C ++编译器?

最后,为确保正确定义您的文件集,您可以使用虚拟show目标see here打印它们。

show:
     @echo "OBJECTSTEST=$(OBJECTSTEST)"
     ...

答案 1 :(得分:2)

该链接显示过时的方法,例如suffix rules。在编译过程中也可以通过gcc / g ++来完成依赖关系。

至于其余部分,请注意:

EXE         :=  test

SRCDIR      :=  src
OBJDIR      :=  .obj

SRC         :=  $(shell find $(SRCDIR) -name "*.cpp")
OBJ         :=  $(SRC:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
DEP         :=  $(OBJ:.o=.d)

LDLIBS      :=  # -l flags
LDFLAGS     :=  # -L flags

CPPFLAGS    :=  -MMD -MP # -I flags also
CXXFLAGS    :=  -W -Wall # no -c flag here

.PHONY: all clean fclean re

all:    $(EXE)

clean:
    $(RM) -r $(OBJDIR)

fclean: clean
    $(RM) $(EXE)

re: fclean all

-include $(DEP)

$(EXE): $(OBJ)
    $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(OBJDIR)/%.o:  $(SRCDIR)/%.cpp
    @mkdir -p $(@D)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<

不重新定义内部定义的变量,没有后缀规则,正确的链接步骤和依赖关系生成。


更新:为避免为每个源文件调用mkdir,应使用order-only prerequisites和特殊目标.SECONDEXPANSION

更改此块:

$(OBJDIR)/%.o:  $(SRCDIR)/%.cpp
    @mkdir -p $(@D)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<

对此:

.SECONDEXPANSION:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $$(@D)/
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<

%/:
    mkdir $*