⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 深入makefile.htm

📁 MAKEFILE 的一些入门常识
💻 HTM
📖 第 1 页 / 共 3 页
字号:
      来建我们的程序。我们可以让 它搜索当前目录,找到源码文件,并且假设它们都是属于我们的项 目的,放进一个叫 SOURCES 
      的变量。这里如果也包含所有的 *.cc 文件,也许会更保险,因为源码文件可能是 C++ 码的。<BR><BR>SOURCES = 
      $(wildcard *.c *.cc)<BR><BR>利用 patsubst ,我们可以由源码文件名产生目标文件名,我们需 
      要编译出这些目标文件。如果我们的源码文件既有 .c 文件,也有 .cc 文件,我们需要使用相嵌的 patsubst 
      函数呼叫:<BR><BR>OBJS = $(patsubst %.c,%.o,$(patsubst 
      %.cc,%.o,$(SOURCES)))<BR><BR>最里面一层 patsubst 的呼叫会对 .cc 文件进行后缀替代,产生的结 果被外层的 
      patsubst 呼叫处理,进行对 .c 文件后缀的替代。<BR><BR>现在我们可以设立一个规则来建可执行文件:<BR><BR>myprog : 
      $(OBJS)<BR>gcc -o myprog $(OBJS)<BR><BR>进一步的规则不一定需要, gcc 已经知道怎么去生成目标文件 
      (object files) 。下面我们可以设定产生依靠信息的规则:<BR><BR>depends : $(SOURCES)<BR>gcc -M 
      $(SOURCES) &gt; depends<BR><BR>在这里如果一个叫 'depends' 的文件不存在,或任何一个源码文件 比一个已存在的 
      depends 文件新,那么一个 depends 文件会被生 成。depends 文件将会含有由 gcc 产生的关于源码文件的规则(注 意 -M 
      开关)。现在我们要让 make 把这些规则当做 makefile 档 的一部分。这里使用的技巧很像 C 语言中的 #include 系统——我 
      们要求 make 把这个文件 include 到 makefile 里,如下:<BR><BR>include depends<BR><BR>GNU 
      Make 看到这个,检查 'depends' 目的是否更新了,如果没有, 它用我们给它的命令重新产生 depends 档。然后它会把这组(新) 
      规则包含进来,继续处理最终目标 'myprog' 。当看到有关 myprog 的规则,它会检查所有的目标文件是否更新——利用 depends 文件 
      里的规则,当然这些规则现在已经是更新过的了。<BR><BR>这个系统其实效率很低,因为每当一个源码文件被改动,所有的源码 
      文件都要被预处理以产生一个新的 'depends' 文件。而且它也不是 100% 的安全,这是因为当一个 header 档被改动,依靠信息并不会 
      被更新。但就基本工作来说,它也算相当有用的了。<BR><BR>2.8 一个更好的 makefile<BR><BR>这是一个我为我大多数项目设计的 
      makefile 。它应该可以不需要修 改的用在大部分项目里。我主要把它用在 djgpp 上,那是一个 DOS 版的 gcc 
      编译器。因此你可以看到执行的命令名、 'alleg' 程序包、 和 RM -F 变量都反映了这一点。<BR><BR>=== makefile 开始 
      ===<BR><BR>######################################<BR># <BR># Generic 
      makefile <BR># <BR># by George Foot <BR># email: 
      george.foot@merton.ox.ac.uk <BR># <BR># Copyright (c) 1997 George Foot 
      <BR># All rights reserved. <BR># 保留所有版权 <BR># <BR># No warranty, no 
      liability; <BR># you use this at your own risk. <BR># 没保险,不负责 <BR># 
      你要用这个,你自己担风险 <BR># <BR># You are free to modify and <BR># distribute this 
      without giving <BR># credit to the original author. <BR># 你可以随便更改和散发这个文件 
      <BR># 而不需要给原作者什么荣誉。 <BR># (你好意思?) <BR># 
      <BR>######################################<BR><BR>### Customising<BR># 
      用户设定<BR>#<BR># Adjust the following if necessary; EXECUTABLE is the 
      target<BR># executable's filename, and LIBS is a list of libraries to link 
      in<BR># (e.g. alleg, stdcx, iostr, etc). You can override these on 
      make's<BR># command line of course, if you prefer to do it that way.<BR># 
      <BR># 如果需要,调整下面的东西。 EXECUTABLE 是目标的可执行文件名, LIBS<BR># 是一个需要连接的程序包列表(例如 
      alleg, stdcx, iostr 等等)。当然你<BR># 可以在 make 的命令行覆盖它们,你愿意就没问题。<BR># 
      <BR><BR>EXECUTABLE := mushroom.exe<BR>LIBS := alleg<BR><BR># Now alter any 
      implicit rules' variables if you like, e.g.:<BR>#<BR># 
      现在来改变任何你想改动的隐含规则中的变量,例如<BR><BR>CFLAGS := -g -Wall -O3 -m486<BR>CXXFLAGS := 
      $(CFLAGS)<BR><BR># The next bit checks to see whether rm is in your djgpp 
      bin<BR># directory; if not it uses del instead, but this can cause 
      (harmless)<BR># `File not found' error messages. If you are not using DOS 
      at all,<BR># set the variable to something which will unquestioningly 
      remove<BR># files.<BR>#<BR># 下面先检查你的 djgpp 命令目录下有没有 rm 命令,如果没有,我们使用<BR># 
      del 命令来代替,但有可能给我们 'File not found' 这个错误信息,这没<BR># 什么大碍。如果你不是用 DOS 
      ,把它设定成一个删文件而不废话的命令。<BR># (其实这一步在 UNIX 类的系统上是多余的,只是方便 DOS 用户。 UNIX<BR># 
      用户可以删除这5行命令。)<BR><BR>ifneq ($(wildcard $(DJDIR)/bin/rm.exe),)<BR>RM-F := 
      rm -f<BR>else<BR>RM-F := del<BR>endif<BR><BR># You shouldn't need to 
      change anything below this point.<BR>#<BR># 
      从这里开始,你应该不需要改动任何东西。(我是不太相信,太NB了!)<BR><BR>SOURCE := $(wildcard *.c) 
      $(wildcard *.cc)<BR>OBJS := $(patsubst %.c,%.o,$(patsubst 
      %.cc,%.o,$(SOURCE)))<BR>DEPS := $(patsubst 
      %.o,%.d,$(OBJS))<BR>MISSING_DEPS := $(filter-out $(wildcard 
      $(DEPS)),$(DEPS))<BR>MISSING_DEPS_SOURCES := $(wildcard $(patsubst 
      %.d,%.c,$(MISSING_DEPS)) \<BR>$(patsubst 
      %.d,%.cc,$(MISSING_DEPS)))<BR>CPPFLAGS += -MD<BR><BR>.PHONY : everything 
      deps objs clean veryclean rebuild<BR><BR>everything : 
      $(EXECUTABLE)<BR><BR>deps : $(DEPS)<BR><BR>objs : $(OBJS)<BR><BR>clean 
      :<BR>@$(RM-F) *.o<BR>@$(RM-F) *.d<BR><BR>veryclean: clean<BR>@$(RM-F) 
      $(EXECUTABLE)<BR><BR>rebuild: veryclean everything<BR><BR>ifneq 
      ($(MISSING_DEPS),)<BR>$(MISSING_DEPS) :<BR>@$(RM-F) $(patsubst 
      %.d,%.o,$@)<BR>endif<BR><BR>-include $(DEPS)<BR><BR>$(EXECUTABLE) : 
      $(OBJS)<BR>gcc -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))<BR><BR>=== 
      makefile 结束 ===<BR><BR>有几个地方值得解释一下的。首先,我在定义大部分变量的时候使 用的是 := 而不是 = 
      符号。它的作用是立即把定义中参考到的函 数和变量都展开了。如果使用 = 的话,函数和变量参考会留在那 
      儿,就是说改变一个变量的值会导致其它变量的值也被改变。例 如:<BR><BR>A = foo<BR>B = $(A)<BR># 现在 B 是 
      $(A) ,而 $(A) 是 'foo' 。<BR>A = bar<BR># 现在 B 仍然是 $(A) ,但它的值已随着变成 'bar' 
      了。<BR>B := $(A)<BR># 现在 B 的值是 'bar' 。<BR>A = foo<BR># B 的值仍然是 'bar' 
      。<BR><BR>make 会忽略在 # 符号后面直到那一行结束的所有文字。<BR><BR>ifneg...else...endif 系统是 
      makefile 里让某一部分码有条件的 失效/有效的工具。 ifeq 使用两个参数,如果它们相同,它把直 到 else (或者 endif 
      ,如果没有 else 的话)的一段码加进 makefile 里;如果不同,把 else 到 endif 间的一段码加入 makefile (如果有 
      else )。 ifneq 的用法刚好相反。<BR><BR>'filter-out' 函数使用两个用空格分开的列表,它把第二列表中所 
      有的存在于第一列表中的项目删除。我用它来处理 DEPS 列表,把所 有已经存在的项目都删除,而只保留缺少的那些。<BR><BR>我前面说过, 
      CPPFLAGS 存有用于隐含规则中传给预处理器的一些 旗标。而 -MD 开关类似 -M 开关,但是从源码文件 .c 或 .cc 中 
      形成的文件名是使用后缀 .d 的(这就解释了我形成 DEPS 变量的 步骤)。DEPS 里提到的文件后来用 '-include' 加进了 
      makefile 里,它隐藏了所有因文件不存在而产生的错误信息。<BR><BR>如果任何依靠文件不存在, makefile 会把相应的 .o 
      文件从磁碟 上删除,从而使得 make 重建它。因为 CPPFLAGS 指定了 -MD , 它的 .d 文件也被重新产生。<BR><BR>最后, 
      'addprefix' 函数把第二个参数列表的每一项前缀上第一 个参数值。<BR><BR>这个 makefile 的那些目的是(这些目的可以传给 
      make 的命令行 来直接选用):<BR><BR>everything:(预设) 更新主要的可执行程序,并且为每一个 源码文件生成或更新一个 
      '.d' 文件和一个 '.o' 文件。<BR><BR>deps: 只是为每一个源码程序产生或更新一个 '.d' 文件。<BR><BR>objs: 
      为每一个源码程序生成或更新 '.d' 文件和目标文件。<BR><BR>clean: 删除所有中介/依靠文件( *.d 和 *.o 
      )。<BR><BR>veryclean: 做 `clean' 和删除可执行文件。<BR><BR>rebuild: 先做 `veryclean' 然后 
      `everything' ;既完全重建。<BR><BR>除了预设的 everything 以外,这里头只有 clean , veryclean , 
      和 rebuild 对用户是有意义的。<BR><BR>我还没有发现当给出一个源码文件的目录,这个 makefile 会失败的 
      情况,除非依靠文件被弄乱。如果这种弄乱的情况发生了,只要输入 `make clean' ,所有的目标文件和依靠文件会被删除,问题就应该 
      被解决了。当然,最好不要把它们弄乱。如果你发现在某种情况下这 个 makefile 
      文件不能完成它的工作,请告诉我,我会把它整好的。<BR><BR><BR>3 
      总结<BR>~~~~~~~~~~~~~~~<BR><BR>我希望这篇文章足够详细的解释了多文件项目是怎么运作的,也说明了 
      怎样安全而合理的使用它。到此,你应该可以轻松的利用 GNU Make 工 具来管理小型的项目,如果你完全理解了后面几个部分的话,这些对于 
      你来说应该没什么困难。<BR><BR>GNU Make 是一件强大的工具,虽然它主要是用来建立程序,它还有很多 
      别的用处。如果想要知道更多有关这个工具的知识,它的句法,函数, 和许多别的特点,你应该参看它的参考文件 (info pages, 别的 GNU 
      工具也一样,看它们的 info pages. )。</FONT><FONT color=#008000 
  size=2><BR></FONT></TD></TR></TBODY></TABLE></CENTER></DIV>
<TABLE height=1 cellPadding=0 width=758 border=0>
  <TBODY>
  <TR>
    <TD width=752 height=1>
      <HR color=#ffff00>
    </TD></TR>
  <TR>
    <TD width=752 height=6>
      <P align=center><A href="http://kexinspace.myrice.com/">可心工作室制作 
      版权所有</A><BR><FONT 
  color=#0000ff>haokexin@netease.net</FONT></P></TD></TR></TBODY></TABLE></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -