【Linux学习笔记】makefile学习笔记(一)

1. makefile与make基本介绍

在linux/unix开发环境中,makefile文件描述了一个特定编译系统所需要的策略,而make工具则是通过解析makefile文件并执行相应的命令来帮助我们构建其编译系统。大致原理如下:

1.makefile文件帮助我们记录了整个项目工程的所有需要编译的文件列表,这样我们在编译时仅需要输入简单的make命令就能编译出我们期望的结果;
2.makefile文件反映了整个项目中各个模块的依赖关系,这样我们改动了某些源文件后,仅需简单的输入make命令,make工具就会根据makefile文件里描述的依赖关系帮助我们分析哪些模块需要重新编译,并执行相应的操作。

1.1 makefile简介

makefile就是一个简单的文本文件,它基本上就是由一条条的规则构成。下面,我们就来看一下makefile里的最基本的语法单元:规则。一条makefile的规则构成如下:

target:prerequisites
<tab> command1
<tab> command2
.....
<tab> commandN

target: 规则的目标,可以简单理解为这条规则存在的目的是什么。通常是程序中间或者最后需要生成的文件的文件名,也可以不对应具体的文件,而仅仅就是个概念上的规则目标。
prerequisites: 规则的依赖列表,可以简单的理解为要达到本条规则的目标所需要的先决条件是什么。可以是文件名,也可以是其他规则的目标。
command: 规则的命令,可以简单地理解为当目标所需要的先决条件的满足了之后,需要执行什么动作来达成规则的目标。规则的命令其实就是shell命令。一条规则中可以有多行命令。(特别注意:每行命令都必须以tab键开始!)

1.2 make工作机理

要解释make的工作机理,需要解决以下3个问题:

1.make命令如何使用 ;
2.make从哪读取makefile;
3.make如何解析执行makefile文件的规则。

make命令的基本使用范式如下:

$ make [ -f makefile ] [ options ] ... [ targets ] ...

使用make命令的最简单的方式主要有以下四种形式:

1.不带任何参数,直接执行make:
$ make
2.指定makefile文件:
$ make -f <makefile_name>
3.指定 makefile 目标:
$ make <target>
4.到指定目录下执行make:
$ make -C <subdir> <target>

在执行make的时候,我们可以带上 -f <makefile_name>参数,来指定make命令从哪里读取makefile文件;而如果我们不显式指定,则make就会在当前目录下依次查找名字为GNUmakefile, makefile****和 Makefile的文件来作为其makefile文件。

在读取完makefile的内容后,make工具并不是一条一条地去执行makefile里的规则,而是以某条规则为突破口,以“多米诺骨牌”的方式去执行makefile里的规则。而这条作为突破口的规则的目标,称为终极目标 。我们可以在执行make时以参数的形式指定终极目标,从而执行作为突破口的规则。如果我们不显式地指定终极目标,make一般情况下将选择makefile的第一条规则的目标作为终极目标。

下面介绍一下make解析makefile的流程。

假设有一个mekefile文件,其文件框架如下所示:

终极目标:依赖A  依赖B 依赖C
    终极目标命令

依赖A:子依赖A1 子依赖A2 
    依赖A命令

依赖B:子依赖B1 子依赖B2 
    依赖B命令

依赖C:子依赖C1 子依赖C2 
    依赖C命令

步骤一: 以终极目标为树根,解析出整颗依赖树:
在这里插入图片描述
步骤二: 对整颗依赖树以从底到上,从左到右的顺序,解析执行每一条规则:
在这里插入图片描述

2. makefile实例一

本节将通过构建一个简单的c语言项目工程project_demo1来理解makefile的基本概念。

先来看一下project_demo1的整体目录结构。
在这里插入图片描述
构建项目的步骤如下:

步骤一: 创建工程目录
在这里插入图片描述
步骤二: 创建main.c文件,代码如下:

extern void hello();    //声明hello()函数是在文件外部定义的

int main()
{
    hello();
    return 0;
}

步骤三: 创建hello.c文件,代码如下:

#include <stdio.h>

void hello()
{
    printf("Hello, csdn!\n");
}

步骤四: 编写makefile

在每次编写makefile之前都需要先分析清楚整个工程各个模块的依赖关系,及相应的生成命令。project_demo1工程最终生成的是一个叫hello的可执行文件,而该可执行文件是使用gcc命令编译main.c和hello.c生成的。整个工程的关系依赖图如下:

在这里插入图片描述
因此makefile可以这么写:

hello: main.c hello.c
	gcc hello.c main.c -o hello

接下来在终端里输入make,终端打印出了makefile里的依赖命令,并生成了可执行文件hello.
运行hello,终端成功打印出我们所期望的语句,说明makefile编写正确。
在这里插入图片描述

3. makefile实例二

本节将创建另一个项目project_demo2,其文件之间的依赖关系相比上一个项目会更复杂一点。操作过程与上一个项目类似。先来看一下项目的整体目录结构:
在这里插入图片描述
main.c的代码如下:

#include <stdio.h>
#include "hello.h"
int main()
{
	printf("%s\n", HELLO);
	hello();
	return 0;
}

hello.c的代码如下:

#include <stdio.h>
#include "hello.h"
void hello()
{
    printf("%s\n", HELLO);
}

hello.h的代码如下:

#ifndef __HELLO_H__
#define __HELLO_H__
#define HELLO "Hello, csdn!"
#define GREET "How are you?"
extern void hello();
#endif

项目的依赖关系如下:
在这里插入图片描述

由此编写makefile如下:

hello: main.o hello.o
	gcc main.o hello.o -o hello

main.o: main.c
	gcc -c main.c -o main.o

hello.o: hello.c
	gcc -c hello.c -o hello.o

最后输入make指令,成功生成可执行文件hello,并且运行结果与程序相一致,说明makefile编写正确。
在这里插入图片描述

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Juicy B

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值