📄 make-06.html
字号:
<h3><a name="_gnu_make_6.2.1"><span lang="en-us">6</span><span lang="EN-US">.2.1<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7.0pt; font-family: Times New Roman">
</span></span><span style="font-family: 楷体_GB2312">递归展开式变量</span></a></h3>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; text-indent: 24.0pt; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
第一种风格的变量是递归方式扩展的变量。这一类型变量的定义是通过“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">=</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”或者使用指示符“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">define</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”定义的。这种变量的引用,在引用的地方是严格的文本替换过程,此变量值的字符串原模原样的出现在引用它的地方。如果此变量定义中存在对其他变量的引用,这些被引用的变量会在它被展开的同时被展开。就是说在变量定义时,变量值中对其他变量的引用不会被替换展开;而是变量在引用它的地方替换展开的同时,它所引用的其它变量才会被一同替换展开。语言的描述可能比较晦涩,让我们来看一个例子:</span></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; text-indent: 24.0pt; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial">
</span></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial">foo = $(bar)</span></i></b></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial">bar = $(ugh)</span></i></b></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial">ugh = Huh?</span></i></b></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial"> </span></i></b></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial">all:;echo $(foo)</span></i></b></p>
<p class="MsoNormal" style="text-indent: 20.5pt">
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial"> </span></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
执行“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">make</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”将会打印出“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">Huh?</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”。整个变量的替换过程时这样的:首先“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">$(foo)</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”被替换为“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">$(bar)</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”,接下来“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">$(bar)</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”被替换为“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">$(ugh)</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”,最后“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">$(ugh)</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”被替换为“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">Hug?</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”。整个替换的过程是在执行“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">echo
$(foo)</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”时完成的。</span></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; text-indent: 24.0pt; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
这种类型的变量是其它版本的</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">make</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">所支持的类型。我们可以把这种类型的变量称为“递归展开”式变量。此类型变量存有它的优点同时也存在其缺点。<b>其优点是:</b></span></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<b>
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
这种类型变量在定义时,可以引用其它的之前没有定义的变量(可能在后续部分定义,或者是通过</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">make</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">的命令行选项传递的变量)。</span></b><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">看一个这样的例子:</span></p>
<p class="MsoNormal" style="text-indent: 20.5pt">
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial"> </span></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial">CFLAGS = $(include_dirs)
-O</span></i></b></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial">include_dirs =
-Ifoo -Ibar</span></i></b></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; text-indent: 24.0pt; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">
</span></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">CFLAGS</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”会在命令中被展开为“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">-Ifoo
-Ibar -O</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”。而在“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">CFLAGS</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”的定义中使用了其后才定义的变量“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">include_dirs</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”。</span></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; text-indent: 24.1pt; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<b>
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
其缺点是:</span></b></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; text-indent: -21.0pt; line-height: 150%; text-autospace: ideograph-numeric ideograph-other; margin-left: 39.0pt">
<span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">
1.<span style="font:7.0pt "Times New Roman""> </span></span><b>
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
使用此风格的变量定义,可能会由于出现变量的递归定义而导致</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">make</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">陷入到无限的变量展开过程中,最终使</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">make</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">执行失败。</span></b><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">例如,接上边的例子,我们给这个变量追加值:</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">
</span></p>
<p class="MsoNormal" style="text-indent: 20.5pt">
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial"> </span></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial">CFLAGS = $(CFLAGS)
–O</span></i></b></p>
<p class="MsoNormal" style="text-indent: 20.5pt">
<span lang="SV" style="font-size: 12.0pt; font-family: Arial"> </span></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
它将会导致</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">make</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">对变量“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">CFLAGS</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”的无限展过程中去(这种定义就是变量的递归定义)。因为一旦后续同样存在对“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">CLFAGS</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”定义的追加,展开过程将是套嵌的、不能终止的(在发生这种情况时,</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">make</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">会提示错误信息并结束)。一般书写</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">Makefile</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">时,这种追加变量值的方法很少使用(也不是我们推荐的方式)。看另外一个例子:</span></p>
<p class="MsoNormal" style="text-indent: 20.5pt">
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial"> </span></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial">x = $(y)</span></i></b></p>
<p class="MsoNormal" style="text-indent: 13.85pt; margin-left: 29.95pt"><b><i>
<span lang="EN-US" style="font-size: 12.0pt; font-family: Arial">y = $(x) $(z)</span></i></b></p>
<p class="MsoNormal" style="text-indent: 20.5pt">
<span lang="SV" style="font-size: 12.0pt; font-family: Arial"> </span></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
这种情况下变量在进行展开时,同样会陷入死循环。所以对于此风格的变量,当在一个变量的定义中需要引用其它的同类型风格的变量时需特别注意,防止变量展开过程的死循环。</span></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; text-indent: -21.0pt; line-height: 150%; text-autospace: ideograph-numeric ideograph-other; margin-left: 39.0pt">
<b>
<span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">
2.<span style="font:7.0pt "Times New Roman""> </span></span>
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
第二个缺点:这种风格的变量定义中如果使用了函数,那么包含在变量值中的函数总会在变量被引用的地方执行(变量被展开时)。</span></b></p>
<p class="MsoNormal" style="text-align: justify; text-justify: inter-ideograph; text-indent: 24.0pt; line-height: 150%; text-autospace: ideograph-numeric ideograph-other">
<span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">
这是因为在这种风格变量的定义中,对函数引用的替换展开发生在变量展开的过程中,而不是在定义这个变量的时候。这样所带来的问题是:使</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">make</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">的执行效率降低(每一次在变量被展开时都要展开他所引用的函数);另外在某些时候会出现一些变量和函数的引用出现非预期的结果。特别是当变量定义中引用了“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">shell</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”和“</span><span lang="EN-US" style="font-size: 12.0pt; line-height: 150%; font-family: Arial; color: black">wildcard</span><span style="font-size: 12.0pt; line-height: 150%; font-family: 楷体_GB2312; color: black">”函数的情况,可能出现不可控制或者难以预料的错误,因为我们无法确定它在何时会被展开。</span></p>
<h3><a name="_gnu_make_6.2.2"><span lang="en-us">6</span><span lang="EN-US">.2.2<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7.0pt; font-family: Times New Roman">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -