1.Makefile项目管理工具
1.1 是一种项目管理脚本语言
- 1.优点
- 1.便于编译管理代码;
- 2.节省编译时间(生成.o文件的时间);
- 3.复用性强;
1.2 项目编译链接流程
- 1.首先由多个 .c 文件生成对应的 .o 文件;
- 2.其次根据 main.c 文件生成 _START 文件;
- 3.由 _START 文件通过 ld链接器 链接库文件,生成 a.out 可执行文件;
1.3 为什么使用makefile
- 因为庞大的项目中有无数源文件需要生成核心二进制文件,需要耗费大量时间,可是使用makefile来减少这种时间开销。
1.4 第一个 makefile 文件
- 1.首先新建一个 01-test.c 文件;
#include <stdio.h>
int main()
{
printf("Hello!\n");
return 0;
}
- 2.新建一个 Makefile 文件;
all:01-test.c
gcc 01-test.c -o app
- 3.在终端上输入 make ,发现有以下输出:
gcc 01-test.c -o app
- 4.并且当前目录下生成了一个新的 app 可执行文件,输入 ./app 即可看到 Hello 输出,证明我们的makefile可以正常工作。
1.5 Makefile 三要素
- 1.all 冒号左边的称为目标;
- 2.01-test.c 冒号右边的叫做依赖;
- 3.table分隔符起始行称为命令;
1.6 建立一个完整的 Makefile 项目
- 1.新建三个文件夹: include src lib ;
- 2.在 include 文件夹中创建一个 include.c 文件,其中写上四个函数声明:
#include <stdio.h>
int Add(int, int);
int Sub(int, int);
int Mul(int, int);
int Div(int, int);
- 3.在 src 文件夹下新建四个文件: Add.c Sub.c Mul.c Div.c ,其中分别是各个函数的定义:
- Add.c
#include <include.c>
int Add(int a, int b)
{
return a + b;
}
- Sub.c
#include <include.c>
int Sub(int a, int b)
{
return a - b;
}
- Mul.c
#include <include.c>
int Mul(int a, int b)
{
return a * b;
}
- Div.c
#include <include.c>
int Div(int a, int b)
{
return a / b;
}
- 4.在 src 文件夹下新建一个 main.c 文件,用于作为主函数来调用其他四个函数;
#include <include.c>
int main()
{
printf("10 Add 5 Result:%d\n", Add(10, 5));
printf("10 Sub 5 Result:%d\n", Sub(10, 5));
printf("10 Mul 5 Result:%d\n", Mul(10, 5));
printf("10 Div 5 Result:%d\n", Div(10, 5));
return 0;
}
- 5.下面要进行编译文件,我们需要编译所有的 .c 文件,并且由于 include.c 文件与 src 下需要编译的文件不在同一文件夹下,因此在编译时需要指定库目录,使用 gcc 下的 -I 选项来指定库目录,我们在 src 文件夹下输入下面一行命令来进行编译:
gcc *.c -I ../include/ -o app
-
其中涉及一个gcc编译时的小知识: -I 可以将指定的库路径加入到搜索范围中;
-
6.在 src 文件夹下新建一个 Makefile 文件,注意:这里的名字可以是 Makefile makefile 两种,其他的诸如 maKefile makeFile 等均非法;
# VERSION:1.0 最简单的makefile
all:*.c
gcc *.c -I ../include/ -o app
- 在 src 文件夹下,输入 make 命令,发现输出一行 gcc *.c -I …/include/ -o app 语句,并且文件夹下生成了一个新的 app 可执行文件,运行该可执行文件会得到与直接在命令行输入 gcc *.c -I …/include/ -o app 相同的结果。
1.7 更新当前版本的 makefile
- 1.VERSION 1.0 版本的makefile并没有让我们感觉会减少编译时间,因此我们更改依赖项:
# VERSION:2.0 分开编译的版本
all:add.o sub.o mul.o div.o main.o
gcc add.o sub.o mul.o div.o main.o -o app
add.o:add.c
gcc -c -I ../include/ -o add.c
sub.o:sub.c
gcc -c -I ../include/ -o sub.c
mul.o:mul.c
gcc -c -I ../include/ -o mul.c
div.o:div.c
gcc -c -I ../include/ -o div.c
main.o:main.c
gcc -c -I ../include/ -o main.c
- 2.以上代码涉及到一个gcc编译的知识点:-c 选项是用来生成 .c 文件的 .o 中间文件的选项;
- 3.注释掉 VERSION 1.0 版本的代码段,注意:在 makefile 文件中,注释标志为 # 而不是 // ;
- 4.在 src 文件夹下 make ,会发现以下输出:
gcc add.o sub.o mul.o div.o main.o -o app
gcc -c -I ../include/ -o add.c
gcc -c -I ../include/ -o sub.c
gcc -c -I ../include/ -o mul.c
gcc -c -I ../include/ -o div.c
gcc -c -I ../include/ -o main.c
- 5.在 src 文件夹下会生成一个 app 可执行文件(前提是将之前的 app 文件删除),运行可得与之前相同的结果;
- 6.更改其中的 main.c 函数,新加一行 printf(“hello\n”); 再次 make ,发现只有两行输出:
gcc add.o sub.o mul.o div.o main.o -o app
gcc -c -I ../include/ -o main.c
- 这说明其他为被修改的文件都没有再次进行编译,也就是说本次的 makefile 会自动检测哪些文件被修改,需要重新编译,因此会减少编译所需要的时间;
1.8 makefile 执行原理
- 自顶向下分析依赖,自底向上执行命令
- 一个 makefile 中只能有一个目标(默认执行第一个目标,若存在多个目标),若多个目标之间存在依赖关系, make 认为其是一个目标进行执行;
1.9 makefile 节省时间的原理
- makefile遵循一个基本规则:目标的时间比依赖的时间要新,若不满足则重新执行语句,否则不执行语句;
1.10 在主文件夹下(与include lib src文件夹同级目录)新建一个makefile文件
- 1.这个 makefile 文件称为 管理者 ,是用来管理其他文件夹下的 makefile 的;
- 2.在管理者中对 src 文件夹下的makefile进行编译;
all:./src
make -C ./src
- 3.管理者可以调度执行指定文件夹下的 makefile 脚本。