写点什么

makefile:带你了解一种常用于 GNU gcc 编译的工具语言

发布于: 2021 年 03 月 11 日

​​摘要:该文章主要介绍 makefile,一种常用于 GNU gcc 编译的工具语言,同时 LiteOS 也是利用该文件对工程项目进行 make 构建生成执行文件的。


LiteOS 源码中使用 makefile 进行文件的批处理编译和连接到生成文件,如果在使用 LiteOS 来设计工程时使用 GNU 编译器进行编译,一般会都会使用到 makefile 进行编译和链接程序,如果使用的 Keil 或 IAR 的编译器进行编译则在 Keil IDE 或 IAR IDE 中设置编译器信息和文件包换路径就可以了进行编译链接和输出文件。

1、makefile 介绍


简单的说 makefile 就是 make 执行的文件,将代码变成可行性文件的的过程叫做编译,组成一系列文件的编译叫做构建(build),Make 是 GNU 提供的构建工具,主要用 C、C++项目的构建编译过程,要学会使用 Make,我们就需要学会使用 makefile 编写,makefile,该文件描述了如何编译和链接由几个 C 源文件和几个头文件组成的文本编辑器。当明确要求时,makefile 还可以告诉 make 如何运行其他命令(例如,删除某些文件作为清理操作)


1.1 makefile 规则


一个简单的 makefile 由具有以下形状的“规则”组成:

target … : prerequisites …        recipe
复制代码


target(目标)通常是由程序生成的文件的名称。目标的示例是可执行文件或目标文件。目标也可以是要执行的操作的名称,例如“clean”;


prerequisites(前置条件)是一个文件,该文件用作创建目标的输入。一个目标通常取决于几个文件;

recipe(命令)是一种要执行的动作。配方可能在同一行上或在自己的行上具有多个命令。请注意:您需要在每个配方行的开头添加一个制表符!这是一个模糊的地方,引起了人们的注意。如果您希望在食谱中使用制表符以外的其他字符作为前缀,则可以将.RECIPEPREFIX 变量设置为其他字符。


"目标"是必需的,不可省略;"前置条件"和"命令"都是可选的,但是两者之中必须至少存在一个。


一条规则说明了如何以及何时重新制作作为特定规则目标的某些文件。 make 根据创建或更新目标的先决条件执行方法。规则还可以解释如何以及何时执行某项操作。一个 makefile 可能包含除规则之外的其他文本,但是一个简单的 makefile 只需包含规则。规则看起来可能比此样例中显示的要复杂一些,但所有规则或多或少都适合该模式。


1.2Makefile 语法


① # 表示注释


② 通配符用来指定一组符合条件的文件名。Makefile 的通配符与 Bash 一致,主要有星号(*)、问号(?)和 [...] 。比如, *.o 表示所有后缀名为 o 的文件。


③ %模式匹配

     如需要编译当前目录下 a.c 和 b.c 两个文件,原来的写法是:


a.o: a.cb.c: b.c
复制代码


利用 %可以简写为:


%.o : %.c
复制代码


在处理大量同类型文件时既可以利用 %简写文件


④ “=” 自定义变量


txt = Hello World
test:
    @echo $(txt)
复制代码


上面的 txt 代替的了“Hello World”

同时基于“=” Makefile 提供了(=、:=、?=、+=)四个赋值运算操作。


⑤ 内置变量


Make 有自己的操作变量,特指一些自己的功能命令;如:$(CC) 指向当前使用的编译器,$(MAKE) 指向当前使用的 Make 工具

具体变量规则可参考:https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html


⑥ 自动变量(Automatic Variables)


makefile 提供一些与规则相关的变量,常用的有:


(1)$@ -----指代当前目标


(2)$<  -----指代第一个前置条件

a.txt: b.txt c.txt    cp $< $@
复制代码


上面的代码和下面的代码一致

a.txt: b.txt c.txt    cp b.txt a.txt
复制代码


$< 指代第一个前置条件,即“b.txt”;$@ 指代目标值即“a.txt”


(3)$?------ 指代比目标更新的所有前置条件,之间以空格分隔。比如,规则为 t: p1 p2,其中 p2 的时间戳比 t 新,$?就指代 p2。


(4)$^------ 指代所有前置条件,之间以空格分隔。比如,规则为 t: p1 p2,那么 $^ 就指代 p1 p2 。


(5)$*------ 指代匹配符 % 匹配的部分, 比如 % 匹配 f1.txt 中的 f1 ,$* 就表示 f1。


(6)$(@D) 和 $(@F)------ 分别指向 $@ 的目录名和文件名。比如,$@是 src/input.c,那么 $(@D) 的值为 src ,$(@F) 的值为 input.c。


(7)$(<D) 和 $(<F)------ 分别指向 $< 的目录名和文件名。


1.3 makefile 循环


Makefile 使用 Bash 语法,完成判断和循环。

如 ifeq -- else -- endif 使用

ifeq ($(CC),gcc)  libs=$(libs_for_gcc)else  libs=$(normal_libs)endif
复制代码

以上代码通过判断编译器是否为 gcc 决定编译不同的路径。


1.4 makefile 函数


Makefile 提供一些内置函数,使用格式如下:

$(function arguments)# 或者${function arguments}
复制代码


内建函数如下表:具体函数参考路径(https://www.gnu.org/software/make/manual/html_node/Functions.html)

2.mikefile 文件编写


如下文件编译一个 C 语言工程,包含 main.c kdb.c display.c 三个源文件及 defs.h、command.h、两个头文件

编译代如下:

edit : main.o kbd.o command.o display.o     cc -o edit main.o kbd.o command.o display.omain.o : main.c defs.h    cc -c main.ckbd.o : kbd.c defs.h command.h    cc -c kbd.ccommand.o : command.c defs.h command.h    cc -c command.cdisplay.o : display.c defs.h    cc -c display.cclean :     rm edit main.o kbd.o command.o display.o.PHONY: edit clean
复制代码


该代码中,清空了输出文件,然后利用 gcc 编译器编译了三个头文件和两个文件。

 

本文分享自华为云社区《一文读懂LiteOS中的“makefile”文件(1)----makfile简介》,原文作者:o0龙龙0o


点击关注,第一时间了解华为云新鲜技术~


发布于: 2021 年 03 月 11 日阅读数: 24
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
makefile:带你了解一种常用于GNU gcc编译的工具语言