- 什么是Makefile
1,Makefile被称为工程管理文件。简单来说,Makefile就是对工程进行管理的一个脚本,对工程实现”一键编译”!有一套自己的规则和逻辑!
- 什么时候用?
在工程的文件越来越多时,编译命令会越来越复杂,此时可以考虑使用Makefile提高编译的效率!
第一次编译工程时,会把所有的文件都从头到尾编译一次!
第二次开始编译的时候,Makefile就只会去编译发生修改的文件,没有修改的文件不去重新编译!
如果整个工程都没有发生变化,那么就不重新编译!
3,Makefile不是必要的!
- Makefile基本规则
- 文件名
Makefile --> makefile (文件名是固定的,并且没有后缀名!)
- Makefile的核心思想
Makefile的核心思想是目标与依赖!
目标:使用Makefile想要得到的东西! --> 一般是指最终的可执行文件
依赖:想要得到目标需要使用的相关文件 --> 一般是工程的源文件
想要得到目标文件,那需要对依赖文件进行某种规则的处理!
- Makefile编写规则
==> 准备一个Makefile文件!
==> 目标:依赖
==> <Tab>规则 ==> 默认使用Makefile的时候,会打印规则的内容!
例如: 写一个简单的Makefile,实现 gcc main.c -o main
注意事项:
- 目标必须要有一个或一个以上!不能没有。
- Makefile会检查源文件的更新时间,如果源文件没有改变,那么编译的时候就不会编译
- 如果一个Makefile中有多个目标,那么在make的时候可以指定去编译某一个目标,如果没有指定,直接make,默认会去执行第一个目标!
- Makefile变量
1,最常用的变量 $@ 和 $^ (在规则中使用)
==> $@ : 目标
==> $^ : 依赖
==> 如果一个工程中依赖文件有多个,那么依赖文件之间使用空格隔开!
==>例如: gcc main.c fun.c usr.c -o main
2,自定义变量
1)自定义变量的时候不需要给变量指定类型
==> C 语言中定义变量 类型 变量名 = 值; --> int a = 10;
==> Makefile中的变量 变量名 = 值; 默认都是字符串类型!
例如: AAA = hello
变量名命名规则:
- 数字字母下划线组成!
- 大小写敏感 --> src Src
# 是Makefile中的注释,相当于C语言的 //
例子: 在一个Makefile中定义几个变量,然后输出这些变量!
==> 练习1: 参考笔记,写一个makefile, 把依赖文件main.c , usr.c, fun.c 使用变量SRC, 目标main 用变量名 Target, 实现这样的规则 gcc main.c usr.c fun.c -o main
提示:先定义变量,然后写 目标:依赖 <Tab>规则
3,预定义变量
CC --> cc (相当于gcc)
RM --> rm -rf
思考:回顾一下静态库动态库内容,设计一个Makefile脚本,实现将源文件 usr.c , fun.c 生成一个静态库 libfun.a
==> 静态库编译步骤:
- 源文件编译生成二进制 --> 目标:fun.o usr.o 依赖:fun.c usr.c
-
- gcc -c fun.c -o fun.o
- gcc -c usr.c -o usr.o
-
- 把二进制文件处理得到静态库 --> 目标:libfun.a 依赖:fun.o usr.o
ar -cr libfun.a fun.o usr.o
参考资料:
- C语言工程模板
在项目开发中,对于项目文档的整理归档是一项非常重要的事情,如果一个项目的文件弄得很乱,那么对于项目的开发效率以及后期维护是一件非常头疼的事情!我们在设计一个C语言工程的时候,一般会给这个C语言工程创建以下文件夹用来存放工程文件。
Src : 用来存放工程的源文件 (xx.c)
Include : 存放工程的头文件 (xx.h)
Lib : 存放工程的库文件 (libxxx.a , libxxx.so)
Bin : 存放目标文件 (可执行文件)
Share : 存放相关资料文件
Makefile : 工程管理文件 (实现一键编译!)
==> 设计一个C语言模板,将示例代码存放进去!为这个模板编写Makefile脚本!
五,Makefile的函数
1,函数的使用格式
$(函数名 参数1, 参数2, 参数3)
==> wildcard : 函数功能是将表达式中的文件名获取出来
==> SRC = $(wildcard src/*.c)
例如: src 目录下有 main.c , fun.c, usr.c
==> SRC = src/main.c src/fun.c src/usr.c
==> patsubst : 完成文件名的替换
==> OBJ = $(patsubst %.c, %.o, $(SRC)) ==> 把所有的.c 对应的替换成.o 文件
==> OBJ = src/main.o src/fun.o src/usr.o
C语言工程模板:
通用版本的Makefile
==> 如果自己写了一个工程,把所有的源文件放到模板的 src 目录下, 把所有的头文件放在模板的 include 目录下, ==> 然后直接make可以得到目标文件
==> 例子: 把student_project 工程放到C语言工程模板中。
- 将C语言工程模板复制一份,把里面的文件全部删除,只留下框架
Makefile , src/, include/, lib/, bin/, share/
- 把student_project 的所有的 .c 文件复制粘贴到 src目录下,把所有的.h文件放到 include目录下。
3)直接make --> 得到可执行文件 bin/main