make的选项
- make -f mymakefile:make指定的文件
makefile语法规则
目标列表:依赖性列表
<TAB>命令列表
-
目标:一般指需要编译的目标,也可以是一个动作
- makefile默认只执行第一个目标
- 伪目标:它不是一个文件,只是一个标签
-
依赖:执行当前目标所要依赖的先项
- 一个目标可以有多个依赖,也可以没有依赖
- 依赖既可以是其他规则的目标,也可以是某个具体的文件,还可以是某个库
-
命令:可以没有,也可以是多条,一般,一条命令占据一行
- 若想当前命令结果作用于下一条命令:cmd1;cmd2
- 命令出错:并不意味着makefile语法出错,如若目录不存在时cd命令必然出错
- 当规则中某个命令出错时,make就会终止执行当前规则甚至所有规则
- 可在命令前添加一个减号,标记为不管命令是否出错,都认为是成功的,这样就不会影响后续命令的执行
makefile自定义变量
// =号:最基本的赋值方式
// ?=号:前边已经对该变量赋值过,则不执行本次赋值,否则执行
// :=号:覆盖式赋值,将当前赋值作为最新变量值
// +=号:追加赋值,旧值保持不变,将新值追加在后边
makefile维护的预定义变量
- 预定义变量的含义
CC:C编译器的名称,默认为cc
CPP:C预编译器的名称,默认值为$(CC) -E
CXX:C++编译器的名称,默认值为g++
CFLAGS:C编译器的选项,无默认值
CPPFLAGS:C预编译器的选项,无默认值
CXXFLAGS:C++编译器的选项,无默认值
RM:文件删除程序的名称,默认值为rm -f
LDFLAGS:链接器的选项,
- 预定义变量的用法
- CC = gcc
- CFLAGS+=-c -Wall -g
- CFLAGS += -I /mydir/includ:指定头文件所在目录
makefile内置变量
- $@:当前目标的名称
- $<:依赖性列表中的第一个文件
- $^:用空格分开的所有依赖性列表
- $?:时间戳比目标文件新的所有依赖文件,以空格分开
- $* 不包含扩展名的目标文件
- $+ 所有依赖文件,以空格分开,可能包含重复文件
模式字符串替换函数
$(patsubst <pattern>,<replace>,<text>)
// obj = $(patsubst %.c,%.o,$(src)),将src中所有.c文件替换成.o文件
// 此式子中的%.c就是pattern,%.o就是replace,text就是$(src)
// pattern可包含通配符,pattern中的%表示任意长度的字符串
// replace以包含通配符,replace中的%是pattern中那个%所代表的字符中
$(wildcard <pattern>)
// src = $(wildcard *.c)
// src = 当前目录下所有.c文件,用空格隔开
$(filter <pattern>,<text>)
// 字符串过滤函数,filter-out反过滤函数
// 1. 对text过滤,保留符合text中符合pattern的单词
// 2. gcc $(filter %.c %.s,$(src)) -o target,保留符合%.c和%.s的
$(sort <list>)
// 排序函数,将list中单词按首字母升序排序
$(dir <names...>)
// $(dir /usr/hello.c)
// 取目录函数:,返回为/usr/
$(notdir /usr/hello.c)
// 取文件名函数,返回值为hello.c
$(suffix /usr/hello.c hello.s)
// 取后缀名函数,返回值为.c .s
$(basename /usr/hello.c)
// 取前缀名函数,返回值为/usr/hello
$(addsuffix .c,hello world)
// 加后缀,返回结果为hello.c world.c
$(addprefix /usr/,hello.c)
// 加前缀,返回结果为/usr/hello.c
自定义函数
// 函数基本语法:函数名与函数参数之间用空格隔开,参数之间用逗号隔开
$(<function> <arguments>)
// 自定义函数举例:
define myfunc
@echo "xxxxxx"
@echo $(0) // 第1个参数
@echo $(1) // 第2个参数
endef
// 调用:$(call myfunc,1,2)
.c与.o文件的关联
// 1、
src = $(wildcard ./*.c) // 获取当前目录下所有.c文件
obj = $(patsubst %.c,%.o,$(src))// 获取src中所有.c文件名,替换成.o文件名
%.o:%.c
// 2、
.SUFFIXES:.c.o // 声明,.c与.o文件是有关系的
src = $(wildcard ./*.c)
obj = $(src:.c=.o)
.c.o: // 只要依赖是.o文件的,都执行这标号下的把.c编译成.o文件的命令
makefile-v1
src=$(wildcard *.c)
obj=$(patsubst %.c,%.o,$(src))
# 借助$(target)可删除茂名名称不为mytarget的可执行文件
target=$(patsubst %.c,%,$(src))
exec=mytarget
CC=gcc
CFLAGS+=-c -Wall -g
$(exec):$(obj)
$(CC) $^ -o $@
@echo "链接成功"
%.o:%.c
$(CC) $(CFLAGS) $<
@echo "编译成功!"
.PHONY:clean
clean:
$(RM) -rf $(obj)
$(RM) -rf $(exec)
# $(RM) -rf $(target)
@echo "删除成功!"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律