makefile
Posted hesper
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了makefile相关的知识,希望对你有一定的参考价值。
make
make : linux自带构建器, 构建规则在makefile中
makefile文件的命名: makefile, Makefile
makefile中的规则可分为三部分: 目标, 依赖, 命令
格式:
目标:依赖
(tab缩进)命令
工作原理:
检测依赖是否存在, 向下搜索规则, 如果有规则是用来生成查找依赖的, 执行规则中的命令
依赖存在: 判断是否需要更新, 原则是目标的时间要晚于依赖的时间, 否则需要更新
内部会有些构建的规则
变量定义:
自定义变量: obj=a.o b.o c.o
变量取值: aa=$(obj)
makefile自带变量: 一般大写, 有些被赋值, 有些没有赋值
CPPFLAGS: 头文件目录
CC
自动变量: 只能在命令中使用
[email protected]
: 规则中的目标
$<
: 规则中的第一个依赖
$^
: 规则中的所有依赖
命令参数:
命令后加-f
: 强制执行
命令前加-
: 忽略执行失败的命令, 继续向下执行其余的命令
模式匹配:
%.o:%.c
函数: makefile中的所有的函数都有返回值
查找指定目录下指定类型的文件: wildcard
src = $(wildcard ./*.c)
匹配替换: patsubst
obj = $(patsubst %.c, %c, $(src))
, 替换类型的文件, 要替换的类型的文件, 源文件
声明伪目标: 不做文件更新与是否存在的检查.PHONY
版本一
缺点: 效率地, 修改一个文件, 所有文件都会被全部重新编译
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
app:main.c add.c div.c mul.c sub.c
gcc main.c add.c div.c mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ make
gcc main.c add.c div.c mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c a.out div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ ./a.out
sum = 26
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
app:main.o add.o div.o mul.o sub.o
gcc main.o add.o div.o mul.o sub.o
main.o:main.c
gcc main.c -c
add.o:add.c
gcc add.c -c
div.o:div.c
gcc div.c -c
mul.o:mul.c
gcc mul.c -c
sub.o:sub.c
gcc sub.c -c
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ make
gcc main.c -c
gcc add.c -c
gcc div.c -c
gcc mul.c -c
gcc sub.c -c
gcc main.o add.o div.o mul.o sub.o
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c add.o a.out div.c div.o head.h main.c main.o makefile mul.c mul.o sub.c sub.o
[email protected]:~/dir_test/dir_test_1/src$ vim add.c # 只修改一个文件
[email protected]:~/dir_test/dir_test_1/src$ make # 只重新编译2个文件
gcc add.c -c
gcc main.o add.o div.o mul.o sub.o
缺点: 后面的编译.o文件命令冗余
版本二
使用自定义变量和匹配替换
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
obj = main.o add.o div.o mul.o sub.o
target = app
$(target):$(obj)
gcc $(obj) -o $(target)
%.o:%.c # 当需要的.o文件没有时, 会进行替换
gcc -c $< -o [email protected]
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ make
gcc -c main.c -o main.o
gcc -c add.c -o add.o
gcc -c div.c -o div.o
gcc -c mul.c -o mul.o
gcc -c sub.c -o sub.o
gcc main.o add.o div.o mul.o sub.o -o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c add.o app div.c div.o head.h main.c main.o makefile mul.c mul.o sub.c sub.o
使用自动变量
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
obj = main.o add.o div.o mul.o sub.o
target = app
$(target):$(obj)
gcc $^ -o [email protected]
# gcc $(obj) -o $(target)
%.o:%.c
gcc -c $< -o [email protected]
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ make
gcc -c main.c -o main.o
gcc -c add.c -o add.o
gcc -c div.c -o div.o
gcc -c mul.c -o mul.o
gcc -c sub.c -o sub.o
gcc main.o add.o div.o mul.o sub.o -o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c add.o app div.c div.o head.h main.c main.o makefile mul.c mul.o sub.c sub.o
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
obj = main.o add.o div.o mul.o sub.o
target = app
$(target):$(obj)
gcc $^ -o [email protected]
# gcc $(obj) -o $(target)
[email protected]:~/dir_test/dir_test_1/src$ make
cc -c -o main.o main.c
cc -c -o add.o add.c
cc -c -o div.o div.c
cc -c -o mul.o mul.c
cc -c -o sub.o sub.c
gcc main.o add.o div.o mul.o sub.o -o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c add.o app div.c div.o head.h main.c main.o makefile mul.c mul.o sub.c sub.o
版本三
使用makefile函数查找与替换
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
src = $(wildcard ./*.c)
obj = $(patsubst %.c, %.o, $(src))
target = app
$(target):$(obj)
gcc $^ -o [email protected]
# gcc $(obj) -o $(target)
%.o:%.c
gcc -c $< -o [email protected]
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ make
gcc -c mul.c -o mul.o
gcc -c main.c -o main.o
gcc -c add.c -o add.o
gcc -c div.c -o div.o
gcc -c sub.c -o sub.o
gcc mul.o main.o add.o div.o sub.o -o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c add.o app div.c div.o head.h main.c main.o makefile mul.c mul.o sub.c sub.o
版本四
添加清除功能, 编写一个清理项目的规则
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
src = $(wildcard ./*.c)
obj = $(patsubst %.c, %.o, $(src))
target = app
$(target):$(obj)
gcc $^ -o [email protected]
%.o:%.c
gcc -c $< -o [email protected]
hello:
echo "haha"
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ make
gcc -c mul.c -o mul.o
gcc -c main.c -o main.o
gcc -c add.c -o add.o
gcc -c div.c -o div.o
gcc -c sub.c -o sub.o
gcc mul.o main.o add.o div.o sub.o -o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c add.o app div.c div.o head.h main.c main.o makefile mul.c mul.o sub.c sub.o
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
src = $(wildcard ./*.c)
obj = $(patsubst %.c, %.o, $(src))
target = app
$(target):$(obj)
gcc $^ -o [email protected]
%.o:%.c
gcc -c $< -o [email protected]
clean:
rm $(obj) $(target)
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ make
gcc -c mul.c -o mul.o
gcc -c main.c -o main.o
gcc -c add.c -o add.o
gcc -c div.c -o div.o
gcc -c sub.c -o sub.o
gcc mul.o main.o add.o div.o sub.o -o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c add.o app div.c div.o head.h main.c main.o makefile mul.c mul.o sub.c sub.o
[email protected]:~/dir_test/dir_test_1/src$ make clean
rm ./mul.o ./add.o ./main.o ./div.o ./sub.o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
src = $(wildcard ./*.c)
obj = $(patsubst %.c, %.o, $(src))
target = app
$(target):$(obj)
gcc $^ -o [email protected]
%.o:%.c
gcc -c $< -o [email protected]
clean:
-mkdir /haha # 忽略执行失败的命令, 继续向下执行
rm $(obj) $(target)
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ make
gcc -c mul.c -o mul.o
gcc -c main.c -o main.o
gcc -c add.c -o add.o
gcc -c div.c -o div.o
gcc -c sub.c -o sub.o
gcc mul.o main.o add.o div.o sub.o -o app
[email protected]:~/dir_test/dir_test_1/src$ make clean
mkdir /haha # 忽略执行失败的命令, 继续向下执行
mkdir: cannot create directory ‘/haha’: Permission denied
makefile:11: recipe for target 'clean' failed
make: [clean] Error 1 (ignored)
rm ./mul.o ./add.o ./main.o ./div.o ./sub.o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ touch clean
[email protected]:~/dir_test/dir_test_1/src$ make clean
make: 'clean' is up to date.
版本五
声明伪目标: 不被做文件更新, 是否存在的检查
[email protected]:~/dir_test/dir_test_1/src$ cat makefile
src = $(wildcard ./*.c)
obj = $(patsubst %.c, %.o, $(src))
target = app
$(target):$(obj)
gcc $^ -o [email protected]
%.o:%.c
gcc -c $< -o [email protected]
.PHONY:clean
clean:
-mkdir /haha # 忽略执行失败的命令, 继续向下执行
rm $(obj) $(target)
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c clean div.c head.h main.c makefile mul.c sub.c
[email protected]:~/dir_test/dir_test_1/src$ make
gcc -c mul.c -o mul.o
gcc -c main.c -o main.o
gcc -c add.c -o add.o
gcc -c div.c -o div.o
gcc -c sub.c -o sub.o
gcc mul.o main.o add.o div.o sub.o -o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c add.o app clean div.c div.o head.h main.c main.o makefile mul.c mul.o sub.c sub.o
[email protected]:~/dir_test/dir_test_1/src$ make clean
mkdir /haha # 忽略执行失败的命令, 继续向下执行
mkdir: cannot create directory ‘/haha’: Permission denied
makefile:12: recipe for target 'clean' failed
make: [clean] Error 1 (ignored)
rm ./mul.o ./add.o ./main.o ./div.o ./sub.o app
[email protected]:~/dir_test/dir_test_1/src$ ls
add.c clean div.c head.h main.c makefile mul.c sub.c
进阶版
[email protected]:~/dir_test/dir_test_1$ cat makefile
target=app
CPPFLAGES=./include
path=./src
src=$(wildcard ./src/*.c)
obj=$(patsubst %.c, %.o, $(src))
$(target):$(obj)
gcc $^ -o [email protected]
%.o:%.c
gcc -c $< -I $(CPPFLAGES) -o [email protected]
[email protected]:~/dir_test/dir_test_1$ tree
.
├── include
│?? └── head.h
├── lib
├── makefile
└── src
├── add.c
├── div.c
├── main.c
├── mul.c
└── sub.c
3 directories, 7 files
[email protected]:~/dir_test/dir_test_1$ make
gcc -c src/mul.c -I ./include -o src/mul.o
gcc -c src/main.c -I ./include -o src/main.o
gcc -c src/add.c -I ./include -o src/add.o
gcc -c src/div.c -I ./include -o src/div.o
gcc -c src/sub.c -I ./include -o src/sub.o
gcc src/mul.o src/main.o src/add.o src/div.o src/sub.o -o app
[email protected]:~/dir_test/dir_test_1$ ls
app include lib makefile src
以上是关于makefile的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 NMake 样式 Makefile 的 clang-cl 无法回显