Linux系统编程入门2——makefile文件的使用

前言

本文是关于 makefile文件制作的相关介绍,makefile文件制作是很重要的需要熟练掌握的方法,熟练掌握可以很大的提供工作效率。本文所使用的环境为虚拟机 Ubuntu系统,使用 xshell 进行远程连接调试,所有示例均经过测试无误。

Makefile的使用

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,
Makefile 文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 Makefile 文件就像一个 Shell 脚本一样,也可以执行操作系统的命令。

如果后续程序更新了,就可以通过修改 makefile 文件来重新进行编译等操作,可以大大节省程序员的操作

make 是一个命令工具,是一个解释Makefile 文件中指令的命令工具,一般来说,大多数的 IDE 都有这个命令,比如 Delphi 的 make, Visual C++ 的 nmake, Linux 下 GNU 的 make

一般makefile文件的命名可以是makefile也可以是Makefile

makefile规则

一个 Makefile 文件中可以有一个或者多个规则

目标 ...: 依赖 ...
	命令(Shell 命令)

⚫ 目标:最终要生成的文件(伪目标除外)
⚫ 依赖:生成目标所需要的文件或是目标
⚫ 命令:通过执行命令对依赖操作生成目标(命令前必须 Tab 缩进)
Makefile 中的其它规则一般都是为第一条规则服务的。

在实际进行书写时一定要注意缩进格式

实例演示

下面使用这个程序来进行演示 makefile文件的使用

文件

首先是需要用到的文件列表如下,可能在以后的实际开发中,会涉及到更多的文件,是很难进行手动单个依次进行编译的,这里就需要用到makefile文件,进行统一的编译运行,下面是文件结构:
image

我们需要对这几个文件进行编译链接运行

由于头文件在预编译阶段就已经把内容都复制到代码中了,并且头文件就在当前路径下,也不需要特别去加它的路径了

制作makefile文件

使用命令

vim Makfile

来制作makefile文件,注意文件名,一定是 Makefile

下面是该文件的内容

 app:sub.c add.c mult.c div.c main.c
 	gcc sub.c add.c mult.c div.c main.c -o app 

解释如下
image

执行Makefile文件

使用命令

make

该命令会自动寻找该文件夹下的 Makefile 文件,然后进行执行,就可以生成 可执行程序,运行就可以得到程序运行结果了
image

工作原理

命令在执行之前,需要先检查规则中的依赖是否存在

  • 如果存在,执行命令
  • 如果不存在,向下检查其它的规则,检查有没有一个规则是用来生成这个依赖的,
    如果找到了,则执行该规则中的命令

基于这个原理,我们可以使用如下的Makefile文件,依赖需要的 .o 文件还未生成,程序就会自动到下面去找 .o 文件,然后生成

app:sub.o add.o mult.o div.o main.o
	gcc sub.o add.o mult.o div.o main.o -o app
sub.o:sub.c
	gcc -c sub.c -o sub.o
add.o:add.c
	gcc -c add.c -o add.o
mult.o:add.c
	gcc -c mult.c -o mult.o
div.o:div.c
	gcc -c div.c -o div.o
main.o:main.c
	gcc -c main.c -o main.o
检查更新

检测更新,在执行规则中的命令时,会比较目标和依赖文件的时间

  • 如果依赖的时间比目标的时间晚,需要重新生成目标
  • 如果依赖的时间比目标的时间早,目标不需要更新,对应规则中的命令不需要被执行

在写完 Makefile 文件之后,如果 .c 文件进行了更改,只要文件名没有发生变化,再次使用 make 命令的时候,就会自动比较生成时间,然后再次生成新的 可执行文件

在实际开发中,更推荐使用功能第二种 Makefile文件的写法,因为如果发生更改的话,可以快速找到被修改的文件,然后进行重新编译,而不会像第一种方法那样需要对整个项目进行重新编译生成

变量使用

为了使 Makefile文件使用更加方便,可以使用各种变量来实现快捷书写

自定义变量

变量名=变量值

var=hello
预定义变量

系统已经定义好的变量,可以直接使用

AR : 归档维护程序的名称,默认值为 ar
CC : C 编译器的名称,默认值为 cc
CXX : C++ 编译器的名称,默认值为 g++
$@ : 目标的完整名称
$< : 第一个依赖文件的名称
$^ : 所有的依赖文件

获取变量的值

$(变量名)

在使用变量之后,就可以大大简化书写过程了,现在讲上述文件修改为:

 # 定义变量
src=sub.o add.o mult.o div.o main.o
target=app
$(target):$(src)
	$(CC) $(src) -o $(target) 
sub.o:sub.c
	gcc -c sub.c -o sub.o
add.o:add.c
	gcc -c add.c -o add.o
mult.o:add.c
	gcc -c mult.c -o mult.o
div.o:div.c
	gcc -c div.c -o div.o
main.o:main.c
	gcc -c main.c -o main.o
clean:
	rm $(src)  
模式匹配

使用通配符 作为匹配的字符串

% 作为通配符使用,可以匹配一个字符串

两个 % 匹配的是同一个字符串

add.o:add.c
	gcc -c add.c
可以替换为:
%.o:%.c
	gcc -c $< -o $@

所以这样的话,Makefile文件就可以修改为如下这样:

# 定义变量
  src=sub.o add.o mult.o div.o main.o
  target=app
   
  $(target):$(src)
      $(CC) $(src) -o $(target) 
  
  %.o:%.c
      $(CC) -c $< -o $@

函数使用

使用

$(wildcard PATTERN...)
//获取指定目录下指定类型的文件列表

参数: PATTERN 指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔
返回:得到的若干个文件的文件列表,文件名之间使用空格间隔

$(pathsubst <pattern>,<replacement>,<text>)
//查找 <text> 中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换

可以包括通符%,表示任意长度的字串。如果中也包含%,那么, 中的这个%将是中的那个%
所代表的字串。 (可以用\来转义,以\%来表示真实含义的%字符)
返回:函数返回被替换过后的字符串

实例:

image
以及:
image

在使用上述文件进行修改之后,再进行加入清理操作之后,该 Makefile 文件如下

 # 定义变量
  2 src=$(wildcard ./*.c)
  3 objs=$(patsubst %.c,%.o,$(src))
  4 target=app
  5 
  6 $(target):$(src)
  7     $(CC) $(src) -o $(target)                                                                                                                     
  8 
  9 %.o:%.c
 10     $(CC) -c $< -o $@
 11 
 12 clean:
 13     rm $(objs) -f
  

如下是执行结果:
image

可以对 clean 命令添加尾执行 命令,使其在最后执行

.PHONY:clean
clean:
	rm $(objs) -f

最后

感谢观赏,一起提高,慢慢变强

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值