跳转到内容

Make:修订间差异

维基百科,自由的百科全书
删除的内容 添加的内容
来源请求,请描述具体的软件开发项目
补充括号
 
(未显示17个用户的21个中间版本)
第1行: 第1行:
{{refimprove|time=2019-04-21T03:15:30+00:00}}
{{weasel}}
{{lowercase}}
{{lowercase}}
{{noteTA|G1=IT}}
{{noteTA|G1=IT}}
{{Infobox programming language
| name = <!-- otherwise defaults to {{PAGENAME}} -->
| paradigm = [[巨集]], [[宣告式編程]]
| designer = [[斯圖亞特·費爾德曼]]
| released = {{Start date and age|1976|04}}
| programming language = [[C語言|C 語言]]
| operating system = [[類Unix系統|類 Unix 系統]]
| file format = Makefile
}}
'''Make'''是一个在[[软件开发]]中所使用的构建工具,用于[[自動化建構]]軟體。 它通过一个名为 Makefile 的文本文件来描述源代码文件之间的依赖关系和构建规则。 Make 会根据这些规则和依赖关系,判断哪些文件需要重新编译,并执行相应的编译命令,以确保最终生成可执行文件或其他目标文件(这些目标被称为“target”)。 大多数情况下,它被用来[[编译]][[源代码]],生成[[目标代码|结果代码]],然后把结果代码连接起来生成[[可执行文件]]或者[[库文件]]。


許多現代軟體的開發環境(如[[Microsoft Visual Studio]]),[[集成开发环境]]已經取代make,但是在Unix環境中,仍然有許多-{}-工程師採用make來協助軟體開發。
在[[软件开发]]中,'''make'''是一个工具程式(Utility software),經由讀取叫做“[[makefile]]”的文件,[[自動化建構]]軟體。它是一種转化文件形式的工具,转换的目标称为“target”;与此同时,它也检查文件的依赖关系,如果需要的话,它会调用一些外部软件来完成任务。它的依赖关系检查系统非常简单,主要根据依赖文件的修改时间进行判断。大多数情况下,它被用来[[编译]][[源代码]],生成[[目标代码|结果代码]],然后把结果代码连接起来生成[[可执行文件]]或者[[库文件]]。它使用叫做“makefile”的文件来确定一个target文件的依赖关系,然后把生成这个target的相关命令传给shell去执行。

{{Which|許多現代軟體|time=2013-12-24}}的開發中[[集成开发环境]]已經取代make,但是在Unix環境中,仍然有許多工程師採用make來協助軟體開發。


== 起源 ==
== 起源 ==
目前虽有众多依赖关系检查工具,但是make是应用最广泛的一个。这要归功于它被包含在[[Unix]]系统中。<ref name=razzveer>{{cite journal |last1=Thompson |first1=T. J. |title=Designer's Workbench: Providing a Production Environment |journal=Bell System Technical Journal |date=November 1980 |volume=59 |issue=9 |pages=1811–1825 |doi=10.1002/j.1538-7305.1980.tb03063.x|quote=In the general maintenance of DWB, we have used the Source Code Control System and make utility provided by the PWB/UNIX* interactive operating system.}}</ref>[[斯圖亞特·費爾德曼]]({{lang|en|Stuart Feldman}})在1977年在[[贝尔实验室]]({{lang|en|Bell Labs}})里制作了这个软件。<ref name="v7-version">{{cite web|url=http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7%2Fusr%2Fsrc%2Fcmd%2Fmake%2Fident.c|archiveurl=https://archive.today/20130901165315/http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7%2Fusr%2Fsrc%2Fcmd%2Fmake%2Fident.c|deadurl=yes|title=V7/usr/src/cmd/make/ident.c|author=|date=1 September 2013|archivedate=2013-09-01|website=tuhs.org|accessdate=18 March 2018}}</ref><ref>{{cite journal|last1=Feldman|first1=S. I.|title=Make --- A Program for Maintaining Computer Programs|journal=Software: Practice and Experience|date=April 1979|volume=9|issue=4|pages=255–265|doi=10.1002/spe.4380090402|url=http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.39.7058|accessdate=11 May 2016|archive-date=2020-09-14|archive-url=https://web.archive.org/web/20200914183707/http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.39.7058|dead-url=no}}</ref><ref name=razzveer/>2003年,斯圖亞特·費爾德曼因发明了这样一个重要的工具而接受了[[美国计算机协会]](ACM)颁发的软件系统奖。<ref>{{Cite book|pages=[https://archive.org/details/practicaldevelop0000doar/page/94 94]|title=Practical Development Environments|url=https://archive.org/details/practicaldevelop0000doar|author=Matthew Doar|isbn=978-0-596-00796-6|year=2005|publisher=[[O'Reilly Media]]}}</ref>
目前虽有众多依赖关系检查工具,但是make是应用最广泛的一个。这要归功于它被包含在[[Unix]]系统中。[[斯圖亞特·費爾德曼]]在1977年在[[贝尔实验室]]里制作了这个软件。2003年,斯圖亞特·費爾德曼因发明了这样一个重要的工具而接受了[[美国计算机协会]](ACM)颁发的软件系统奖。


在make诞生之前,[[Unix]]系统的编译系统主要由“make”、“install”shell[[腳本語言|脚本]]程序和程序的源代码组成。它可以把不同目标的命令组成一个文件且可以抽象化依赖关系的检查和存档。这是向现代编译环境发展的重要一步。
在make诞生之前,编译工作主要依赖于操作系统里面的类似于“make”、“install”功能的shell[[腳本語言|脚本]]。它可以批量执行生成目标的命令,且可以完成依赖关系的检查。这是向现代编译环境发展的重要一步。


== 不同版本 ==
== 不同版本 ==
make程序已被使用者多次重/改寫,其中包括幾次用相同的文件格式和算法原理重新編寫,並且依照不同需要添加了一些不常見的改良。
make程序已被使用者多次重/改寫,其中包括幾次用相同的文件格式和算法原理重新編寫,並且依照不同需要添加了一些不常見的改良。


=== [[GNU]] make ===
=== GNU make ===
[[GNU]] make仿照make的標準功能(透過clean-room工程)重新改寫,並加入作者覺得值得加入的新功能,常和[[GNU]]編譯系統一起被使用,是大多數[[GNU]] Linux安裝的一部分。
[[GNU]] make仿照make的標準功能(透過clean-room工程)重新改寫,並加入作者覺得值得加入的新功能,常和[[GNU]]編譯系統一起被使用,是大多數[[GNU]] Linux安裝的一部分。


=== [[BSD]] make ===
=== BSD make ===
是從Adam de Boor的製作的版本上發展成。它編譯目標的時候有並行計算的能力。它在[[FreeBSD]],[[NetBSD]]和[[OpenBSD]]中不同程度的修改下存活了下來。
[[BSD]] make是從Adam de Boor的製作的版本上發展成。它編譯目標的時候有並行計算的能力。它在[[FreeBSD]],[[NetBSD]]和[[OpenBSD]]中不同程度的修改下存活了下來。


=== Microsoft nmake ===
=== Microsoft nmake ===
廣泛應用於[[微軟]]的[[Windows]],[[微軟]]的nmake是不要與來自[[AT&T]]和[[貝爾實驗室]]的Unix系統nmake混淆。
廣泛應用於[[微軟]]的[[Windows]],[[微軟]]的nmake是 Visual Studio 随附的命令行工具,不要與來自[[AT&T]]和[[貝爾實驗室]]的Unix系統nmake混淆。


== 优点和缺点 ==
== 优点和缺点 ==
就像其他和make有着悠久历史的软件一样,它有着很多的拥护者和反对者。它的很多问题因现代大型的软件项目的出现而暴露出来。但是很多人争论说它在常见的情况下可以很好的工作,而且使用非常的简单,功能强大,表达清楚。无论如何,make仍然被用来编译很多完整的[[操作系统]],而且现在替代品们在基本的操作上与它没有太大差别。
就像其他和make有着悠久历史的软件一样,make有着很多的拥护者和反对者。它的很多问题因现代大型的软件项目的出现而暴露出来。但是很多人争论说它在常见的情况下可以很好的工作,而且使用非常的简单,功能强大,表达清楚。无论如何,make仍然被用来编译很多完整的[[操作系统]],而且现在替代品们在基本的操作上与它没有太大差别。


随着现代的[[集成开发环境]](IDE)的诞生,特别是非Unix的平台上,很多程序员不再手动管理依靠关系检查,甚至不用去管哪些文件是这个项目的一部分,而是把这些任务交给了他们的开发环境去做。类似的,很多现代的编程语言有自己特别的高效的依赖关系的设置方法。
随着现代的[[集成开发环境]](IDE)的诞生,特别是非Unix的平台上,很多程序员不再手动管理依靠关系检查,甚至不用去管哪些文件是这个项目的一部分,而是把这些任务交给了他们的开发环境去做。类似的,很多现代的编程语言有自己特别的高效的依赖关系的设置方法。


== Makefile ==
== makefile的基本结构与make的运作流程 ==
===规则===
makefile的格式是:
makefile的格式是:

<pre><nowiki>
#用“”号表明注释。
# 用“#”号表明注释。
target(要生成的文件): dependencies(被依赖的文件)
target(要生成的文件): dependencies(被依赖的文件)
#命令前面用的是“tab”而非空格。误用空格是初学者容易犯的错误!
# 命令前面用的是“tab”而非空格。误用空格是初学者容易犯的错误!
命令1
{{keypress|TAB}}命令1
命令2
{{keypress|TAB}}命令2
命令3
{{keypress|TAB}}命令3
.
.
.
.
.
.
命令n
{{keypress|TAB}}命令n
#可以使用“\”表示续行。注意,“\”之后不能有空格!
# 可以使用“\”表示续行。注意,“\”之后不能有空格!
</nowiki></pre>
*target, dependencies和命令构成了一个makefile里的一个“规则”,规则指示make何时以及如何重新生成target或执行target下的命令
*target通常是我们要生成的文件的名字,摆放的顺序不重要,但第一个target是默认的target。当make不带参数时,自动执行第一个target。target也可以是要求make完成的动作,执行这种target后并不能得到和target同名的文件,因此,也称为伪target(phony target)。
*target通常是我们要生成的文件的名字,摆放的顺序不重要,但第一个target是默认的target。当make不带参数时,自动执行第一个target。target也可以是要求make完成的动作,执行这种target后并不能得到和target同名的文件,因此,也称为伪target(phony target)。
*dependencies是生成target所需的文件名列表。依赖可以为空,常用的“clean”target就常常没有依赖,只有命令。
*dependencies是生成target所需的文件名列表。依赖可以为空,常用的“clean”target就常常没有依赖,只有命令。若依赖不为空,则make会先检查依赖的“规则”。依赖规定了何时重新执行target下命令。若任何依赖比target更新 (由于执行了依赖的“规则”的命令或用户修改了依赖),make则会重新执行target下的命令。
*命令可以是任何一个shell能运行的命令。
*命令可以是任何一个shell能运行的命令。


===示例===
举例来说明makefile的结构和make如何运作。
举例来说明makefile的结构和make如何运作。
<syntaxhighlight lang="make">
<pre><nowiki>
editor: main.o text.o
editor: main.o text.o
gcc -o editor main.o text.o
gcc -o editor main.o text.o
第56行: 第71行:
install:editor
install:editor
mv editor /usr/local
mv editor /usr/local
</syntaxhighlight>
</nowiki></pre>
当我们输入:
当我们输入:
<pre><nowiki>
<pre><nowiki>
第93行: 第108行:
make会检查install的依赖editor是否是最新,如果是,则执行其下的命令“mv editor /usr/local”。由于这个过程并没有产生名为“install”的文件,所以,install是一个假目标。
make会检查install的依赖editor是否是最新,如果是,则执行其下的命令“mv editor /usr/local”。由于这个过程并没有产生名为“install”的文件,所以,install是一个假目标。



== makefile的基本语法 ==
===巨集===
* [[巨集]]:“巨集”指的是用一个字符串代替另一个字符串的功能。在makefile中可以使用“=”号来定义巨集,使用“$(巨集名)”来使用巨集;还可以用“+=”追加巨集的内容。习惯上,巨集名使用大写。承接上面的例子:
[[巨集]]”指的是用一个字符串代替另一个字符串的功能。在makefile中可以使用“=”号来定义巨集,使用“$(巨集名)”来使用巨集;还可以用“+=”追加巨集的内容。习惯上,巨集名使用大写。承接上面的例子:
<pre><nowiki>
<syntaxhighlight lang="make">
OBJECTS = main.o text.o
OBJECTS = main.o text.o
INSTALL_PATH = /usr/local
INSTALL_PATH = /usr/local
第106行: 第122行:
install:editor
install:editor
mv editor $(INSTALL_PATH)
mv editor $(INSTALL_PATH)
</syntaxhighlight>
</nowiki></pre>


== 参见 ==
== 参见 ==
* [[Apache Ant]]
* [[Apache Ant]]
* [[CMake]]
* [[CMake]]

==参考资料==
{{Reflist}}


== 外部链接 ==
== 外部链接 ==
* [https://www.gnu.org/software/make/ GNU Make官方网站] {{Wayback|url=https://www.gnu.org/software/make/ |date=20210204070747 }}
* [http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/index.html GNU make中文手册]
* [https://web.archive.org/web/20081205025958/http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/index.html GNU make中文手册]
* [https://seisman.github.io/how-to-write-makefile/index.html 跟我一起写Makefile] {{Wayback|url=https://seisman.github.io/how-to-write-makefile/index.html |date=20180806054647 }}


{{Unix命令}}
{{DEFAULTSORT:Make}}
{{DEFAULTSORT:Make}}


第121行: 第143行:
[[Category:自动化构建]]
[[Category:自动化构建]]
[[Category:編譯工具]]
[[Category:編譯工具]]
[[Category:带有代码示例的条目]]

2024年5月21日 (二) 05:08的最新版本

Make
编程范型巨集, 宣告式編程
設計者斯圖亞特·費爾德曼
发行时间1976年4月,​48年前​(1976-04
實作語言C 語言
操作系统類 Unix 系統
檔案格式Makefile

Make是一个在软件开发中所使用的构建工具,用于自動化建構軟體。 它通过一个名为 Makefile 的文本文件来描述源代码文件之间的依赖关系和构建规则。 Make 会根据这些规则和依赖关系,判断哪些文件需要重新编译,并执行相应的编译命令,以确保最终生成可执行文件或其他目标文件(这些目标被称为“target”)。 大多数情况下,它被用来编译源代码,生成结果代码,然后把结果代码连接起来生成可执行文件或者库文件

許多現代軟體的開發環境中(如Microsoft Visual Studio),集成开发环境已經取代make,但是在Unix環境中,仍然有許多工程師採用make來協助軟體開發。

起源[编辑]

目前虽有众多依赖关系检查工具,但是make是应用最广泛的一个。这要归功于它被包含在Unix系统中。[1]斯圖亞特·費爾德曼Stuart Feldman)在1977年在贝尔实验室Bell Labs)里制作了这个软件。[2][3][1]2003年,斯圖亞特·費爾德曼因发明了这样一个重要的工具而接受了美国计算机协会(ACM)颁发的软件系统奖。[4]

在make诞生之前,编译工作主要依赖于操作系统里面的类似于“make”、“install”功能的shell脚本。它可以批量执行生成目标的命令,并且可以完成依赖关系的检查。这是向现代编译环境发展的重要一步。

不同版本[编辑]

make程序已被使用者多次重/改寫,其中包括幾次用相同的文件格式和算法原理重新編寫,並且依照不同需要添加了一些不常見的改良。

GNU make[编辑]

GNU make仿照make的標準功能(透過clean-room工程)重新改寫,並加入作者覺得值得加入的新功能,常和GNU編譯系統一起被使用,是大多數GNU Linux安裝的一部分。

BSD make[编辑]

BSD make是從Adam de Boor的製作的版本上發展成。它編譯目標的時候有並行計算的能力。它在FreeBSDNetBSDOpenBSD中不同程度的修改下存活了下來。

Microsoft nmake[编辑]

廣泛應用於微軟Windows微軟的nmake是 Visual Studio 随附的命令行工具,不要與來自AT&T貝爾實驗室的Unix系統nmake混淆。

优点和缺点[编辑]

就像其他和make有着悠久历史的软件一样,make有着很多的拥护者和反对者。它的很多问题因现代大型的软件项目的出现而暴露出来。但是很多人争论说它在常见的情况下可以很好的工作,而且使用非常的简单,功能强大,表达清楚。无论如何,make仍然被用来编译很多完整的操作系统,而且现在替代品们在基本的操作上与它没有太大差别。

随着现代的集成开发环境(IDE)的诞生,特别是非Unix的平台上,很多程序员不再手动管理依靠关系检查,甚至不用去管哪些文件是这个项目的一部分,而是把这些任务交给了他们的开发环境去做。类似的,很多现代的编程语言有自己特别的高效的依赖关系的设置方法。

Makefile[编辑]

规则[编辑]

makefile的格式是:

   # 用“#”号表明注释。
   target(要生成的文件): dependencies(被依赖的文件)
   	# 命令前面用的是“tab”而非空格。误用空格是初学者容易犯的错误!
   Tab ↹命令1
   Tab ↹命令2
   Tab ↹命令3
         .
   	  .
   	  .
   Tab ↹命令n
   # 可以使用“\”表示续行。注意,“\”之后不能有空格!
   
  • target, dependencies和命令构成了一个makefile里的一个“规则”,规则指示make何时以及如何重新生成target或执行target下的命令
  • target通常是我们要生成的文件的名字,摆放的顺序不重要,但第一个target是默认的target。当make不带参数时,自动执行第一个target。target也可以是要求make完成的动作,执行这种target后并不能得到和target同名的文件,因此,也称为伪target(phony target)。
  • dependencies是生成target所需的文件名列表。依赖可以为空,常用的“clean”target就常常没有依赖,只有命令。若依赖不为空,则make会先检查依赖的“规则”。依赖规定了何时重新执行target下命令。若任何依赖比target更新 (由于执行了依赖的“规则”的命令或用户修改了依赖),make则会重新执行target下的命令。
  • 命令可以是任何一个shell能运行的命令。


示例[编辑]

举例来说明makefile的结构和make如何运作。

editor: main.o text.o
	gcc -o editor main.o text.o
main.o: main.c def.h
	gcc -c main.c
text.o: text.c com.h
	gcc -c text.c
install:editor
	mv editor /usr/local

当我们输入:

make
或者
make editor

当editor这个target文件不存在,或者main.o、text.o这两个依赖文件被修改,都会导致make调用其下的命令“gcc -o editor main.o text.o”;接下来,由于引用到main.o和text.o,make会检查main.o的依赖main.c、def.h有无更新,如果有,则执行其下的命令“gcc -c main.c”;同样的道理,也适用于text.o。 于是,可有几种不同的输出:

  • 第一次运行:
gcc -c main.c
gcc -c text.c
gcc -o editor main.o text.o
  • main.c或/和def.h有修改:
gcc -c main.c
gcc -o editor main.o text.o
  • text.c或/和com.h有修改:
gcc -c text.c
gcc -o editor main.o text.o
  • main.c和text.c均有修改:
gcc -c main.c
gcc -c text.c
gcc -o editor main.o text.o

当我们输入:

make install

make会检查install的依赖editor是否是最新,如果是,则执行其下的命令“mv editor /usr/local”。由于这个过程并没有产生名为“install”的文件,所以,install是一个假目标。


巨集[编辑]

巨集”指的是用一个字符串代替另一个字符串的功能。在makefile中可以使用“=”号来定义巨集,使用“$(巨集名)”来使用巨集;还可以用“+=”追加巨集的内容。习惯上,巨集名使用大写。承接上面的例子:

OBJECTS = main.o text.o
INSTALL_PATH = /usr/local
editor: $(OBJECTS)
	gcc -o editor $(OBJECTS)
main.o: main.c
	gcc -c main.c
text.o: text.c
	gcc -c text.c
install:editor
	mv editor $(INSTALL_PATH)

参见[编辑]

参考资料[编辑]

  1. ^ 1.0 1.1 Thompson, T. J. Designer's Workbench: Providing a Production Environment. Bell System Technical Journal. November 1980, 59 (9): 1811–1825. doi:10.1002/j.1538-7305.1980.tb03063.x. In the general maintenance of DWB, we have used the Source Code Control System and make utility provided by the PWB/UNIX* interactive operating system. 
  2. ^ V7/usr/src/cmd/make/ident.c. tuhs.org. 1 September 2013 [18 March 2018]. (原始内容存档于2013-09-01). 
  3. ^ Feldman, S. I. Make --- A Program for Maintaining Computer Programs. Software: Practice and Experience. April 1979, 9 (4): 255–265 [11 May 2016]. doi:10.1002/spe.4380090402. (原始内容存档于2020-09-14). 
  4. ^ Matthew Doar. Practical Development Environments. O'Reilly Media. 2005: 94. ISBN 978-0-596-00796-6. 

外部链接[编辑]