make命令详解,make使用方法,Make命令基础用法教程

make命令详解,make使用方法,Make命令基础用法教程

本文详细解释了Make命令的基本用法,通过示例代码非常详细。对大家的学习或者工作都有一定的参考价值,有需要的朋友可以参考一下。

目录

一、Make II的概念。Makefile的格式2.1概述2.2目标)2.3先决条件)2.4命令III、Makefile的语法3.1注释3.2回显)3.3通配符3.4模式匹配3.5变量和赋值器3.6隐式变量)3.7自动变量)3.8判断和循环3.9函数IV .Makefile示例

一、Make的概念

Make这个词在英语中是“制造”的意思。Make命令直接用这个意思,就是制作某个文件。例如,要使文件成为a.txt,可以执行以下命令。

$ make a.txt

但是,如果您输入这个命令,它将不起作用。因为Make命令本身不知道如何制作a.txt,所以需要有人告诉它如何调用其他命令来完成这个目标。

例如,假设文件a.txt依赖于b.txt和c.txt,是后两个文件连接的产物(cat命令)。然后,make需要知道以下规则。

a.txt: b.txt c.txt

目录b.txt c.txt a.txt

也就是说,make a.txt命令的背后,其实有两步:第一步,确认b.txt和c.txt必须已经存在,第二步,使用cat命令,将这两个文件合并,作为新文件输出。

像这样的规则被写在一个名为Makefile的文件中,Make命令依赖这个文件来构建。Makefile文件也可以写成makefile,或者用命令行参数指定成其他文件名。

$ make -f rules.txt

#或者

$ make - file=rules.txt

上面的代码指定make命令是根据rules.txt文件中的规则构建的。

总之,make只是一个按照指定的Shell命令构建的工具。它的规则非常简单。您可以指定要构建的文件、它所依赖的源文件,以及当这些文件发生变化时如何重新构建它。

二、Makefile文件的格式

构建规则写在Makefile中。要学习如何制作命令,您必须学习如何编写Makefile。

2.1 概述

Makefile文件由一系列规则组成。每个规则的形式如下。

目标:先决条件

[tab]命令

上面第一行冒号前的部分叫‘target’,冒号后的部分叫‘prerequisites’;第二行必须以tab键开头,后跟“命令”。

“Target”是必需的,不能省略;“前提条件”和“命令”都是可选的,但必须至少存在其中之一。

每条规则都定义了两件事:建立目标的前提条件是什么,以及如何建立目标。下面是对每个规则的三个组成部分的详细解释。

2.2 目标(target)

目标构成了规则。目标通常是文件名,表示Make命令要构建的对象,比如上面的a.txt。目标可以是一个文件名或多个文件名,用空格分隔。

除了文件名,目标也可以是一个操作的名称,称为“假目标”。

清洁:

rm *。o

上面代码的目标是干净的。它不是文件名,而是一个操作的名称,属于‘伪目标’,用于删除目标文件。

$清洁

但是,如果当前目录中恰好有一个名为clean的文件,那么这个命令将不会被执行。因为Make发现clean文件已经存在,认为没有必要重新构建,所以不会执行指定的rm命令。

为了避免这种情况,您可以明确声明clean是一个“假目标”,如下所示。假的:干净

清洁:

rm *。o温度

clean被声明为'伪目标'后,make不会检查是否有名为clean的文件,而是在每次运行时执行相应的命令。有许多内置的目标名,如。假的。请检查手册。

如果Make命令运行时没有指定目标,默认情况下将执行Makefile的第一个目标。

$ make

上面的代码执行Makefile文件的第一个目标。

2.3 前置条件(prerequisites)

前提条件通常是一组由空格分隔的文件名。它规定了判断是否应该重建“目标”的标准:只要前文件不存在或者已经被更新(前文件的最后修改时间戳比目标的时间戳新),就需要重建“目标”。

结果. txt: source.txt

cp source.txt result.txt

在上面的代码中,构建result.txt的前提条件是source.txt如果source.txt已经存在于当前目录中,那么make result.txt可以正常运行,否则必须再写一个规则来生成source.txt。

source.txt:

echo '这是来源' source.txt

在上面的代码中,source.txt后面没有前置条件,也就是说和其他文件没有关系。只要这个文件还不存在,每次调用make source.txt都会生成。

$ make result.txt

$ make result.txt

上面的命令连续执行make result.txt两次。第一次执行会创建一个新的source.txt,然后第二次执行会创建一个新的result.txt,Make发现source.txt没有变化(时间戳晚于result.txt),所以不会执行任何操作,result.txt也不会重新生成。

如果需要生成多个文件,通常使用下面的方法。

来源:文件1文件2文件3

在上面的代码中,source是一个伪目标,只有三个前置文件,没有相应的命令。

$制作源

执行make source命令后,将同时生成三个文件:文件1、文件2和文件3。这比下面的写法方便多了。

$制作文件1

$制作文件2

$制作文件3

2.4 命令(commands)

命令指示如何更新目标文件,由一行或多行Shell命令组成。它是构建一个‘目标’的具体指令,其运行结果通常是生成一个目标文件。

每个命令行前面必须有一个tab键。如果想使用其他键,可以用内置变量声明它们。RECIPEPREFIX。RECIPEPREFIX=

全部:

回声你好,世界

上面的代码是用。RECIPEPREFIX,大于号()替换tab键。因此,每行命令的开头都变成了大于号,而不是tab键。

请注意,每行命令都是在单独的shell中执行的。这些外壳之间没有继承关系。

var-lost:

导出foo=bar

echo 'foo=[$$foo]'

上面的代码执行后(make var-lost),无法获得foo的值。因为这两行命令是在两个不同的进程中执行的。一种解决方案是在一行中写两行命令,用分号隔开。

var-keeped:

export foo=barecho 'foo=[$$foo]'

另一种解决方案是在换行符前用反斜杠进行转义。

var-keeped:

export foo=bar\

echo 'foo=[$$foo]'

最后一个方法是添加。ONESHELL:命令。ONESHELL:

var-keeped:

export foo=bar

echo 'foo=[$$foo]'

三、Makefile文件的语法

3.1 注释

井号(#)表示Makefile中的注释。

#这是评论。

结果. txt: source.txt

#这是评论。

Cp source.txt result.txt #这也是评论

3.2 回声(echoing)

正常情况下,make会打印每一条命令,然后执行,这就叫回显。

测试:

#这是一个测试

如果您执行上述规则,您将获得以下结果。

$进行测试

#这是一个测试

在命令前面添加@以关闭回显。

测试:

@ #这是一个测试

现在执行make test,将没有输出。

在构建的过程中,需要知道当前执行的是哪个命令,所以@通常只加在注释和纯echo命令的前面。

测试:

@ #这是一个测试

@echo TODO

3.3 通配符

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

清洁:

rm -f *。o

3.4 模式匹配

Make命令允许文件名通过类似的常规操作进行匹配,主要使用的匹配器是%。比如,假设当前目录下有两个源文件f1.c和f2.c,需要编译成对应的目标文件。

%.o: %。c

相当于下面的写法。

f1.o: f1.c

f2.o: f2.c

有了match%,大量相同类型的文件可以只用一个规则来构建。

3.5 变量和赋值符

Makefile允许您使用等号来自定义变量。

txt=Hello World

测试:

@echo $(txt)

在上面的代码中,变量txt等于Hello World。调用时,变量需要放在$()中。

要调用Shell变量,需要在美元符号前添加一个美元符号,因为Make命令对美元符号进行了转义。

测试:

@echo $$HOME

有时候,一个变量的值可能指向另一个变量。

v1=$(v2)

在上面的代码中,变量v1的值是另一个变量v2。这时就产生了一个问题,v1的值是在定义时扩展(静态扩展)还是在运行时扩展(动态扩展)?如果v2的值是动态的,这两种展开方法的结果可能会有很大的不同。

为了解决类似的问题,Makefile提供了四个赋值操作符(=,=,=,=),它们的区别见StackOverflow。

变量=值

#在执行时展开,允许递归展开。

变量:=值

#定义时展开。

变量?=值

#仅当变量为空时设置值。

变量=值

#将值追加到变量的末尾。

3.6 内置变量(Implicit Variables)

MAKE命令提供了一系列内置变量,比如$(CC)指向当前使用的编译器,$(MAKE)指向当前使用的Make工具。这主要是为了跨平台的兼容性。有关内置变量的详细列表,请参见手册。

输出:

$(CC) -o输出输入

3.7 自动变量(Automatic Variables)

Make命令还提供了一些值与当前规则相关的自动变量。主要有以下几种。

(1)$@

$ @指的是当前目标,即Make命令当前构建的目标。比如make foo的$ @就是指foo。

a.txt b.txt:

触摸$@

相当于下面的写法。

a.txt:

触摸a.txt

b.txt:

触摸b.txt

(2)$

$指的是第一个前提条件。例如,如果规则是t: p1 p2,那么$引用p1。

a.txt: b.txt c.txt

cp $ $@

相当于下面的写法。

a.txt: b.txt c.txt

中国石油天然气股份有限公司

(3)$?

$?指比目标更新的所有前提条件,用空格分隔。比如规则是t: p1 p2,其中p2的时间戳比T新,$?它指的是p2。

(4)$^

$表示所有前提条件,用空格分隔。例如,如果规则是t: p1 p2,那么$指的是p1 p2。

(5)$*

$ *指匹配%匹配的部分,如f1.txt中%匹配f1,$ *表示f1。

(6)$(@D) 和 $(@F)

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

(7)$(D) 和 $(F)

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

有关所有自动变量的列表,请参考手册。下面是一个自动变量的例子。

dest/%。txt: src/%。文本文件(textfile)

@[ -d dest ] || mkdir dest

cp $ $@

上面的代码将src目录下的txt文件复制到dest目录下。首先,确定dest目录是否存在,如果不存在,创建一个新目录。然后,$指的是前面的文件(src/%。txt),而$ @指的是目标文件(dest/%。txt)。

3.8 判断和循环

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

ifeq ($(CC),gcc)

libs=$(libs_for_gcc)

其他

libs=$(normal_libs)

endif

上面的代码确定当前编译器是否是gcc,然后指定一个不同的库文件。

列表=一二三

全部:

对于I以$(列表);做

echo $ $ I;\

完成的

#相当于

全部:

因为我在一二三;做

echo $ I;\

完成的

上面代码的运行结果。

一个

3.9 函数

Makefile也可以使用以下格式的函数。

$(函数参数)

#或者

$ {函数参数}

Makefile提供了许多可以调用的内置函数。下面是几个常用的内置函数。

(1)shell 函数

Shell函数用于执行shell命令。

srcfiles :=$(shell echo src/{00.99}.txt)

(2)wildcard 函数

通配符函数用于替换Makefile中Bash的通配符。

srcfiles :=$(通配符src/*。txt)

(3)subst 函数

Subst函数用于以下格式的文本替换。

$(subst from,to,text)

以下示例将字符串“felt on the street”替换为“felt on the street”。

$(subst ee,ee,街上的脚)

下面是一个稍微复杂的例子。

逗号:=,

空:=

# space变量使用两个空变量作为标识符,其中一个是空格。

空格:=$(空)$(空)

食物:=a b c

bar:=$(subst $(空格),$(逗号),$(foo))

# bar现在是` a,b,c '。

(4)patsubst函数

Patsubst函数用于替换模式匹配。格式如下。

$(patsubst模式,替换,文本)

以下示例将文件名“x.c.c bar.c”替换为“x.c.o bar.o”。

$(patsubst %)。c,%。o,x . c . c . bar . c)

(5)替换后缀名

替换后缀函数的写法如下:变量名冒号后缀的替换规则。它实际上是patsubst函数的简写形式。

最小值:$(输出:js=.min.js)

上面的代码意味着替换所有的后缀。用min.js输出变量中的js

四、Makefile 的实例

(1)执行多个目标。假的:cleanall cleanobj cleandiff

cleanall : cleanobj cleandiff

rm程序

cleanobj:

rm *。o

cleandiff:

rm *。差速器

上面的代码可以调用不同的目标删除不同后缀的文件,或者调用一个目标(cleanall)删除指定类型的所有文件。

(2)编译C语言项目

编辑:main.o kbd.o命令. o显示. o

cc -o edit main.o kbd.o命令. o显示. o

main.o : main.c defs.h

cc -c主

kbd.o : kbd.c defs.h命令

cc -c

command.o : command.c defs.h命令. h

cc -c命令

display.o : display.c defs.h

cc -c显示

清洁:

rm edit main.o kbd.o命令. o显示. o。假的:编辑干净

今天Make命令的介绍就到这里了。在下一篇文章中,我将介绍如何用Make构建Node.js项目。

这就是本文的全部内容。希望对大家的学习有帮助,支持我们。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: