Makefile基本语法:
目标文件:依赖文件
[TAB]指令
#指令前必须有tab键,否则报错
#程序按照递归方式进行依赖文件查找,所以接近目标文件的命令写在前边
示例代码
hello:hello.o
gcc hello.o -o hello
hello.o:hello.S
gcc -c hello.S -o hello.o
hello.S:hello.i
gcc -S hello.i -o hello.S
hello.i:hello.c
gcc -E hello.c -o hello.i
当前文件夹中有hello.c和Makefile两个文件,执行make命令,则会自动
生成hello.o\hello.S\hello.\hello.exe
基本符号及含义:
= 替换(最终)
+= 追加
:= 等于(立即)
?= 无值则赋值
%.o 任意的.o文件
*.o 所有的.o文件
$^ 所有依赖文件
$@ 所有目标文件
$< 第一个依赖文件
伪目标 标志位.PHONY
.PHONY:
clear:
rm hello.o hello.S hello.i
.PHONY:这是固定格式,不能变的,但是下面的clear是自己取的名字,你随
便取什么名字都可以,但是clear比较直观
则上述示例代码变为
TAR = test
OBJ = program1.o program2.o main.o
CC := gcc
$(TAR)😒(OBJ)
$(CC) $(OBJ) -o $(TAR)
%.o:%.c
$(CC) -c %.c -o %.o
.PHONY:
clean_all:
rm $(OBJ)
其他注意事项:
1、"="是最普通的等号,在Makefile中容易搞错赋值等号,使用 “=”进行
赋值,变量的值是整个Makefile中最后被指定的值。
VIR_A = A
VIR_B = $(VIR_A) B
VIR_A = AA
经过上面的赋值后,最后VIR_B的值是AA B,而不是A B,在make时,会
把整个Makefile展开,来决定变量的值
2、":=" 表示直接赋值,赋予当前位置的值。
VIR_A := A
VIR_B := $(VIR_A) B
VIR_A := AA
最后BIR_B的值是A B,即根据当前位置进行赋值。因此相当于“=”,“:=”
才是真正意义上的直接赋值
附一篇万能模板:
####################################################
Generic makefile - 万能Makefile
for compiling and linking C++ projects on Linux
Author: George Foot Modified:Jackie Lee
####################################################
Customising
Adjust the following if necessary; EXECUTABLE is the target
executable's filename, and LIBS is a list of libraries to link in
(e.g. alleg, stdcx, iostr, etc). You can override these on make's
command line of course, if you prefer to do it that way.
EXECUTABLE := main # 可执行文件名
LIBDIR:= # 静态库目录
LIBS := # 静态库文件名
INCLUDES:=. # 头文件目录
SRCDIR:= # 除了当前目录外,其他的源代码文件目录
# Now alter any implicit rules' variables if you like, e.g.:
CC:=g++
CFLAGS := -g -Wall -O3
CPPFLAGS := $(CFLAGS)
CPPFLAGS += $(addprefix -I,$(INCLUDES))
CPPFLAGS += -MMD
# The next bit checks to see whether rm is in your djgpp bin
# directory; if not it uses del instead, but this can cause (harmless)
# `File not found' error messages. If you are not using DOS at all,
# set the variable to something which will unquestioningly remove
# files.
RM-F := rm -f
# You shouldn't need to change anything below this point.
SRCS := $(wildcard .cpp) $(wildcard $(addsuffix /.cpp, $(SRCDIR)))
OBJS := $(patsubst %.cpp,%.o,$(SRCS))
DEPS := $(patsubst %.o,%.d,$(OBJS))
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.cpp,$(MISSING_DEPS)))
.PHONY : all deps objs clean veryclean rebuild info
all: $(EXECUTABLE)
deps : $(DEPS)
objs : $(OBJS)
clean :
@$(RM-F) *.o
@$(RM-F) *.d
veryclean: clean
@$(RM-F) $(EXECUTABLE)
rebuild: veryclean all
ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) :
@$(RM-F) $(patsubst %.d,%.o,$@)
-include $(DEPS)
$(EXECUTABLE) : $(OBJS)
$(CC) -o $(EXECUTABLE) $(OBJS) $(addprefix -L,$(LIBDIR)) $(addprefix -l,$(LIBS))
info:
@echo $(SRCS)
@echo $(OBJS)
@echo $(DEPS)
@echo $(MISSING_DEPS)
@echo $(MISSING_DEPS_SOURCES)