Makefile的相关使用

        一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个日录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个she!本一样,其中也可以执行操作系统的命令。
        Makefile带来的好处就是--"自动化编译",一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefle中指令的命令工具,一般来说,大多数的IDE都有这个命令。

make主要解决两个问题:

1)大量代码的关系维护

        大项日中源代码比较多,手丁维护、编译时间长而目编译命令复杂,难以记忆及维护把代码维护命令及编译命令写在makefile文件中,然后再用make工具解析此文件自动执行相应命令,可实现代码的合理编译。

2)减少重复编译时间

         在改动其中一个文件的时候,能判断哪些文件被修改过,可以只对该文件进行軍新编译,然后重新接所有的目际文件,节省编译时间。

Makefile语法规则

一条规则

目标:依赖文件列表
<tab>命令列表

Makefile基本规则三要素:

1)目标:

  • 通常是要产生的文件名称,目标可以是可执行文件或其它ob文件,也可是一个动作的名称

2)依赖文件

  • 用来输入从而产生日标的文件
  • 一个日标通常有几个依赖文件(可以没有)

3)命令

  • make执行的动作,一个规则可以含几个命令(可以没有)
  • 有多个命令时,每个命令占一行

make命令格式

make是一个命令工具,它解释Makefile 中的指令(应该说是规则)。

make命令格式:

make[-f file][options][target]

1.[-f file]:

  • make默认在工作日录中寻找名为GNUmakefile、makefile、Makefile的文件作为Makefile输入文件
  • -f可以指定以上名字以外的文件作为makefle输入文件

2.[options]

  • -v:显示make工具的版本信息
  • -w:在处理makefile之前和之后显示工作路径
  • -C dir:读取makefile之前改变工作路径至dir目录
  • -n:只打印要执行的命令但不执行
  • -s:执行但不显示执行的命令

3.[targets]

  • 若使用make命令时没有指定日标,则make工具默认会实现makefile文件内的第一个日标,然后退出
  • 指定了make工具要实现的目标,目标可以是一个或多个(多个目标间用空格隔开)。

Makefile工作原理

1)若想生成目标,检查规则中的依赖条件是否存在,如不存在,则寻找是否有规,则用来 生成该依赖文件

2)检查规则中的日标是否需要更新,必须先检査它的所有依軌,依赖中有任一个被更新,则目标必须更新

Makefile简单举例

最简单的Makefile:

test:add.c sub.c mul.c div.c test.c
        gcc add.c sub.c mul.c div.c -o test

 修改之后的Makefile:

test:add.o sub.o mul.o div.o test.o
        gcc add.o sub.o mul.o div.o test.o  -o test

add.o:add.c
        gcc -c add.c -o add.o

sub.o:sub.c
        gcc -c sub.c -o sub.o

mul.o:mul.c
        gcc -c mul.c -o mul.o

div.o:div.c
        gcc -c div.c -o div.o

test.o:test.c
        gcc -c test.c -o test.o

Makefile中的变量

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

自定义变量

1)定义变量方法:

交量名=交星值

2)引用变量

$[变量名] or $(变量名)

3)Makefile的变量名

  • makefike变量名可以以数字开头
  • 交量是大小写敏感的
  • 交量一般都在makefike的头部定义
  • 交量几乎可在makefike的任何地方使用

使用变量替代目标文件

OBJS = add.o sub.o mul.o div.o test.o



test:$(OBJS)
        gcc $(OBJS) -o test

add.o:add.c
        gcc -c add.c -o add.o

sub.o:sub.c
        gcc -c sub.c -o sub.o

mul.o:mul.c
        gcc -c mul.c -o mul.o

div.o:div.c
        gcc -c div.c -o div.o

test.o:test.c
        gcc -c test.c -o test.o

clean:
        rm -rf $(OBJS) test

系统提供

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

CC = gcc #arm-linux-gcc

CPPFLAGS #C预处理选项 如-l

CFLAGS  #C编译器选项-wall-g-c

LDFLAGS #连接器选项-L -l

 模式规则

模式规则示例:

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

 使用模式规则的示例:


OBJS = add.o sub.o mul.o div.o test.o
TARGET = test
#这些变量不能单独使用必须在命令中使用
#$@ 表示目标
#$^ 表示所有依赖
#$< 表示第一个依赖:wq

$(TARGET):$(OBJS)
        gcc $^ -o $@

#模式匹配 所有的.o都依赖对应的.c
#将所有的.c生成对应的.o
%.o:%.c
        gcc -c $< -o $@





clean:
        rm -rf $(OBJS) $(TARGET)

Makefile中的函数

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

  1. wildcard-查找指定目录下的指定类型的文件
    src = $(wildcard *,c)     //找到当前目录下所有后缀为.c的文件,赋值给src
  2. patsubst-匹配替换
    obj = $(patsubst %.c,%.o,$(src)) /把src变量里所有后缀为.c的文件替换成.o

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

示例如下:

#获取当前目录下所有的.c文件
SRC = $(wildcard ./*.c)

#将SRC中所有出现.c的替换成.o
OBJS = $(patsubst %.c, %.o, $(SRC))

TARGET = test

#这些变量不能单独使用必须在命令中使用
#$@ 表示目标
#$^ 表示所有依赖
#$< 表示第一个依赖:wq

$(TARGET):$(OBJS)
        gcc $^ -o $@

#模式匹配 所有的.o都依赖对应的.c
#将所有的.c生成对应的.o
%.o:%.c
        gcc -c $< -o $@



#声明clean为为伪目标 伪目标不去判断目标文件是否存在或者已经更新
#无条件执行命令
.PHONY:clean
clean:
        rm -rf $(OBJS) $(TARGET)

Makefile中的伪目标

clean用途: 清除编译生成的中间.0文件和最终目标文件
make clean 如果当前目录下有同名clean文件,则不执行clean对应的命令,解决方案:

伪目标声明:.PHONY:clean

声明目标为伪目机之后,makefle将不会该判断目标是杏存在或者该目标是否需要更新

clean命令中的特殊符号:

  • "-" 此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”
  • “@"不显示命令本身,只显示结果。如:"@echo clean done'
  • 25
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值