我想学习如何为包含3个文件的程序创建基本Makefile:a.cpp,b.cpp和b.h.我在a.cpp中包含b.h并调用在那里声明并在b.cpp中定义的函数。我浏览了几个Makefile教程并想出了一个像这样的Makefile:
CC=g++
CFLAGS= -std=c++11 -Wall -pedantic -g
SOURCES= a.cpp b.cpp
DEPS= b.h
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=exec
all: $(EXECUTABLE)
@echo Make has finished.
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $(EXECUTABLE)
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *~ $(EXECUTABLE)
但是,当我制作并运行exec时,它无法按预期工作。编译器没有提供警告或错误,但是跳过a.cpp中的函数调用,好像它不存在一样。相反,如果我运行简单的
g++ -std=c++11 -Wall -pedantic -g a.cpp b.cpp -o exec
我的程序按预期运行。显然我在Makefile中没有做任何事情,但我无法弄清楚是什么。
答案 0 :(得分:2)
CC=g++
CFLAGS= -std=c++11 -Wall -pedantic -g
SOURCES= a.cpp b.cpp
DEPS= b.h
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=exec
all: $(EXECUTABLE)
@echo Make has finished.
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) -c $*.cpp
clean:
$(RM) *.o *~ $(EXECUTABLE)
答案 1 :(得分:1)
在阅读Makefile示例时,将其作为计算机读取非常有用,在浏览文件时替换字段。突然出现在我身上的是:
SOURCES= a.cpp b.cpp
...
OBJECTS=$(SOURCES:.cpp=.o)
...
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $(EXECUTABLE)
...
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) -c -o $@ $<
第一行定义源文件。第二个定义了Makefile所说的可以从.cpp文件构建的目标文件(扩展名.o)。第三个和第四个定义了生成最终可执行文件的规则,这要求成功生成两个目标文件a.o
和b.o
。最后两行定义了生成目标文件的规则,该规则指定它们需要相同名称的.cpp文件和$(DEPS) == b.h
文件。
最后,这个Makefile调用以下行:
g++ -std=c++11 -Wall -pedantic -g -c -o a.o a.cpp b.h
g++ -std=c++11 -Wall -pedantic -g -c -o b.o b.cpp b.h
g++ -std=c++11 -Wall -pedantic -g a.o b.o -o exec
所以看起来代码中的破坏是前两次传递给编译器的混合标记。