0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Makefile简介和使用方法

嵌入式那些事 来源:嵌入式那些事 2023-12-26 12:24 次阅读

1.Makefile简介

Makefile是和make工具一起配合使用的,用于组织管理项目源代码的编译和链接。

make工具用于找出修改过的文件,根据依赖关系,找出受影响的相关文件,最后按照规则单独编译这些文件。

Makefile文件则记录依赖关系和编译规则。

Makefile的本质:无论多么复杂的语法,都是为了更好地解决项目文件之间的依赖关系。

2.Makefile规则介绍

Makefile的一个规则由目标、依赖、命令组成,其语法结构如下所示:

目标:依赖的文件或者是其他目标

命令1

命令2

...

一个规则可以有多个命令行,每一条命令占一行。注意:每一个命令行必须以[Tab]字符开始,[Tab]字符告诉 make 此行是一个命令行。make 按照命令完成相应的动作。这也是书写 Makefile 中容易产生,而且比较隐蔽的错误。

3.Makefile伪目标

伪目标不代表一个真正的文件名,在执行 make 时可以指定这个目标来执行其所在规则定义的命令,有时也可以将一个伪目标称为标签

使用伪目标有两点原因:

(1).避免在我们的 Makefile 中定义的只执行命令的目标(此目标的目的是为了执行一系列命令,而不需要创建这个目标)和工作目录下的实际文件出现名字冲突。

(2).提高执行 make 时的效率,特别是对于一个大型的工程来说,编译的效率也许你同样关心。

将一个目标声明为伪目标的方法是将它作为特殊目标".PHONY"的依赖。在书写伪目标规则时,首先需要声明目标是一个伪目标,之后才是伪目标的规则定义。目标"clean"的书写格式应该如下:

.PHONY:clean

clean:
rm*.otemp

4.Makefile的变量

在 Makefile 中,变量是一个名字(像是 C 语言中的宏),代表一个文本字符串。在 Makefile 的目标、依赖、命令中引用变量的地方,变量会被它的值所取代。

变量名是不包括":"、"#"、"="、前置空白和尾空白的任何字符串。变量名最好使用字母、数字和下划线进行定义,对于其他的特殊符号不建议使用到变量名的定义中。

变量名是大小写敏感的。变量"foo"、"Foo"和"FOO"指的是三个不同的变量。

变量的引用方式是:"$(VARIABLE_NAME)" 或者 "${VARIABLE_NAME}" 来引用一个变量的定义。

Makefile的变量包含系统环境变量,自定义变量和自动化变量。

4.1.系统环境变量

使用系统环境变量需要注意以下几点:

(1).在 Makefile 中对一个变量的定义或者以 make 命令行形式对一个变量的定义,都将覆盖同名的系统环境变量(注意:它并不改变系统环境变量定义,被修改的环境变量只在 make 执行过程有效)。而 make 使用"-e"参数时,Makefile 和命令行定义的变量不会覆盖同名的环境变量,make 将使用系统环境变量中这些变量的定义值。

(2).make的递归调用中,所有的系统环境变量会被传递给下一级make。默认情况下,只有系统环境变量和通过命令行方式定义的变量才会被传递给子make进程。在Makefile中定义的普通变量需要传递给子make时需要使用"export"指示符来对它声明。

4.2.自定义变量

在Makefile中自定义变量比较简单,下面简单的区分下各个符号的含义:

(1).延迟赋值:"=";

使用"="号定义变量时,如果定义的变量存在对其他变量的引用,那么定义的变量并不会立即展开对其他变量的引用,而是在真正使用到该变量时才进行展开。例如下述例子中,只有在echo "(A),虽然在定义变量B之前A的值为123,但是在执行echo "$(B)"时,A的最终值为456,因此会输出456。

(2).立即赋值:":=";

立即赋值是相对于延迟赋值的,使用":="号定义变量时,如果定义的变量存在对其他变量的引用,那么定义的变量会立即展开对其他变量的引用。可以结合下面的例子进行理解。

(3).为空赋值(条件赋值):"?=";

使用"?="号定义变量时,只有定义的变量在之前没有赋值的情况下才会对这个变量进行赋值。可以结合下面的例子进行理解。

(4).追加赋值:"+=";

使用"+="符号,可以对变量的值进行追加。可以结合下面的例子进行理解。

例子:

#延迟赋值
A=123
B=$(A)
A=456

#立即赋值
C=123
D:=$(C)
C=456

#空赋值
E?=123
E?=456

#追加赋值
F?=123
F+=456

.PHONY:all

all:
echo"$(B)"#结果:456
echo"$(D)"#结果:123
echo"$(E)"#结果:123
echo"$(F)"#结果:123456

4.3.自动化变量

Makefile中常用的自动化变量如下描述:

$<:第一个依赖文件;

$^:全部的依赖文件;

$@:目标;

5.Makefile条件分支

条件分支语法如下:

ifeq(var1,var2)
...
else
...
endif

ifneq(var1,var2)
...
else
...
endif

例子:

ARCH?=x86

ifeq($(ARCH),x86)
CC=gcc
else
CC=arm-linux-gnueabihf-gcc
endif

6.Makefile的常用函数

Makefile还是提供了比较多的函数供我们使用,这里介绍下常用的几个函数。

6.1.patsubst

$(patsubst PATTERN,REPLACEMENT,TEXT)

函数名称:模式替换函数 - patsubst。

函数功能:搜索"TEXT"中以空格分开的单词,将符合模式"PATTERN"替换为"REPLACEMENT"。参数"PATTERN"中可以使用模式通配符"%"来代表一个单词中的若干字符。如果参数"REPLACEMENT"中也包含一个"%",那么"REPLACEMENT"中的"%"将是"PATTERN"中的那个"%"所代表的字符串。在"PATTERN"和"REPLACEMENT"中,只有第一个"%"被作为模式字符来处理,之后出现的不再作模式字符(作为一个字符)。在参数中如果需要将第一个出现的"%"作为字符本身而不作为模式字符时,可使用反斜杠""进行转义处理。

返回值:替换后的新字符串。函数说明:参数"TEXT"单词之间的多个空格在处理时被合并为一个空格,并忽略前导和结尾空格。

如果感觉上述的文字说明有点不太好理解,那么看看下面的示例吧,之后再结合示例看上面的文字说明应该就比较好理解了,示例如下:

.PHONY:all

all:
echo"$(patsubst%.c,%.o,x.c.cbar.c)"#结果:x.c.obar.o

上述示例的运行结果:把字串"x.c.c bar.c"中以.c 结尾的单词替换成以.o 结尾的字符。函数的返回结果是"x.c.o bar.o"。

6.2.notdir

$(notdir NAMES…)

函数名称:取文件名函数 - notdir。

函数功能:从文件名序列"NAMES…"中取出非目录部分。目录部分是指最后一个斜线("/")(包括斜线)之前的部分。删除所有文件名中的目录部分,只保留非目录部分。

返回值:文件名序列"NAMES…"中每一个文件的非目录部分。

函数说明:如果"NAMES…"中存在不包含斜线的文件名,则不改变这个文件名。以反斜线结尾的文件名,是用空串代替,因此当"NAMES…"中存在多个这样的文件名时,返回结果中分割各个文件名的空格数目将不确定!这是此函数的一个缺陷。

示例:

.PHONY:all

all:
echo"$(notdirsrc/foo.chacks)"#结果:foo.chacks

6.3.wildcard

$(wildcard PATTERN)

函数名称:获取匹配模式文件名函数 - wildcard。

函数功能:列出当前目录下所有符合模式"PATTERN"格式的文件名。

返回值:空格分割的、存在当前目录下的所有符合模式"PATTERN"的文件名。

函数说明:"PATTERN"使用shell可识别的通配符,包括"?"(单字符)、"*"(多字符)等。

示例:

.PHONY:all

all:
echo"$(wildcard*.c)"#结果:当前目录下所有.c源文件列表

6.4.foreach

$(foreach VAR,LIST,TEXT)

函数"foreach"不同于其它函数。它是一个循环函数。类似于 Linux shell 中的for 语句。

函数名称:循环函数 - foreach。

函数功能:这个函数的工作过程是这样的:如果需要(存在变量或者函数的引用),首先展开变量"VAR"和"LIST"的引用;而表达式"TEXT"中的变量引用不展开。执行时把"LIST"中使用空格分割的单词依次取出赋值给变量"VAR",然后执行"TEXT"表达式。重复直到"LIST"的最后一个单词(为空时结束)。"TEXT"中的变量或者函数引用在执行时才被展开,因此如果在"TEXT"中存在对"VAR"的引用,那么"VAR"的值在每一次展开式将会到的不同的值。

返回值:空格分割的多次表达式"TEXT"的计算的结果。

备注:函数中参数"VAR"是一个局部的临时变量,它只在"foreach"函数的上下文中有效,它的定义不会影响其它部分定义的同名"VAR"变量的值。

示例:

.PHONY:all

dirs:=abcd
files:=$(foreachdir,$(dirs),$(wildcard$(dir)/*))

all:
echo"$(files)"#结果:files是abcd4个目录下所有文件组成的文件列表.

示例分析:例子中,"TEXT"的表达式为 $(wildcard $(dir)/*)。表达式第一次执行时将展开为 $(wildcard a/*);第二次执行时将展开为 $(wildcard b/*);第三次展开为 $(wildcard c/*); ...;以此类推。

7.其他

默认规则:.o文件默认使用对应的.c文件来进行编译。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 命令
    +关注

    关注

    5

    文章

    678

    浏览量

    21983
  • 源代码
    +关注

    关注

    96

    文章

    2944

    浏览量

    66663
  • 编译
    +关注

    关注

    0

    文章

    653

    浏览量

    32805
  • Makefile
    +关注

    关注

    1

    文章

    125

    浏览量

    19161

原文标题:Makefile学习与使用-一篇文章带你了解

文章出处:【微信号:嵌入式那些事,微信公众号:嵌入式那些事】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux系统中的Makefile使用方法

    今天主要和大家聊一聊,Linux系统中的Makefile使用方法
    发表于 11-17 09:35 4132次阅读

    linux系统中Makefile使用方法

    Makefile是一种编译控制文件,广泛用于项目的自动化构建。它定义了一系列的规则来指导构建的过程。通过Makefile,开发者可以轻松管理大型项目的编译链接、清理等任务。本文将从Makefile
    的头像 发表于 05-11 08:49 593次阅读

    Layout使用方法简介及设计步骤

    Layout使用方法简介及设计步骤    PCB的设计流程一般分为:网表(Netlist)输入、规则设置、元器件布局、布线
    发表于 10-30 10:02

    Crawler:关于爬虫的简介、安装、使用方法之详细攻略

    Crawler:关于爬虫的简介、安装、使用方法之详细攻略
    发表于 12-19 16:58

    关于Anaconda简介、安装、使用方法的详细攻略

    DL之Anaconda:关于Anaconda简介、安装、使用方法的详细攻略
    发表于 12-24 11:42

    常见的图片标注工具labelImg的简介、安装和使用方法

    labelImg:图片标注工具之labelImg的简介、安装、使用方法详细攻略
    发表于 12-25 10:26

    Python库的twisted简介安装和使用方法

    Py之twisted:Python库之twisted简介、安装、使用方法等详细攻略
    发表于 12-25 10:03

    Python库的PyMySQL简介安装及使用方法

    Py之PyMySQL:Python库之PyMySQL的简介、安装、使用方法之详细攻略
    发表于 12-26 10:40

    Python库的Shutil简介和安装及使用方法

    Py之Shutil:Python库之Shutil简介、安装、使用方法之详细攻略
    发表于 12-27 16:46

    Python库的Xlrd简介和安装及使用方法

    Py之Xlrd:Python库之Xlrd简介、安装、使用方法之详细攻略
    发表于 12-27 16:46

    Python库的ipykernel简介安装及使用方法

    Py之ipykernel:Python库之ipykernel简介、安装、使用方法之详细攻略
    发表于 12-27 16:47

    lightgbm的简介、安装、使用方法

    Py之lightgbm:lightgbm的简介、安装、使用方法之详细攻略
    发表于 06-01 08:42

    Makefile脚本语法简介

    宏定义LEDS_CTL 的使用Makefile脚本语法简介Makefile测试
    发表于 12-22 06:39

    振动测试系统组成及基本仪器使用方法简介

    激振器之振动测试系统组成及基本仪器的使用方法...(2015-09-20 03:48:41)标签:能够随时实验一 振动测试系统组成及基本仪器使用方法简介 一、 实验目的 1、了解结构振动控制实验装置
    发表于 09-10 07:13

    LINGO软件的简介和基本使用方法详细中文概述

    本文档的主要内容介绍的是LINGO软件的简介和基本使用方法详细中文概述
    发表于 06-14 08:00 7次下载
    LINGO软件的<b class='flag-5'>简介</b>和基本<b class='flag-5'>使用方法</b>详细中文概述