Makefile的简单使用

一、Makefile核心规则

目标文件(target)… : 依赖文件(prerequiries)…
tab键+ 命令(command)

如果依赖文件比目标文件更加新,那么执行命令来重新生成目标文件

举例:

a.c

#include <stdio.h>

int main()
{
        func_b();
        return 0;
}

b.c

#include <stdio.h>

void func_b()
{

        printf("this is A!\n");
}

可用命令gcc -o test a.c b.c 进行编译,但现在需要用make命令,编写Makefile文件
我们知道可以用gcc -c 命令分别对a.c 和 b.c 文件进行编译不链接,形成a.o 和 b.o 文件,然后再对a.o 和 b.o 文件进行链接形成可执行文件test。基于这一点,可以编写以下Makefile文件(后续进行完善)

test: a.o b.o
        gcc -o test a.o b.o
a.o: a.c
        gcc -c -o a.o a.c
b.o: b.c
        gcc -c -o b.o b.c

二、 Makefile语法

1.通配符: %.o
表示目标 $@
表示第一个依赖文件 $<
表示所有依赖文件 $^

2.假相目标: .PHONY

根据以上语法可对之前的Makefile文件进行改进
若make 不指定目标,默认执行第一条命令,即生成可执行文件test;若指定目标clean则执行删除有关文件。

Makefile命令执行条件是:目标文件不存在或者依赖文件比目标文件新
若文件目录存在clean文件,而无依赖文件,则执行不了删除命令,则需要使用.PHONY

test: a.o b.o
        gcc -o $@ $^
%.o: %.c
        gcc -c -o $@ $<
clean:
        rm *.o test -f
.PHONY: clean

3.即时变量 延时变量

:= 即时变量
= 延时变量
?= 延时变量,如果是第一次定义才起效,如果在前面该变量已定义则忽略这句
+= 附加,它是即时变量还是延时变量取决于前面的定义

有以下Makefile文件
A为即时变量,在定义时就确定,此时变量C为空
B为延时变量 使用时才确定

A := $(C)
B = $(C)

C = ab

D = hello
D ?= heavysea

all:
        @echo A = $(A)
        @echo B = $(B)
        @echo D = $(D)

C += ee
~

执行make命令:

A =
B = ab ee
D = hello

三、Makefile部分常用函数

1. $(foreach var f,list,text)
把参数list中的单词逐一取出来放到var所指的变量中,然后再执行text所包含的表达式

2. $(filter pattern…,text)
在text中取出符合pattern格式的值

3. $(filter-out pattern…,text)
在text中取出不符合pattern格式的值

4. $(wildcard pattern)
pattern 定义了条件名的格式
wildcard 取出其中存在的文件

5. $(patsubst pattern,replacement, $(var))
从列表中取出每一个值,如果符合pattern,则替换为replacement

Makefile

A = a b c
B = $(foreach f,$(A),$(f).o)
C = a b c d e/

// 查找C中符合 .../的形式
D = $(filter %/,$(C))
// 查找C中不符合 .../的形式
E = $(filter-out %/,$(C))

//取出存在的.c文件
file = $(wildcard *.c)

file2 = a.c b.c c.c d.c e.c
// 取出file2中且存在的文件
file3 = $(wildcard $(file2))

// 从file2中取出的值若符合.c形式则替换为.d文件
dep_files = $(patsubst %.c,%.d,$(file2))

all:
        @echo B = $(B)
        @echo D = $(D)
        @echo E = $(E)
        @echo file = $(file)
        @echo file3 = $(file3)
        @echo dep_files = $(dep_files)

运行结果如下图
在这里插入图片描述

四、Makefile的实例(自动检测头文件)

文件目录下有a.c b.c 文件

objs = a.o b.o

// .a.o.d   .b.o.d
// 需要判断是否存在依赖文件
dep_files := $(patsubst %,.%.d,$(objs))
dep_files := $(wildcard $(dep_files))

// 警告作为错误提醒  指定头文件路径
CFLAGS = -Werror -I .

test: $(objs)
        gcc -o $@ $^

// 把依赖文件包含进来
ifneq ($(dep_files),)
include $(dep_files)
endif

%.o: %.c
        gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d
clean:
        rm *.o test -f
 // 删除依赖文件
distclean:
        rm $(dep_files)
.PHONY: clean

有关依赖文件的常用命令

// 打印出依赖
gcc -M b.c    

// 把依赖写入文件b.d 
gcc -M -MF b.d b.c

// 编译b.o 把依赖写入文件b.d
gcc -c -o b.o b.c -MD -MF b.d
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值