makefile: 项目的代码管理工具.
makefile的命名:
makefile/Makefile
makefile的规则:
三要素: 目标 依赖 命令
格式: 目标: 依赖条件
命令. #命令前要有一个tab.
makefile的三个自动变量:
$< -- 规则中的第一个依赖.
$@ -- 规则中的目标.
$^ -- 规则中的所有依赖.
# 只能在规则中的命令中使用.
makefile自己维护的变量(通常用大写字母命名变量):
CC = cc -- gcc
CPPFLAGs -- 预编译的参数.
CFLAGS -- 编译时使用的参数.
LDFLAGS -- 链接库使用的选项 -L -l
makefile的函数:
wildcard ./目录/*.c # 从指定目录中查找指定文件,并返回. 例: src=$(whildcard ./*.c)
patsubst ./*.c, ./*.o, $(src) # 匹配替换函数(将所有.c换成.o). 例:obj=$(patsubt ./*.c, ./*.o, $(src))
nodir path/文件. # 把展开的文件去掉路径信息. 例: dir=$(nodir $(src))
模式规则:
%.o:%.c
gcc -c $< -o $@
实例:
c程序结构:
makefile文件(1):
# 最简单的写法,但若在大项目中,一个文件修改,则全部需要重新编译,故不推荐此写法.
list: ./src/delete.c ./src/init.c ./src/insert.c ./src/length.c ./src/location.c ./src/print.c list.c
gcc ./src/delete.c ./src/init.c ./src/insert.c ./src/length.c ./src/location.c ./src/print.c list.c -o list -I ./include
makefile文件(2):
# 先编译成.o文件,再生成可执行文件,当有文件修改时,makefile会根据文件时间(比较目标文件和依赖文件修改时间)判断需不需要重新编译.
# 缺点: 若项目中有大量文件,过于费事.
list:list.o ./src/delete.o ./src/init.o ./src/insert.o ./src/length.o ./src/location.o ./src/print.o
gcc list.o ./src/delete.o ./src/init.o ./src/insert.o ./src/length.o ./src/location.o ./src/print.o -o list -I ./include
list.o:list.c
gcc -c list.c -I ./include
./src/delete.o:./src/delete.c
gcc -c ./src/delete.c -o ./src/delete.o -I ./include
./src/init.o:./src/init.c
gcc -c ./src/init.c -o ./src/init.o -I ./include
./src/length.o:./src/length.c
gcc -c ./src/length.c -o ./src/length.o -I ./include
./src/location.o:./src/location.c
gcc -c ./src/location.c -o ./src/location.o -I ./include
./src/print.o:./src/print.c
gcc -c ./src/print.c -o ./src/print.o -I ./include
./src/insert.o:./src/insert.c
gcc -c ./src/insert.c -o ./src/insert.o -I ./include
makefile文件(3):
# 使用变量,当target找不到依赖文件时会向下匹配,%会匹配需要的文件.
obj=list.o ./src/delete.o ./src/init.o ./src/insert.o ./src/length.o ./src/location.o ./src/print.o
target=list
$(target):$(obj)
gcc $(obj) -o $(target) -I ./include # 或 gcc $^ -o $@ -I ./include
%.o:%.c
gcc -c $< -o $@ -I ./include
# $< 规则中的第一个依赖, $@ 规则中的目标, $^规则中的所有依赖.
makefile文件(4):
# 使用wildcard 和patsubst函数,自动为变量赋值,不需要一个个手动输入,大大降低了工作量.
# 可以通过make clean 来调用makefile中的clean清理.o和可执行文件,但若文件夹中有clean文件/文件夹,则不能调用clean,可以使用.PHONY伪目标来避免.
src=$(wildcard ./src/*.c ./*.c)
obj=$(patsubst ./%.c, ./%.o, $(src))
target=list
CC = gcc
$(target):$(obj)
$(CC) $^ -o $@ -I ./include
# 与CC $(obj) -o $(target) -I ./include一样.
%.o:%.c
$(CC) -c $< -o $@ -I ./include
all:
@echo $(obj)
.PHONY: clean
clean:
rm -f $(target) $(obj)
# -rm # 命令前加上-若执行失败,继续向下执行.
# 若目录中有clean文件/目录,这该命令不能执行,通过伪目标解决(.PHONY:clean).
hello:
echo "Hello, makefile"