📄 make使用中文介绍.htm
字号:
<p> 在当前的工作目录下,将产生一个名为Makefile的文件。make工具工作的时候,这个文件中的信息将被使用到。一旦我们有了makefile文件,那么我们唯一要做的就是:键入‘make’和相关命令,生成目标文件,这些都将被自动执行。</p>
<p> 使用下面的命令行来调用make:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
make target1 target2……
</code></pre></td></tr></table>
<p> 目标是可选择的(如果目标文件没有指定,那么将使用Makefile中的第一个目标)Make习惯在当前目录中搜寻Makefile文件。很有可能会提供多个目标。</p>
<p><b> Makefile的衔接</b></p>
<p> Makefile将由一个编辑器生成:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
# This is an example of a Makefile.
# Comments can be put after a hash (#).
target: prerequisites
command
target: prerequisites
commando
# and so on and so on.
</code></pre></td></tr></table>
<p> 我们把目标文件放在最前面,后边紧接着一个“:”及所需的先决条件。在先决条件存在的情况下,用一个反斜线符号(/)结束一个命令行然后开始另一个命令行。</p>
<p> 在接下来的命令行中,将具有一个或多个命令。每一行都被认为是一个标准命令。假如你想使用多行来定义一个命令,那么你可以在行末使用反斜线符号(//)。Make工具将把这些命令衔接起来。在这种情况下,我们用分号来分离这些命令,以便在运行shell的时候避免出现错误。</p>
<p> <font color=blue>注意:命令用TAB缩进,而不是用8个空格。</font></p>
<p> Make读取Makefile文件而且确定每一个目标命令是否被执行。目标文件、先决条件、标准被指示为规则(rule)。</p>
<p> 如果make工具在没有参数的情况下使用,那么只有第一个目标文件被执行。</p>
<p><b> 我们例子中的Makefile文件</b></p>
<p> 编辑Makefile文件内容如下: </p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
# This Makefile builds Piets' and Jans' website, the potato-eaters.
all: /home/piet/public_html/index.html /home/piet/public_html/offer.html
/home/piet/public_html/index.html: header.html footer.html
/home/jan/Docs/website/index.html
{
cat header.html /home/jan/Docs/website/index.html ;
echo -n '
----------------------------------------------------------------
Last modification: ' ;
date '+%A %e %B' ;
cat footer.html ;
} > /home/piet/public_html/index.html
/home/piet/public_html/offer.html: header.html footer.html
/home/jan/Docs/website/offer.html
{
cat header.html /home/jan/Docs/website/index.html ;
echo -n '
------------------------------------------------------------------
Last modification: ' ;
date '+%A %e %B' ;
cat footer.html ;
} > /home/piet/public_html/offer.html
# the end
</code></pre></td></tr></table>
<p> 现在,我们有了三个目标文件:’all’、index.html和offer.html。’all’唯一的作用就是将其他两个文件作为先决条件。因为’all’本身不是文件名,所以目标文件’all’将被执行。(随后我们将介绍一种更别致的方法用来定义并非文件的目标)</p>
<p> 如果header文件和footer文件被修改,那么整个页面都将被更新。但如果只改变其中的一页,那么仅这一页被更新。</p>
<p> 但是,Makefile文件有一个缺点:它不容易被监查。所幸的是,有许多方式可以有效而简单的解决这个问题!</p>
<p><b> Makefile的制作流程</b></p>
<p> ☆变量</p>
<p> 使用变量,Makefile将得到很大的简化。变量定义如下:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
variable = value
</code></pre></td></tr></table>
<p> 我们使用表达式$(variabele)来引用变量。如果我们将变量并入Makefile中,操作如下:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
# This Makefile builds Piets' and Jans' website, the potato-eaters.
# Directory where the website is stored:
TARGETDIR = /home/piet/public_html
# Jans' directory:
JANSDIR = /home/jan/Docs/website
# Files needed for the layout:
LAYOUT = header.html footer.html
all: $(TARGETDIR)/index.html $(TARGETDIR)/offer.html
$(TARGETDIR)/index.html: $(LAYOUT) $(JANSDIR)/index.html
{
cat header.html $(JANSDIR)/index.html ;
echo -n '
----------------------------------------------------------------
Last modification: ' ;
date '+%A %e %B' ;
cat footer.html ;
} > $(TARGETDIR)/index.html
$(TARGETDIR)/offer.html: $(LAYOUT) $(JANSDIR)/offer.html
{
cat header.html $(JANSDIR)/index.html ;
echo -n '
-----------------------------------------------------------------
Last modification: ' ;
date '+%A %e %B' ;
cat footer.html ;
} > $(TARGETDIR)/offer.html
# the end
</code></pre></td></tr></table>
<p> 要养成用大写字母来书写变量的好习惯。这样改动起来的时候会容易得多。</p>
<p> 如果你愿意,你可以定义另外一种方法将各个文档放在恰当的布局。但如果你想将许多变量放在一个布局中,那又该怎么做呢?当有许多副本的时候makefile文件将变得非常庞大。但是,所有这些问题也可以变得很简单。</p>
<p><b> ☆模式规则</b></p>
<p> 模式规则使我们对不同的目标文件使用同样的一系列命令。</p>
<p> 使用模式规则,将改变行的衔接;加入一个额外的pattern field:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
Multiple targets: pattern : prerequisite prerequisite ...
command
</code></pre></td></tr></table>
<p> 这个模式是一个表达式,它适用于任何目标文件。百分号被用于合并目标文件名的不同部分。</p>
<p> 例如:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
/home/bla/target1.html /home/bla/target2.html: /home/bla/% : %
commands
</code></pre></td></tr></table>
<p> 当make工具读到这的时候,行将扩张到两行。在此,模式将确定目标文件的哪一个部分将用百分号合并。</p>
<p> 当百分号出现在先决条件区段(prerequisites-field)中时,表示这一部分已经被百分号复制了下来。</p>
<p><b> Make工具发展如下:</b></p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
/home/bla/target1.html: target1.html
commands
/home/bla/target2.html: target2.html
</code></pre></td></tr></table>
<p> 模式‘/home/bla/%’中的百分号和目标‘/home/bla/target1.html’中的‘target1.html’,从而‘%’发展为‘target.html’的必备条件。</p>
<p> 适用我们的web站点,下面的规则合并为:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
$(TARGETDIR)/index.html $(TARGETDIR)/offer.html:
$(TARGETDIR)/% : $(JANSDIR)/%
$(LAYOUT)
</code></pre></td></tr></table>
<p> 现在我们还剩一个问题:在命令中如何使用这些变量?命令和目标文件都有一些不同吗?</p>
<p><b> ☆自动变量</b></p>
<p> 幸运的是,make能自动定义变量。这些变量中的某些被称为自动变量。这些变量在命令执行过程中(最好:刚好在执行命令之前)包含目标的数量及(或者)先决条件。</p>
<p> 简单的变量$< 象征第一先决条件,变量$@ 为目前的目标。</p>
<p> 使用这些变量可将下全部的规则归纳如下:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
$(TARGETDIR)/index.html $(TARGETDIR)/offer.html: $(TARGETDIR)/% :
$(JANSDIR)/%
$(LAYOUT)
{
cat header.html $< ;
echo -n '
-----------------------------------------------------------------
Last modification: ' ;
date '+%A %e %B' ;
cat footer.html ;
} > $@
</code></pre></td></tr></table>
<p> 为了完整性,要呈现整个Makefile文件,包括一些optimalisations:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
# This Makefile builds Piets' and Jans' website, the potato-eaters.
# Directory where the website is published:
TARGETDIR = /home/piet/public_html
# Jans' directory:
JANSDIR = /home/jan/Docs/website
# Files needed for the layout:
LAYOUT = header.html footer.html
# These are the webpages:
DOCS = $(TARGETDIR)/index.html $(TARGETDIR)/offer.html
# Please change nothing below this line;-)
# ---------------------------------------------------------
all: $(DOCS)
$(DOCS): $(TARGETDIR)/% : $(JANSDIR)/% $(LAYOUT)
{
cat header.html $< ;
echo -n '
-----------------------------------------------------------------
Last modification: ' ;
date '+%A %e %B' ;
cat footer.html ;
} > $@
# the end
</code></pre></td></tr></table>
<p> 就算要加入更多的文件,并将它们合并到Makefile文件中,只要使用DOCS变量还是很简单的,无须很多的键入。</p>
<p> 你看,维护Makefile文件是一件多么简单的事,你根本不用再为它是怎么工作的而感到困惑!</p>
<p><b> ☆最后的小小优化</b></p>
<p> 我们更喜欢在DOCS中mension文档,这样不用包含整个目录。操作如下(我们在TEXTS中的makefile文件的开头改变DOCS):</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
# Please change nothing below this line;-)
# --------------------------------------------------------
DOCS = $(addprefix $(TARGETDIR)/,$(TEXTS))
all: $(DOCS)
# and so on
</code></pre></td></tr></table>
<p> 我们在此看到的是make工具的一个独特的功能:它可以在括号间使用一个完全的表达式来代替变量名。这样,我们可以通过很多方式来修改文本。</p>
<p> 这个独特的命令$(addprefix prefix,list)为列在列表上的每个元素加上一个前缀。例如,TARGETDIR变量加上一个斜线(/)。 </p>
<p> 所列条目用空格分开。出于这个原因,使用make 工具加工带有空格的文件名将会出现问题。</p>
<p> 在前面我们提到目标文件’all’并不能产生一个名为’all’的文件(这行并不包括任何命令 ),结果是该目标文件将被始终执行。但是当自动生成一个以此文件名命名的文件,而且它比其它文件新的时候,我们又该怎样操作?</p>
<p> 有一种很简单的方式定义make 始终执行一个特定的目标文件,而且这个目标文件并不指定硬盘中的文件。操作起来是将这个目标文件标示为’phony’(假名):</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
.PHONY:all
</code></pre></td></tr></table>
<p> 这样,整个MakeFile文件变成如下所示:</p>
<table border='1' cellspacing='0' cellpadding='5' width='100%' bgcolor='#CCCCCC'><tr><td><pre><code>
# This Makefile builds Piets' and Jans' website, the potato-eaters.
# Directory where the website is published:
TARGETDIR = /home/piet/public_html
# Jans' directory:
JANSDIR = /home/jan/Docs/website
# Files needed for the layout:
LAYOUT = header.html footer.html
# These are the names of the webpages:
TEXTS = index.html offer.html yetanotherfile.html
# Please change nothing below this line;-)
# ------------------------------------------------------
DOCS = $(addprefix $(TARGETDIR)/,$(TEXTS))
.PHONY: all
all: $(DOCS)
$(DOCS): $(TARGETDIR)/% : $(JANSDIR)/% $(LAYOUT)
{
cat header.html $< ;
echo -n '
------------------------------------------------------------
Last modification: ' ;
date '+%A %e %B' ;
cat footer.html ;
} > $@
# the end
</code></pre></td></tr></table>
<p> 保存这个文件然后忽略它!从现在开始它将通过使用你的contab来维持你的web布局,并且将你的布局和内容完全分开来。</p>
<p><b> 最后的忠告</b></p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -