📄 1007.html
字号:
# distribute this without giving<br>
# credit to the original author.<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>
EXECUTABLE := mushroom.exe<br>
LIBS := alleg<br>
# Now alter any implicit rules' variables if you like, e.g.:<br>
#<br>
# 现在来改变任何你想改动的隐含规则中的变量,例如<br>
CFLAGS := -g -Wall -O3 -m486<br>
CXXFLAGS := $(CFLAGS)<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 命令,如果没有,我们使用 del 命令来代替,但有可能给我们 'File not found' 这个错误信息,这没 # 什么大碍。如果你不是用 DOS ,把它设定成一个删文件而不废话的命令。 (其实这一步在 UNIX 类的系统上是多余的,只是方便 DOS 用户。 UNIX 用户可以删除这5行命令。)<br>
<br>
ifneq ($(wildcard $(DJDIR)/bin/rm.exe),)<br>
RM-F := rm -f<br>
else<br>
RM-F := del<br>
endif<br>
# You shouldn't need to change anything below this point.<br>
#<br>
# 从这里开始,你应该不需要改动任何东西。(我是不太相信,太NB了!)<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>
..PHONY : everything deps objs clean veryclean rebuild<br>
everything : $(EXECUTABLE)<br>
deps : $(DEPS)<br>
objs : $(OBJS)<br>
clean :<br>
@$(RM-F) *.o<br>
@$(RM-F) *.d<br>
veryclean: clean<br>
@$(RM-F) $(EXECUTABLE)<br>
rebuild: veryclean everything<br>
ifneq ($(MISSING_DEPS),)<br>
$(MISSING_DEPS) :<br>
@$(RM-F) $(patsubst %.d,%.o,$@)<br>
endif<br>
-include $(DEPS)<br>
$(EXECUTABLE) : $(OBJS)<br>
gcc -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))<br>
=== makefile 结束 ===<br>
<br>
有几个地方值得解释一下的。首先,我在定义大部分变量的时候使 用的是 :=<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>
make 会忽略在 # 符号后面直到那一行结束的所有文字。<br>
ifneg...else...endif 系统是 makefile 里让某一部分码有条件的 失效/有效的工<br>
具。 ifeq 使用两个参数,如果它们相同,它把直 到 else (或者 endif ,如果没有<br>
else 的话)的一段码加进 makefile 里;如果不同,把 else 到 endif 间的一段码加入<br>
makefile (如果有 else )。 ifneq 的用法刚好相反。 'filter-out' 函数使用两个用<br>
空格分开的列表,它把第二列表中所 有的存在于第一列 表中的项目删除。我用它来处理<br>
DEPS 列表,把所 有已经存在的项目都删除,而只保留缺少的那些。<br>
我前面说过, CPPFLAGS 存有用于隐含规则中传给预处理器的一些 旗标。而 -MD 开<br>
关 类似 -M 开关,但是从源码文件 .c 或 .cc 中 形成的文件名是使用后缀.d 的(这就<br>
解释了我形成 DEPS 变量的 步骤)。DEPS 里提到的文件后来用 '-include' 加进了 makefile<br>
里,它隐藏了所有因文件不存在而产生的错误信息。 如果任何依靠文件不存在, makefile<br>
会把相应的 .o 文件从磁碟 上删除,从而使得 make 重建它。因为 CPPFLAGS 指定了-MD,<br>
它的 .d 文件也被重新产生。 最后, 'addprefix' 函数把第二个参数列表的每一项前缀<br>
上第一个参数值。这个makefile的那些目的是(这些目的可以传给make的命令行来直接选用):<br>
everything:(预设) 更新主要的可执行程序,并且为每一个 源码文件生成或更新一个 '.d' <br>
文件和一个 '.o' 文件。 deps: 只是为每一个源码程序产生或更新一个 '.d' 文件。 <br>
objs: 为每一个源码程序生成或更新 '.d' 文件和目标文件。 clean: 删除所有中介/<br>
依靠文件( *.d 和 *.o )。<br>
veryclean: 做 `clean' 和删除可执行文件。<br>
rebuild: 先做 `veryclean' 然后 `everything' ;既完全重建。<br>
除了预设的 everything 以外,这里头只有 clean , veryclean , 和rebuild 对用户是<br>
有意义的。 我还没有发现当给出一个源码文件的目录,这个 makefile 会失败的情况,除非依<br>
靠文件被弄乱。如果这种弄乱的情况发生了,只要输入 `make clean' , 所有的目标文件和依<br>
靠文件会被删除,问题就应该 被解决了。当然,最好不要把它们弄乱。如果你发现在某种情况<br>
下这个makefile 文件不能完成它的工作,请告诉我,我会把它整好的。<br>
3 总结<br>
我希望这篇文章足够详细的解释了多文件项目是怎么运作的,也说明了 怎样安全而合理的<br>
使用它。到此,你应该可以轻松的利用 GNU Make 工 具来管理小型的项目,如果你完全理解了<br>
后面几个部分的话,这些对于 你来说应该没什么困难。 GNU Make 是一件强大的工具,虽然它<br>
主要是用来建立程序,它还有很多 别的用处。如果想要知道更多有关这个工具的知识,它的句<br>
法,函数,和许多别的特点,你应该参看它的参考文件(info pages, 别的GNU工具也一样, 看<br>
它们的 info pages. )。<br>
<br>
<br>
文章摘要:<br>
无论是在linux还是在Unix环境中,make都是一个非常重要的编译命令。不管是自己进行项<br>
目开发还是安装应用软件,我们都经常要用到make或make install,有效的利用make和makefile<br>
工具可以大大提高项目开发的效率。但令人遗憾的是,在许多讲述linux应用的书籍上都没有详细<br>
介绍这个功能强大但又非常复杂的编译工具。在这里我就向大家详细介绍一下make及其描述文件makefile。<br>
<http://member.netease.com/%7Ehalon/unixfaq/unix_31.htm> <br>
<br>
正文: <br>
linux/Unix环境下的make和makefile详解 <br>
Pathetique<br>
<br>
无论是在linux还是在Unix环境中,make都是一个非常重要的编译命令。不管是自己进行项<br>
目开发还是安装应用软件, 我们都经常要用到make或make install。利用make工具,我们可以<br>
将大型的开发项目分解成为多个更易于管理的模块, 对于一个包括几百个源文件的应用程序,<br>
使用make和makefile工具就可以简洁明快地理顺各个源文件之间纷繁复杂的相互关系。 而且如<br>
此多的源文件,如果每次都要键入gcc命令进行编译的话,那对程序员来说简直就是一场灾难。<br>
而make工具则可自动完成编译工作,并且可以只对程序员在上次编译后修改过的部分进行编译。<br>
因此,有效的利用make和makefile工具可以大大提高项目开发的效率。同时掌握make和makefile<br>
之后,您也不会再面对着linux下的应用软件手足无措了。<br>
但令人遗憾的是,在许多讲述linux应用的书籍上都没有详细介绍这个功能强大但又非常复<br>
杂的编译工具。在这里我就向大家详细介绍一下make及其描述文件makefile。<br>
<br>
Makefile文件<br>
<br>
Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自<br>
动维护编译工作。而makefile文件需要按照某种语法进行编写,文件中需要说明如何编译各个源<br>
文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile文件是许多编译器--<br>
包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友<br>
好的界面修改 makefile 文件而已。<br>
在UNIX系统中,习惯使用Makefile作为makfile文件。如果要使用其他文件作为 makefile,<br>
则可利用类似下面的 make 命令选项指定 makefile 文件:<br>
$ make -f Makefile.debug<br>
例如,一个名为prog的程序由三个C源文件filea.c、fileb.c和filec.c以及库文件LS编译生<br>
成,这三个文件还分别包含自己的头文件a.h 、b.h和c.h。通常情况下, C编译器将会输出三个<br>
目标文件filea.o、fileb.o和filec.o。 假设filea.c和fileb.c都要声明用到一个名为defs的文<br>
件,但filec.c不用。即在filea.c和fileb.c里都有这样的声明:<br>
#include "defs"<br>
那么下面的文档就描述了这些文件之间的相互联系:<br>
---------------------------------------------------------<br>
#It is a example for describing makefile<br>
prog : filea.o fileb.o filec.o<br>
cc filea.o fileb.o filec.o -LS -o prog<br>
filea.o : filea.c a.h defs<br>
cc -c filea.c<br>
fileb.o : fileb.c b.h defs<br>
cc -c fileb.c<br>
filec.o : filec.c c.h<br>
cc -c filec.c<br>
----------------------------------------------------------<br>
这个描述文档就是一个简单的makefile文件。<br>
从上面的例子注意到,第一个字符为 # 的行为注释行。第一个非注释行指定prog由三个目<br>
标文件filea.o、fileb.o和filec.o链接生成。第三行描述了如何从prog所依赖的文件建立可执<br>
行文件。接下来的4、6、8行分别指定三个目标文件,以及它们所依赖的.c和.h文件以及defs文<br>
件。而5、7、9行则指定了如何从目标所依赖的文件建立目标。<br>
当filea.c或a.h文件在编译之后又被修改,则 make 工具可自动重新编译filea.o,如果在<br>
前后两次编译之间,filea.C 和a.h 均没有被修改,而且 test.o 还存在的话, 就没有必要重<br>
新编译。这种依赖关系在多源文件的程序编译中尤其重要。通过这种依赖关系的定义,make 工<br>
具可避免许多不必要的编译工作。当然,利用 Shell 脚本也可以达到自动编译的效果,但是,<br>
Shell 脚本将全部编译任何源文件,包括哪些不必要重新编译的源文件,而 make 工具则可根据<br>
目标上一次编译的时间和目标所依赖的源文件的更新时间而自动判断应当编译哪个源文件。<br>
Makefile文件作为一种描述文档一般需要包含以下内容:<br>
◆ 宏定义<br>
◆ 源文件之间的相互依赖关系<br>
◆ 可执行的命令<br>
Makefile中允许使用简单的宏指代源文件及其相关编译信息,在linux中也称宏为变量。在<br>
引用宏时只需在变量前加$符号,但值得注意的是,如果变量名的长度超过一个字符,在引用时<br>
就必须加圆括号()。<br>
下面都是有效的宏引用:<br>
$(CFLAGS)<br>
$2<br>
$Z<br>
$(Z)<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -