<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Makefile</title>
	<atom:link href="https://www.aitaocui.cn/tag/158965/feed" rel="self" type="application/rss+xml" />
	<link>https://www.aitaocui.cn</link>
	<description>翡翠玉石爱好者聚集地</description>
	<lastBuildDate>Tue, 22 Nov 2022 15:02:38 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.1</generator>

<image>
	<url>https://www.aitaocui.cn/wp-content/uploads/2022/11/taocui.png</url>
	<title>Makefile</title>
	<link>https://www.aitaocui.cn</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Makefile(配置文件)</title>
		<link>https://www.aitaocui.cn/article/252316.html</link>
					<comments>https://www.aitaocui.cn/article/252316.html#respond</comments>
		
		<dc:creator><![CDATA[钱琨]]></dc:creator>
		<pubDate>Tue, 22 Nov 2022 15:02:38 +0000</pubDate>
				<category><![CDATA[百科]]></category>
		<category><![CDATA[Makefile]]></category>
		<guid isPermaLink="false">https://www.aitaocui.cn/?p=252316</guid>

					<description><![CDATA[Makefile是一种配置文件，Makefile一个工程中的源文件不计数，其按类型、功能、模块分别放在若干个目录中，makefile定义了一系列的规则来指定，哪些文件需要先编译，哪...]]></description>
										<content:encoded><![CDATA[</p>
<article>
<p>Makefile是一种配置文件，Makefile一个工程中的源文件不计数，其按类型、功能、模块分别放在若干个目录中，makefile定义了一系列的规则来指定，哪些文件需要先编译，哪些文件需要后编译，哪些文件需要重新编译，甚至于进行更复杂的功能操作，因为makefile就像一个Shell脚本一样，其中也可以执行操作系统的命令。</p>
</article>
<article>
<h1>定义概述</h1>
<p>makefile关系到了整个工程的编译规则。一个工程中的源文件不计数，一般按照类型、功能、模块分别放在若干个目录中。Makefile通过定义整个工程的编译规则来告诉make命令如何编译和链接文件。</p>
<p>Linux环境下的程序员如果不会使用GNUmake来构建和管理自己的工程，应该不能算是一个合格的专业程序员，至少不能称得上是Unix程序员。在Linux(unix)环境下使用GNU的make工具能够比较容易的构建一个属于你自己的工程，整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要投入一些时间去完成一个或者多个称之为Makefile文件的编写。</p>
<p>所要完成的Makefile文件描述了整个工程的编译、连接等规则。其中包括：工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生想要得可执行文件。尽管看起来可能是很复杂的事情，但是为工程编写Makefile的好处是能够使用一行命令来完成“自动化编译”，一旦提供一个(通常对于一个工程来说会是多个)正确的Makefile。编译整个工程你所要做的唯一的一件事就是在shell提示符下输入make命令。整个工程完全自动编译，极大提高了效率。</p>
<p>make是一个命令工具，它解释Makefile中的指令(应该说是规则)。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile有自己的书写格式、关键字、函数。像C语言有自己的格式、关键字和函数一样。而且在Makefile中可以使用系统shell所提供的任何命令来完成想要的工作。Makefile(在其它的系统上可能是另外的文件名)在绝大多数的IDE开发环境中都在使用，已经成为一种工程的编译方法。</p>
<p>例子：(一个相对复杂的例子，嵌入式编程中经常用到的，详细情况请参考嵌入式linux应用开发完全手册)</p>
<p>01src:=$(shellls*.c)/*把当前目录下所有c源代码赋给变量src*/</p>
<p>02obj:=$(patsubst%.c,%.o,$(src))/*调用makefile中的函数patsubst,用.o文件代替.c文件*/</p>
<p>03</p>
<p>04test:$(objs)</p>
<p>05gcc-o$@$^</p>
<p>06</p>
<p>07%.o:%.c</p>
<p>08gcc-c-o$@lt;</p>
<p>09</p>
<p>10clean:</p>
<p>11rm-ftest*.o</p>
<p>上述Makefile中的“$@&quot;,&quot;$^&quot;,&quot;lt;&quot;称为自动变量。</p>
<h1>基本介绍</h1>
<p>makefile带来的好处就是——“自动化编译”，一旦写好，只需要一个make命令，整个工程完全自动编译，极大的提高了软件开发的效率。make是一个命令工具，是一个解释makefile中指令的命令工具，一般来说，大多数的IDE都有这个命令，比如：Delphi的make，VisualC++的nmake，Linux下GNU的make。可见，makefile都成为了一种在工程方面的编译方法。</p>
<h1>主要功能</h1>
<p>Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile文件需要按照某种语法进行编写，文件中需要说明如何编译各个源文件并连接生成可执行文件，并要求定义源文件之间的依赖关系。makefile文件是许多编译器&#8211;包括WindowsNT下的编译器&#8211;维护编译信息的常用方法，只是在集成开发环境中，用户通过友好的界面修改makefile文件而已。</p>
<p>在UNIX系统中，习惯使用Makefile作为makefile文件。如果要使用其他文件作为makefile，则可利用类似下面的make命令选项指定makefile文件：</p>
<p>$make-fMakefile.debug</p>
<p>例如，一个名为prog的程序由三个C源文件filea.c、fileb.c和filec.c以及库文件LS编译生成，这三个文件还分别包含自己的头文件a.h、b.h和c.h。通常情况下，C编译器将会输出三个目标文件filea.o、fileb.o和filec.o。假设filea.c和fileb.c都要声明用到一个名为defs的文件，但filec.c不用。即在filea.c和fileb.c里都有这样的声明：</p>
<p>#include&quot;defs&quot;</p>
<p>那么下面的文档就描述了这些文件之间的相互联系:</p>
<p>0#Itisaexamplefordescribingmakefile注释行</p>
<p>1prog:filea.ofileb.ofilec.o#指定prog由三个目标文件filea.o、fileb.o和filec.o链接生成</p>
<p>2ccfilea.ofileb.ofilec.o-LS-oprog#如何从prog所依赖的文件建立可执行文件</p>
<p>3filea.o:filea.ca.hdefs#指定filea.o目标文件，以及它们所依赖的.c和.h文件以及defs文件</p>
<p>4cc-cfilea.c#如何从目标所依赖的文件建立目标，即如何从filea.c建立filea.o</p>
<p>5fileb.o:fileb.cb.hdefs#指定fileb.o目标文件，以及它们所依赖的.c和.h文件以及defs文件</p>
<p>6cc-cfileb.c#如何从目标所依赖的文件建立目标,即如何从fileb.c建立fileb.o</p>
<p>7filec.o:filec.cc.h#指定filec.o目标文件，以及它们所依赖的.c和.h文件</p>
<p>8cc-cfilec.c#如何从目标所依赖的文件建立目标,即如何从filec.c建立filec.o</p>
<p>这个描述文档就是一个简单的makefile文件。针对上例的代码方面进行一些基础性说明：CC是一个全局变量，它指定你的Makefile所用的编译器，一般默认是gcc;.o文件是unix下的中间代码目标文件，就如同在windows下的.obj文件一样，在unix下生成.o文件的过程叫编译(compile)，将无数.o文件集合生成可执行文件的过程叫链接(link);有时会在unix界面下看到.a文件，那是ArchiveFile，相当于windows下的库文件LibraryFile。</p>
<p>a文件作用是：由于源文件太多(上例是指.c和.h文件过多)，编译生成的中间目标文件(.o文件)太多，而在链接时需要明显地指出中间目标文件名，这对于编译很不方便，所以，要给中间目标文件打个包，这个包就是.a文件。</p>
<p>当filea.c或a.h文件在编译之后又被修改，则make工具可自动重新编译filea.o，如果在前后两次编译之间，filea.c和a.h均没有被修改，而且filea.o还存在的话，就没有必要重新编译。这种依赖关系在多源文件的程序编译中尤其重要。通过这种依赖关系的定义，make工具可避免许多不必要的编译工作。当然，利用Shell脚本也可以达到自动编译的效果，但是，Shell脚本将全部编译任何源文件，包括哪些不必要重新编译的源文件，而make工具则可根据目标上一次编译的时间和目标所依赖的源文件的更新时间而自动判断应当编译哪个源文件。</p>
<p>Makefile文件准备好之后，接着在Makefile文件所在的目录下敲入make这个命令就可以了，根据Makefile文件，以告诉make命令需要怎么样的去编译和链接目标程序。</p>
<p>Makefile的规则</p>
<p>让先来粗略地看一看Makefile的规则。</p>
<p>target&#8230;:prerequisites&#8230;</p>
<p>command</p>
<p>目标：依赖</p>
<p>执行指令&#8230;</p>
<p>target也就是一个目标文件，可以是ObjectFile，也可以是执行文件。还可以是一个标签(Label)。</p>
<p>①prerequisites就是，要生成那个target所需要的文件或是目标。</p>
<p>②command也就是make需要执行的命令。(任意的Shell命令)</p>
<p>这是一个文件的依赖关系，也就是说，target这一个或多个的目标文件依赖于prerequisites中的文件，其生成规则定义在command中。说白一点就是说，prerequisites中如果有一个以上的文件比target文件要新的话，command所定义的命令就会被执行(command一定要以Tab键开始，否者编译器无法识别command)，减少重复编译，提高了其软件工程管理效率。</p>
<p>文件定义与命令</p>
<p>Makefile文件作为一种描述文档一般需要包含以下内容:</p>
<p>宏定义源文件之间的相互依赖关系</p>
<p>可执行的命令</p>
<p>Makefile中允许使用简单的宏指代源文件及其相关编译信息，在Linux中也称宏为变量。在引用宏时只需在变量前加$符号，但值得注意的是，如果变量名的长度超过一个字符，在引用时就必须加圆括号()。</p>
<p>有效的宏引用</p>
<p>$(CFLAGS)</p>
<p>$Z</p>
<p>$(Z)</p>
<p>其中最后两个引用是完全一致的。</p>
<p>需要注意的是一些宏的预定义变量，在Unix系统中，$*、$@、$?和lt;四个特殊宏的值在执行命令的过程中会发生相应的变化，而在GNUmake中则定义了更多的预定义变量。关于预定义变量的详细内容，宏定义的使用可以使脱离那些冗长乏味的编译选项，为编写makefile文件带来很大的方便。</p>
<p>#Defineamacrofortheobjectfiles</p>
<p>OBJECTS=filea.ofileb.ofilec.o</p>
<p>#Defineamacroforthelibraryfile</p>
<p>LIBES=-LS</p>
<p>#usemacrosrewritemakefile</p>
<p>prog:$(OBJECTS)</p>
<p>cc$(OBJECTS)$(LIBES)-oprog</p>
<p>……&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>此时如果执行不带参数的make命令，将连接三个目标文件和库文件LS;但是如果在make命令后带有新的宏定义：</p>
<p>make&quot;LIBES=-LL-LS&quot;#如何实现?</p>
<p>则命令行后面的宏定义将复盖makefile文件中的宏定义。若LL也是库文件，此时make命令将连接三个目标文件以及两个库文件LS和LL。</p>
<p>在Unix系统中没有对常量NULL作出明确的定义，因此要定义NULL字符串时要使用下述宏定义：</p>
<p>STRINGNAME=//这里有待考证</p>
<p>makefile中的变量(宏)</p>
<p>GNU的make工具除提供有建立目标的基本功能之外，还有许多便于表达依赖性关系</p>
<p>以及建立目标的命令的特色。其中之一就是变量或宏的定义能力。如果你要以相同的编译</p>
<p>选项同时编译十几个C源文件，而为每个目标的编译指定冗长的编译选项的话，将是非</p>
<p>常乏味的。但利用简单的变量定义，可避免这种乏味的工作：</p>
<p>#Definemacrosfornameofcompiler</p>
<p>CC=gcc</p>
<p>#DefineamacrofortheCCflags</p>
<p>CCFLAGS=-D_DEBUG-g-m486</p>
<p>#Aruleforbuildingaobjectfile</p>
<p>test.o:test.ctest.h</p>
<p>$(CC)-c$(CCFLAGS)test.c</p>
<p>在上面的例子中，CC和CCFLAGS就是make的变量。GNUmake通常称之为变量，</p>
<p>而其他UNIX的make工具称之为宏，实际是同一个东西。在makefile中引用变量的值</p>
<p>时，只需变量名之前添加$符号，如上面的$(CC)和$(CCFLAGS)。</p>
<p>GNUmake有许多预定义的变量，这些变量具有特殊的含义，可在规则中使用。表13-2</p>
<p>给出了一些主要的预定义变量，除这些变量外，GNUmake还将所有的环境变量作为自己</p>
<p>的预定义变量。</p>
<p>表13-2GNUmake的主要预定义变量</p>
<p>预定义变量</p>
<p>含义</p>
<p>$*</p>
<p>不包含扩展名的目标文件名称。</p>
<p>$+</p>
<p>所有的依赖文件，以空格分开，并以出现的先后为序，可能包含重复的依赖文件。</p>
<p>lt;</p>
<p>第一个依赖文件的名称。</p>
<p>$?</p>
<p>所有的依赖文件，以空格分开，这些依赖文件的修改日期比目标的创建日期晚。</p>
<p>$@</p>
<p>目标的完整名称。</p>
<p>$^</p>
<p>所有的依赖文件，以空格分开，不包含重复的依赖文件。</p>
<p>$%</p>
<p>如果目标是归档成员，则该变量表示目标的归档成员名称。例如，如果目标名称为</p>
<p>(image.o)，则$@为，而$%为image.o。</p>
<p>AR</p>
<p>归档维护程序的名称，默认值为ar。</p>
<p>ARFLAGS</p>
<p>归档维护程序的选项。</p>
<p>AS</p>
<p>汇编程序的名称，默认值为as。</p>
<p>ASFLAGS</p>
<p>汇编程序的选项。</p>
<p>CC</p>
<p>C编译器的名称，默认值为cc。</p>
<p>CFLAGS</p>
<p>C编译器的选项。</p>
<p>CPP</p>
<p>C预编译器的名称，默认值为$(CC)-E。</p>
<p>CPPFLAGS</p>
<p>C预编译的选项。</p>
<p>CXX</p>
<p>C++编译器的名称，默认值为g++。</p>
<p>CXXFLAGS</p>
<p>C++编译器的选项。</p>
<p>FC</p>
<p>FORTRAN编译器的名称，默认值为f77。</p>
<p>FFLAGS</p>
<p>FORTRAN编译器的选项。</p>
<p>Makefile以文件名:文件名的形式比较冒号右边的文件是不是较左边的文件有更新，如果有更新则执行下一行的程序代码。因此Makefile可以把文件关联起来</p>
</article>
<div class="mt-3 mb-3" style="max-width: 770px;height: auto;">
                                    </div>
<div class="mt-3 mb-3" style="max-width: 770px;height: auto;">
                                    </div>
<div class="mt-3 mb-3" style="max-width: 770px;height: auto;">
                                    </div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.aitaocui.cn/article/252316.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
