Linux-开发与管理 P4 Makefile基础

Linux-开发与管理 P4 Makefile基础

在这里插入图片描述

简介

在这里插入图片描述

Makefile是一个工具程序,它是一种转化文件形式的工具,转换的目标称为target

而对于Makefile另一个重要的内容就是目标间的依赖关系

编译与链接

不过在讲Makefile之前,要先来回顾一下GCC编译的内容,对于GCC中讲解的5个步骤,这里可以将其简单的看成两个步骤

第一个就是将.c文件编译(compile)成.o文件
然后是通过链接各个.o文件链接成可执行文件或者.out文件

在这里插入图片描述

编译

进行编译时,会判断语法是否正确,函数与变量的声明是否正确,还要告诉编译器头文件所在的位置;判断所有的编译的结果都正确时,编译器就会编译出中间目标文件.o文件

链接

链接时,链接所有的.o文件,链接里面的函数和全局变量,然后通过链接它们生成可执行文件

Makefile介绍

什么是Makefile呢?

Makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为Makefile就像一个shell脚本一样,其中也可以自行操作系统的命令

Makefile工作流程

这里通过一个栗子来看看Makefile的简单工作流程

首先创建一个Makefile文件(这里注意文件名必须是Makefile,M必须大写
在这里插入图片描述

然后进入到Makefile里面进行编程(记住echo前必须使用Tab键

在这里插入图片描述

main:
	echo "Hello World!"

使用make来查看效果,这里显示了代码段和执行结果

在这里插入图片描述

然后这里做一点扩展

在这里插入图片描述

main:
	@echo "Hello World!"
cage:
	@echo "Hello Cage!"

查看效果

在这里插入图片描述

这里使用了@之后,指令就不会在make的时候出现,然后cage目标只有在指定的时候才会显示结果,所以在执行make指令时,会默认执行第一个目标,那如何也执行cage目标呢?

这里做进一步的改进

在这里插入图片描述

main:cage
	@echo "Hello World!"
cage:
	@echo "Hello Cage!"

查看效果
在这里插入图片描述
这样就是一个简单的Makefile基本结构,下面会详细讲解,这里cage写在main:后面,表明了cage与main之间的依赖关系

基本规则

在这里插入图片描述

基本规则

Makefile编辑的基本规则

target:prerequisites
command

target:目标文件,可以是.o文件,也可以是执行文件,还可以是标签
prerequistes:生成目标文件所需要的文件或目标
command:是目标所执行的命令

编译单个文件

首先编写一个.c文件的栗子,然后对其进行Makefile的方式进行编译

在这里插入图片描述

#include <stdio.h>

int main(int argc, const char *argv[])
{
	printf("Hello Cage!\n");	
	return 0;
}

然后编写Makefile

在这里插入图片描述

main:main.o
	gcc main.o -o main
main.0:
	gcc -c main.c -o mian.o
clean:
	rm *.o

查看效果

在这里插入图片描述

这里通过clean目标可以对.o文件进行清理,也看到了程序的执行结果

对多个文件编译

好的,对于一个文件进行编译后,发现并没有比直接进行gcc要简单多少,但是当我增加编译的文件数量增加时,就会发现Makefile的优点

同样,这里编写一个多文件结构

all.h

#ifndef __ALL_H__
#define __ALL_H__
#include <stdio.h>

int my_add(int a,int b);
int my_sub(int a,int b);


#endif

myadd.c

#include <stdio.h>
#include "all.h"

int my_add(int a,int b){
	int s;
	s = a + b;
	return s;
}

mysub.c

#include <stdio.h>
#include "all.h"

int my_sub(int a,int b){
	int s;
	s = a - b;
	return s;
}

main.c

#include <stdio.h>
#include "all.h"

int main(int argc, const char *argv[])
{
	int x = 100,y = 50;
	int s1,s2;
	s1 = my_add(x,y);
	s2 = my_sub(x,y);
	printf("x+y=%d\nx-y=%d\n",s1,s2);
	return 0;
}

Makefile

main:main.o myadd.o mysub.o
	gcc -o main main.o myadd.o mysub.o
main.o:main.c all.h
	gcc -c main.c
myadd.o:myadd.c all.h
	gcc -c myadd.c
mysub.o:mysub.c all.h
	gcc -c mysub.c
clean:
	rm *.o

然后就可以开始进行测试

在这里插入图片描述

Makefile工作原理

以上面的栗子来看看Makefile到底是怎么工作

1.当输入make的时候,会在当前目录下寻找名字叫做Makefile的文件
2.找到Makefile文件之后,找到文件里的第一个目标,也就是mian目标
3.然后寻找第一个目标对象的依赖的目标或者内容,也就是mian.o、myadd.o、mysub.o
4.分别找到对应mian.o、myadd.o、mysub.o,并根据依赖文件进行后面的指令,生成对应的目标文件,然后传回第一个目标进行最最的指令,完成Makefile工作
5.然后就生成了main可执行文件,然后通过make clean来清理.o中间文件

变量

在这里插入图片描述

为了方便使用,Makefile中也有变量,可以在Makefile中通过使用变量来使得它更简洁、更具可维护性

自动变量

对于很多目标和文件会在Makefile中多次出现,所以可以使自定义变量

变量功能
$@用于表示一个规则中的目标;当一个规则中有多个目标时,则指的是其中任何造成命令被运行的目标
$^表示的是规则中的所有选择条件
$<表示的是规则中的第一个先决条件

包括这些还能进行自行定义变量

CC = gcc

通过

$(CC)

来调用

这里对上面的栗子进行简化和修改

在这里插入图片描述

CC = gcc
RM = rm
OBJ = main
OBJS = main.o myadd.o mysub.o

$(OBJ):$(OBJS)
	$(CC) -o $@ $^
main.o:main.c all.h
	$(CC) -c $^ 
myadd.o:myadd.c all.h
	$(CC) -c $^ 
mysub.o:mysub.c all.h
	$(CC) -c $^ 
clean:
	$(RM) $(OBJS)

重新来测试程序运行的效果

在这里插入图片描述

预定义变量

Makefile预定义变量包含了常见编译器汇编器的名称及其编译选项

预定义变量表

命令格式功能
AR库文件维护程序的名称,默认值为ar
AS汇编程序的名称,默认值为as
CCC汇编器的名称,默认值为cc
CPPC预编译器的名称,默认值为$(CC)-E
CXXC++编译器的名称,默认值为g++
FCFORTARAN编译器的名称,默认值为f77
RM文件删除程序的名称,默认值为rm -f
ARFLAGS库文件维护程序的选项,无默认值
ASFLAGS汇编程序的选项,无默认值
CFLAGSC编译器的选项,无默认值
CPPFLAGSC预编译的选项,无默认值
CXXFLAGSC++编译器的选项
FFLAGSFortran编译器的选项,无默认值

自动推导和隐含规则

这里将会在Makefile进阶里做进一步讲解

结构与工作方式

这里将会在Makefile进阶里做进一步讲解

更多内容

Linux-开发与管理 P1 shell编程

Linux-开发与管理 P2 GCC编译器

Linux-开发与管理 P3 GDB调试器

Linux-开发与管理 P4 Makefile基础

Linux-开发与管理 P5 软件管理

Linux-开发与管理 P6用户管理

Linux-开发与管理 P7 文件系统

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CagePan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值