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)

 posted on 2025-03-21 14:50  哈哈哈119  阅读(33)  评论(0)    收藏  举报