比较通用的makefile:
##################################### # Copyright (c) 1997 George Foot (george.foot@merton.ox.ac.uk) # # All rights reserved. # ###################################### # #目标(可执行文档)名称,库(譬如stdcx,iostr,mysql等),头文件路径 DESTINATION := mini-muduo LIBS := INCLUDES := . RM := rm -f #C,CC或CPP文件的后缀 PS=cc # GNU Make的隐含变量定义 CC=g++ CPPFLAGS = -g -Wall -O3 -march=i486 CPPFLAGS += $(addprefix -I,$(INCLUDES)) CPPFLAGS += -MMD #以下部分无需修改 SOURCE := $(wildcard *.$(PS)) OBJS := $(patsubst %.$(PS),%.o,$(SOURCE)) DEPS := $(patsubst %.o,%.d,$(OBJS)) MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS)) MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.$(PS),$(MISSING_DEPS))) .PHONY : all deps objs clean rebuild all : $(DESTINATION) deps : $(DEPS) $(CC) -MM -MMD $(SOURCE) objs : $(OBJS) clean : @$(RM) *.o @$(RM) *.d @$(RM) $(DESTINATION) rebuild: clean all ifneq ($(MISSING_DEPS),) $(MISSING_DEPS) : @$(RM) $(patsubst %.d,%.o,$@) endif -include $(DEPS) $(DESTINATION) : $(OBJS) $(CC) -o $(DESTINATION) $(OBJS) $(addprefix -l,$(LIBS)) #结束
赋值符号 := 与 =
:=与=的区别在于,符号:=表示立即展开变量值。例如:
A:=foo
B:=$(A)
A:=bar
这时,B的值仍为foo,因为它已被展开,不会再随A的值改变而改变。
filter-out函数
$(filter-out $(A),$(B))表示从B中过滤掉A中的内容,返回剩余内容;
.all deps objs clean veryclean rebuild info
这些都是“伪目标”。
all是第一个目标,所以输入make时它被默认执行;all生成或更新所有*.cpp文件对应的*.d文件和*.o文件,并链接所有*.o文件生成可执行文件$(EXECUTABLE)。
deps仅仅生成*.d文件;.d文件是什么文件?它包含了代码文件的依赖信息。
objs仅仅生成*.o文件;.o文件是C++代码编译后的中间结果文件,废话!
clean用于删除*.d文件和*.o文件。
veryclean删除*.d文件、*.o文件,还有名为$(EXECUTABLE)的可执行文件。
rebuild先调用veryclean清除结果文件,再调用all重新编译和链接。
info查看某些信息。
使用方法:
make deps即可执行deps;
9.ifneq...else...endif
条件语句,ifneq表示如果不想等,则...;
10.include <files>语句
include表示把<files>的内容包含进来;
$(DEPS)是包含依赖信息的文件,每个源文件对应一个.d文件;-include $(DEPS)表示把这些依赖信息包含进来;
11.链接*.o文件,生成可执行文件
主菜来了!
$(EXECUTABLE) : $(OBJS) $(CC) -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))
$(EXECUTABLE)为可执行文件名;$(OBJS)为所有.o文件名;$(CC)在这里是g++;$(addprefix -l,$(LIBS)添加引用库;
前面说好的*.d文件和*.o文件是怎么生成的呢?貌似没有命令指出要生成它们呀!请看隐含规则!
12. 隐含规则(Implicit rules)
$(EXECUTABLE)依赖于$(OBJS),但makefile中没有指明$(OBJS)依赖于谁,也没指明命令生成它们;
这时,make的隐含规则开始起作用;针对$(OBJS)中的每个目标,make自动调用:
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
依次生成.o文件和.d文件;
$<表示依赖文件列表的第一个文件名;
$@表示目标文件名;
之所以会生成.d文件,是由于“-MMD”这一编译选项。为g++加上这一选项后,编译器会生成文件依赖信息,并存放至.d文件中。
每一个.cpp文件相应地生成一个.d文件和一个.o文件。
13.@符号
命令行前的@符号表示不回显命令行;
14.CFLAGS和CPPFLAGS
这两者包含编译选项,更详细内容请Google之。
-g 添加gdb调试信息;
-Wall 提示warning信息;
-O3 表示第3级优化;
参考:http://graybull.is-programmer.com/posts/37758.html