Linux系统编程makefile的使用规则和编写

目录

1.1makefile使用规则

第一个版本makefile

1.2makefile原理

第二个版本makefile 

1.3 makefile中的变量

第三个版本makefile

1.4 makefile函数

 第四个版本makefile 

1.5 makefile清理操作

第五个版本makefile

makefile文件中定义了一系列的规则来指定, 哪些文件需要先编译, 哪些文件需要后编译, 哪些文件需要重新编译, 甚至于进行更复杂的功能操作, 因为makefile就像一个Shell脚本一样, 其中也可以执行操作系统的命令.  makefile带来的好处就是——“自动化编译”, 一旦写好, 只需要一个make命令, 整个工程完全自动编译, 极大的提高了软件开发的效率.

make是一个命令工具, 是一个解释makefile中指令的命令工具, 一般来说, 大多数的IDE都有这个命令, 比如:Visual C++的nmake, Linux下GNU的make. 可见, makefile都成为了一种在工程方面的编译方法.

makefile文件中会使用gcc编译器对源代码进行编译, 最终生成可执行文件或者是库文件.

makefile文件的命名:makefile或者Makefile

1.1makefile使用规则

目标: 依赖

tab)命令

makefile基本规则三要素:

  • 目标: 要生成的目标文件
  • 依赖: 目标文件由哪些文件生成
  • 命令: 通过执行该命令由依赖文件生成目标

下面以具体的例子来讲解:

当前目录下有main.c fun1.c fun2.c sum.c, 根据这个基本规则编写一个简单的makefile文件, 生成可执行文件main.

第一个版本makefile

#第二行开头一定是tab 而不能是空格
main:main.c fun1.c fun2.c sum.c
    gcc -o main main.c fun1.c fun2.c sum.c
    

1.2makefile原理

基本原则:

  • 若想生成目标, 检查规则中的所有的依赖文件是否都存在:
  1. 如果有的依赖文件不存在, 则向下搜索规则, 看是否有生成该依赖文件的规则:

如果有规则用来生成该依赖文件, 则执行规则中的命令生成依赖文件;

如果没有规则用来生成该依赖文件, 则报错.

    1. 如果所有依赖都存在, 检查规则中的目标是否需要更新, 必须先检查它的所有依赖,依赖中有任何一个被更新, 则目标必须更新.(检查的规则是哪个时间大哪个最新)
  • 若目标的时间 > 依赖的时间, 不更新
  • 若目标的时间 < 依赖的时间, 则更新

总结:

  • 分析各个目标和依赖之间的关系
  • 根据依赖关系自底向上执行命令
  • 根据依赖文件的时间和目标文件的时间确定是否需要更新
  • 如果目标不依赖任何条件, 则执行对应命令, 以示更新(如:伪目标)

第二个版本makefile 

main:main.o fun1.o fun2.o sum.o
    gcc -o main main.o fun1.o fun2.o sum.o

main.o:main.c
    gcc -o main.o -c main.c -I./

fun1.fun1.c
    gcc -o fun1.o -c fun1.c -I./

fun2.fun2.c
    gcc -o fun2.o -c fun2.c -I./

sum.sum.c
    gcc -o sum.o -c sum.c -I./

缺点: 冗余, .c文件数量很多, 编写起来比较麻烦.,编译时只更改了一个文件的话只需要执行对应的文件就行,相对于第一种makefile提高了使用效率

1.3 makefile中的变量

在makefile中使用变量有点类似于C语言中的宏定义, 使用该变量相当于内容替换, 使用变量可以使makefile易于维护, 修改起来变得简单。

makefile有三种类型的变量:

    • 普通变量
    • 自带变量
    • 自动变量

普通变量

  • 变量定义直接用 =
  • 使用变量值用 $(变量名)

:下面是变量的定义和使用

foo = abc                    // 定义变量并赋值

bar = $(foo)                // 使用变量, $(变量名)

定义了两个变量: foo、bar, 其中bar的值是foo变量值的引用。

除了使用用户自定义变量, makefile中也提供了一些变量(变量名大写)供用户直接使用, 我们可以直接对其进行赋值:

CC = gcc #arm-linux-gcc

CPPFLAGS : C预处理的选项 -I

CFLAGS:   C编译器的选项 -Wall -g -c

LDFLAGS :  链接器选项 -L  -l

自动变量

  • $@: 表示规则中的目标
  • $<: 表示规则中的第一个条件
  • $^: 表示规则中的所有条件, 组成一个列表, 以空格隔开, 如果这个列表中有重复的项则消除重复项。

特别注意:自动变量只能在规则的命令中使用.

模式规则

至少在规则的目标定义中要包含’%’, ‘%’表示一个或多个, 在依赖条件中同样可以使用’%’, 依赖条件中的’%’的取值取决于其目标:

比如: main.o:main.c  fun1.o: fun1.c  fun2.o:fun2.c, 说的简单点就是: xxx.o:xxx.c

第三个版本makefile

target = main
object = main.o fun1.o fun2.o sum.o
CC = gcc
CPPFLAGS = -I ./

$(target):$(object)
    $(CC) -o $@ $<

%.o:%.c
    $(CC) -o $@ -c $< $(CPPFLAGS)

1.4 makefile函数

makefile中的函数有很多, 在这里给大家介绍两个最常用的。

  1. wildcard – 查找指定目录下的指定类型的文件

src=$(wildcard *.c)  //找到当前目录下所有后缀为.c的文件,赋值给src

  1. patsubst – 匹配替换

obj=$(patsubst %.c,%.o, $(src)) //src变量里所有后缀为.c的文件替换成.o

在makefile中所有的函数都是有返回值的。

当前目录下有main.c fun1.c fun2.c sum.c

src=$(wildcard *.c) 等价于src=main.c fun1.c fun2.c sum.c

obj=$(patsubst %.c,%.o, $(src))等价于obj=main.o fun1.o fun2.o sum.o

 第四个版本makefile 

src = (wildcard ./*.c)
object = $(patsubst %.c, %.o, $(src))
target = main
CC = gcc
CPPFLAGS = -I ./

$(target):$(object)
    $(CC) -o $@ $<

%.o:%.c
    $(CC) -o $@ -c $< $(CPPFLAGS)

缺点: 每次重新编译都需要手工清理中间.o文件和最终目标文件

1.5 makefile清理操作

用途: 清除编译生成的中间.o文件和最终目标文件

make clean 如果当前目录下有同名clean文件,则不执行clean对应的命令, 解决方案:

  • 伪目标声明:

.PHONY:clean

    1. 声明目标为伪目标之后, makefile将不会检查该目标是否存在或者该目标是否需要更新
  1. clean命令中的特殊符号:
  • “-”此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”

    rm -f: 强制执行, 比如若要删除的文件不存在使用-f不会报错

    • “@”不显示命令本身, 只显示结果。如:“@echo clean done”
  1. 其它

– make 默认执行第一个出现的目标, 可通过make dest指定要执行的目标

– make -f : -f执行一个makefile文件名称, 使用make执行指定的makefile: make -f mainmak

第五个版本makefile

#解释版本
#src = add.c sub.c main.c
src = $(wildcard ./*.c)

#object = add.o sub.o main.o             
object = $(patsubst %.c, %.o, $(src))
	
target:mainmak
cc = gcc
CPPFLAGS = -I ./

#mainmak: add.o sub.o main.o
#gcc –o main add.o sub.o main.o
$(target):$(object)					
	$(cc) –o $@ $^

#add.o:add.c sub.o:sun.c
#gcc –g –o add.o –c add.c –I./				
%.o:%.c								
	$(cc) –g –o $@ -c $< $(CPPFLAGS)	

#rm -f main add.o sub.o main.o 	
.PHONY:clean
	-rm –f $(target) $(object)
#最终版本
src = $(wildcard ./*.c)
object = $(patsubst %.c, %.o, $(src))
target:mainmak
cc = gcc
CPPFLAGS = -I ./

$(target):$(object)					
	$(cc) –o $@ $^

%.o:%.c								
	$(cc) –g –o $@ -c $< $(CPPFLAGS)	

.PHONY:clean
	-rm –f $(target) $(object)

makefile的第5个版本中, 综合使用了变量, 函数, 模式规则和清理命令,

是一个比较完善的版本.

make clean即调用清理函数。

$@ 目标文件 $^ 第一个条件 $< 所有条件(会跳过重复的)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值