Makefile退出时发生致命错误

时间:2018-04-30 20:56:24

标签: c++ makefile

我有一个具有以下结构的项目:

$ tree
.
├── bin
├── include
│   └── reader.h
├── Makefile
├── obj
└── src
    ├── main.cpp
    └── reader.cpp

4 directories, 4 files

我想在.cpp中有src/个文件,在include/中有标题,在obj/中编译对象文件,在bin/中有可执行文件。我在版本4.1中使用GNU make,在版本7.2.0和Ubuntu 17.10中使用g ++。当我尝试构建它时(我尝试使用想法from here,略微修改)我得到以下错误:

$ make
make: Circular obj/main.o <- obj/main.o dependency dropped.
make: Circular obj/reader.o <- obj/main.o dependency dropped.
make: Circular obj/reader.o <- obj/reader.o dependency dropped.
g++ -c -o obj/obj/reader.o include/reader.h 
In file included from <command-line>:0:0:
/usr/include/stdc-predef.h:1:0: fatal error: can’t create precompiled header obj/obj/reader.o: No such file or directory
 /* Copyright (C) 1991-2017 Free Software Foundation, Inc.

compilation terminated.
Makefile:15: recipe for target 'obj/reader.o' failed
make: *** [obj/reader.o] Error 1

我是makefiles的新手,所以我猜它是非常基本的东西。我该如何解决这个问题?

编辑我忘记了Makefile`。我们走了:

IDIR = include
OBJDIR = obj

CXX = g++
CXXFLAGS = -g -Wall -std=c++14 -I$(IDIR)
DEPS = reader.h

_DEPS = reader.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

_OBJ = main.o reader.o
OBJ = $(patsubst %,$(OBJDIR)/%,$(_OBJ))

$(OBJDIR)/%.o: $(OBJ) $(DEPS)
    $(CXX) -c -o $(OBJDIR)/$@ $< $(CFLAGS)

main: $(OBJ)
    $(CXX) -o $@ $^ $(CXXFLAGS)

EDIT2 将语言改为英语后,我理解了我的警告。  我从$(OBJDIR)指令删除了多余的$(OBJDIR)/%.o部分,结果是这样的:

IDIR = include
OBJDIR = obj

CXX = g++
CXXFLAGS = -g -Wall -std=c++14 -I$(IDIR)
DEPS = reader.h

_DEPS = reader.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

_OBJ = main.o reader.o
OBJ = $(patsubst %,$(OBJDIR)/%,$(_OBJ))

$(OBJDIR)/%.o: $(OBJ) $(DEPS)
    $(CXX) -c -o $@ $< $(CFLAGS)

main: $(OBJ)
    $(CXX) -o $@ $^ $(CXXFLAGS)

和新错误:

$ make
make: Circular obj/main.o <- obj/main.o dependency dropped.
make: Circular obj/reader.o <- obj/main.o dependency dropped.
make: Circular obj/reader.o <- obj/reader.o dependency dropped.
g++ -c -o obj/main.o obj/reader.o 
g++: warning: obj/reader.o: linker input file unused because linking not done
g++ -o main obj/main.o obj/reader.o -g -Wall -std=c++14 -Iinclude
g++: error: obj/main.o: No such file or directory
Makefile:18: recipe for target 'main' failed
make: *** [main] Error 1

1 个答案:

答案 0 :(得分:3)

$(OBJDIR)/%.o: $(OBJ) $(DEPS)毫无意义。你说每个目标文件都依赖于它自己(以及所有其他目标文件)。这就是为什么make抱怨Circular obj/main.o <- obj/main.o dependency dropped.$(OBJ)不应该在那里。

$(CXX) -c -o $@ $< $(CFLAGS)已被删除,因为$<是第一个先决条件,在本例中为obj/reader.o。这就像你正在尝试将一个目标文件编译成另一个目标文件,这没有任何意义。

另外,为什么在这里使用$(CFLAGS)?你正在编译C ++,所以它应该是$(CXXFLAGS)(你的代码永远不会设置CFLAGS。)

您的Makefile从未提及任何cpp文件。这不起作用。

我会扔掉你的Makefile并从简单的东西开始:

CXXFLAGS = -g -Wall -std=c++14 -Iinclude

bin/main: obj/main.o obj/reader.o
        $(CXX) -o $@ $(LDFLAGS) $+ $(LDLIBS)

obj/main.o: src/main.cpp include/reader.h
obj/reader.o: src/reader.cpp include/reader.h

这应该就是你所需要的。