我有一个具有以下结构的项目:
$ 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
答案 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
这应该就是你所需要的。