Makefile定义了一套规则,规定了哪些文件哪些需要优先编译,哪些需要后编译,哪些需要重新编译。Makedile完成之后整个工程只需要一个make命令便可以完成全部编译工作。完成编译,链接等各种功能。
Makefile的基本规则是:
目标 :依赖
(tab)规则
目标:需要生成的目标文件
以来:生成该目标所需要的文件
tab:每条规则必须以tab键开头,不能使用空格
规则:由依赖文件生成目标文件的具体方式
例:
demo : demo.cpp
gcc demo.cpp -o demo
执行命令:
使用make命令,如果文件名不为M(m)akefile,则使用make -f (fileName)
-:makefile中该条命令出错也继续执行后续命令
make clean:清除编译中间件,如果文件中有名为clean的文件,则不执行,需要使用伪目标 .PHONY:clean
@:此目标只执行,不回显,不会再终端打印出来具体执行规则
$:变量取值需要$符号 $(x)
常用自动变量:
$@:规则中的目标
$<:规则中的第一个依赖条件
$^:规则中的所有依赖条件
模式规则:
%.o : %.cpp
$(CC) -c $< -o $@
该模式规则表示目录下所有.o文件由对应.cpp文件生成
常用函数:
wildcard:查找指定目录下指定类型的文件,返回值为该类型的文件文件名集合。
例:SOURCES = $(wildcard ./src/*.cpp)
patsubst:匹配替换函数
例:OBJS = $(patsubst %.cpp.%.o ,$(SOURCES))
将SOURCES中所有以.cpp结尾的文件替换为.o文件,并返回给OBJS
一、简单Makefile demo:
CC = gcc
SOURCES = $(wildcard ./*.cpp)
OBJS = $(patsubst %.cpp, %.o, $(SOURCES))
TARGET = demo
%.o: %.cpp
$(CC) -c $< -o $@
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET)
.PHONY: clean
clean:
rm -rf $(OBJS) $(TARGET)
二、一个文件夹下有多个.cpp文件,分别对应一个小程序,而总共只有一个Makefile时:
将每个.cpp文件都看作一个程序,编译出来的程序名与.cpp文件名相同(去掉.cpp):
SOURCES = $(wildcard ./*.cpp)
TARGETS = $(patsubst %.cpp,% , $(SOURCES))
每个.cpp文件编译成一个目标:
$(TARGETS) : %:%.cpp
$(CC) $< $(CFLAGS) -o $@
完整demo:
CC = gcc
SOURCES = $(wildcard *.cpp)
TARGETS = $(patsubst %.cpp, %, $(SOURCES))
CFLAGS = -Wall -g
all:$(TARGETS)
$(TARGETS):%:%.cpp
$(CC) $< $(CFLAGS) -o $@
.PHONY:clean all
clean:
-rm -rf $(TARGETS)
三、头文件不在同一个文件夹下,且存在多个依赖库
依赖库前加 -l(小写L) 依赖库路径前加 -L 头文件目录前加 -I(大写i)
例:
LABS = -lpthread
LAB_PATH = -L ./lib
INCLUDE = -I ./inc1 -I./inc2
完整demo:
CC = gcc
INCLUDE = -I./inc1 -I./inc2
CFLAGS = -fpermissive
LIB_PATH = -L../lib
LIBS = -lpthread -lconfigini
SOURCES = $(wildcard *.cpp src/*.cpp)
OBJS = $(patsubst %.cpp,%.o,$(SOURCES))
TARGET = demo
%.o:%.cpp
$(CC) $(CFLAGS) $(INC) $(LIB_PATH) $(LIBS) -c $< -o $@
$(TARGET):$(OBJS)
$(CC) $(CFLAGS) $(INC) $(LIB_PATH) $(LIBS) $(OBJS) -o $(TARGET)
.PHONY: clean
clean:
rm -rf *.o $(OBJS) $(TARGET)