linux_makefile文件编写,基本规则、工作原理、模式规则,wildcard函数、patsubst函数

接上一篇:linux_GDB调试学习(调试运行、多文件设置断点)_C/C++程序调试

本次来分享linux下的makefile文件的编写,开始上菜:

目录

  • 1.makefile文件的命名规则
  • 2.用途
  • 3.基本规则
  • 3.1.用例一
  • 4.工作原理
    • 4.1.用例二
  • 5.makefile的执行
    • 5.1.用例三
  • 6.makefile的变量
    • 6.1.普通变量
    • 6.2.自动变量
    • 6.3.用例四
  • 7.makefile函数-两个常用函数
    • 7.1.wildcard函数
    • 7.2.patsubst函数
    • 7.3.用例五

使用前请安装make,安装命令:sudo apt install make

1.makefile文件的命名规则

   ①要么第一个字母大写,剩余字母小写,例如:Makefile
   ②要么全部字母小写:makefile

2.用途

   ①项目代码编译管理
   ②节省编译项目的时间
   ③一次编写终身受益

3.基本规则

(1)格式:
目标:依赖
   (tab)命令

(2)解释:

目标 --> 要生成的目标文件
依赖 --> 生成目标文件需要的一些文件
命令 --> 借助依赖文件生成目标文件的手段
tab --> 缩进,在第二行开始

Makefile会把规则中的第一个目标作为终极目标
app:依赖 #指定生成的最终目标为app

3.1.用例一

写该用例前请自己先创建add.c、sub.c、main.c源文件,否则执行makefile的时候会出错。
创建一个makefile文件,在其中添加如下内容:
mycalc:add.c sub.c main.c -o mycalc
   gcc add.c sub.c main.c -o mycalc

#该代码功能:(在makefile文件中用#进行注释)
#执行gcc add.c sub.c main.c -o mycalc命令,生成mycalc可执行文件

4.工作原理

   ①若想生成目标,检查规则中的依赖条件是否存在,
   ②如果不存在,寻找是否有规则用来生成该依赖文件
   ③检查规则中的目标是否需要更新,必须检查它的所有依赖,
   ④依赖中有任意一个被更新,则目标必须更新
   ⑤依赖文件比目标文件时间晚,则需要更新

make怎么知道哪个文件被更新了?
   make根据文件修改的时间来进行对比的,源文件生成的时间<.o生成的时间<最终目标生成的时间,这样就知道哪个文件被修改了,可看用例二。

4.1.用例二

写该用例前请自己先创建main.c、add.c、sub.c、mul.c源文件,否则执行makefile的时候会出错。
创建一个makefile文件,在其中添加如下内容:
app:main.o add.o sub.o mul.o
   gcc main.o add.o sub.o mul.o -o app
main.o:main.c
   gcc -c main.c
add.o:add.c
   gcc -c add.c
mul.o:mul.c
   gcc -c mul.c
sub.o:sub.c
   gcc -c sub.c

linux_makefile文件编写,基本规则、工作原理、模式规则,wildcard函数、patsubst函数_第1张图片

解释说明:
   ①make先检查main.o add.o sub.o mul.o是否存在,若是不存在,则会向下寻找是否有用来生成该依赖条件的文件;
   ②第4行到第14行都是对第一行的依赖条件的生成,make就会去找这些行依赖;
   ③使用该种方法,第一次编译后,若是main.c或者其他某单个文件被修改(make会对比文件修改的时间),只会编译对应的单个文件,就不会全部文件都被编译一次,这样更节省时间。

注意:生成终极目标的规则一定要写在第一行,在这里app就是我们需要生成的终极目标,若是写在其他行,我们的终极目标就变了。

5.makefile的执行

make的执行命令如下:

make				#makefile文件的路径下,终端执行命令:
make +objname		#执行makefile文件中的objname目标

使用方法请看用例三

5.1.用例三

写该用例前请自己先创建main.o、add.c、sub.c、mul.c源文件,否则执行makefile的时候会出错。
创建一个makefile文件,在其中添加如下内容:
app:main.o add.o sub.o mul.o
   gcc main.o add.o sub.o mul.o -o app
main.o:main.c
   gcc -c main.c
add.o:add.c
   gcc -c add.c
mul.o:mul.c
   gcc -c mul.c
sub.o:sub.c
   gcc -c sub.c
clean:
   rm main.o add.o sub.o mul.o

这个时候,终端执行命令:
make   #是编译.c文件
终端执行命令:
make clean   #就会删除掉main.o add.o sub.o mul.o这四个文件。

问题1:
如果当前目录下有同名clean文件会怎么样?
答:报错:clean已是最新,即不执行clean对应的命令。

解决方案:
添加伪目标声明代码:.PHONY:clean
makefile文件中的代码更改如下:
app:main.o add.o sub.o mul.o
   gcc main.o add.o sub.o mul.o -o app
main.o:main.c
   gcc -c main.c
add.o:add.c
   gcc -c add.c
mul.o:mul.c
   gcc -c mul.c
sub.o:sub.c
   gcc -c sub.c
.PHONY:clean    #伪目标声明
clean:
   rm main.o add.o sub.o mul.o -f    #-f是强制执行这个命令,无论有没有这些.o文件

这样就不会出现上述问题了。

问题2:
   在执行makefile的时候,当你执行完一条命令出错后,就不会在执行剩下的命令了,这时候,我们在命令的前面加入特殊-,表示此条命令出错,make也会继续执行后续的命令。如:“-rm a.o b.o”

6.makefile的变量

6.1.普通变量

变量定义及赋值:obj = a.o b.o c.o
变量取值:fobj = $(obj)

由 Makefile 维护的一些变量,通常格式都是大写
例如:
   CC =cc   #系统变量CC默认为cc,也就是gcc
有些有默认值,有些没有
   CPPFLAGS : 预处理器需要的选项 如:-I
   CFLAGS:编译的时候使用的参数 –Wall –g -c
   LDFLAGS :链接库使用的选项 –L -l

用户可以修改这些变量的默认值
CC = gcc

(请看用例四。)

6.2.自动变量

1、自动变量规则:
   $@    #规则中的目标
   $<    #规则中的第一个依赖条件
   $^    #规则中的所有依赖条件

都是在规则中的命令中使用
2、模式规则
   在规则的目标定义中使用   %
   在规则的依赖条件中使用   %

3、示例:
%.o:%.c
$(CC) –c $< -o $@
   $<   #表示依次取出依赖条件
   $@  #表示依次取出目标值
   %    #表示一个或者多个
   $^    #规则中的所有依赖

如图:
linux_makefile文件编写,基本规则、工作原理、模式规则,wildcard函数、patsubst函数_第2张图片
linux_makefile文件编写,基本规则、工作原理、模式规则,wildcard函数、patsubst函数_第3张图片

(请看用例四。)

6.3.用例四

现将用例三中makefile的代码做如下修改:

obj=main.o add.o sub.o mul.o
target=app
CC = gcc
$(target):$(obj)
	$(CC) $(obj) -o $(target)
%.o:%.c
	$(CC) -c $< -o $@
.PHONY:clean		#伪目标声明
clean:
	rm main.o add.o sub.o mul.o -f

(这样一写是不是就看着简洁很多了~~)
执行的功能效果和用例三是一样的。

7.makefile函数-两个常用函数

   makefile中所有的函数必须都有返回值,在这里介绍两个常用的函数。

7.1.wildcard函数

查找指定目录下指定类型的文件,该函数有一个参数
用法:src = $(wildcard ./src/*.c)
#找到./src 目录下所有后缀为.c的文件,赋给变量src,其中./src/*.c就是该函数的参数了

7.2.patsubst函数

匹配替换,从src中找到所有.c 结尾的文件,并将其替换为.o
用法:
#把src变量中所有后缀为.c的文件替换成.o
   obj = $(patsubst %.c ,%.o ,$(src))

#指定.o 文件存放的路径 ./obj/%.o
   obj = $(patsubst %.c, ./obj/%.o, $(src))

注意:在写目标的时候,也需要加上路径
./obj/%.o:%.c

当然,makefile的函数肯定不止这些,这里只是介绍两个常用的。

7.3.用例五

现将用例四中makefile的代码做如下修改:

target=app
src=$(wildcard ./*.c)
obj=$(patsubst ./%.c, ./%.o, $(src))
CC = gcc
$(target):$(obj)
	$(CC) $(obj) -o $(target) -I./1
%.o:%.c
	$(CC) -c $< -o $@
.PHONY:clean		#伪目标声明
clean:
	rm main.o add.o sub.o mul.o -f

(执行的功能效果和用例四是一样的。)

以上就是本次的分享了,希望对广大网友有帮助。

此博主在CSDN发布的文章目录:【我的CSDN目录,作为博主在CSDN上发布的文章类型导读】

你可能感兴趣的:(Linux笔记,linux,ubuntu,运维)