cxMake使用问题、Gcc编译选项问题、GNU连接问题
一、GNUMake使用
make工作自动确定工程的哪部分需要重新编译,执行命令去编译它们。虽然make多
用于C程序,然而只要提供命令行的编译器,你可以将其用于任何语言。
如果要使用make,你必须写一个叫做―makefile‖的文件,这个文件描述工程中文件之间
的关系,提供更新每个文件的命令。典型的工程是这样的:可执行文件靠目标文件来更新,
目标文件靠编译源文件来更新。
Makefile写好之后,每次更改了源文件后,只要执行make就足够了,所有必要的重新
编译将执行。Make程序利用makefile中的数据库和文件的最后修改时间来确定那个文件需
要更新;对于需要更新的文件,make执行数据库中记录的命令。
可以提供命令行参数给make来控制那个文件需要重新编译。
1.1Makefile介绍
Makefile文件告诉make做什么,多数情况是怎样编译和链接一个程序。
这里有一个简单的makefile,描述如何编译链接由8个C文件和3个头文件组成的一个
编辑器:
edit:ay.o
.o
cc–ay.o
.o
main.o:.h
cc–cmain.c
kdb.o:nd.h
cc–ckbd.c
command.o:nd.h
cc-ccommand.c
display.o:r.h
cc-cdisplay.c
inrt.o:r.h
cc-cinrt.c
arch.o:r.h
cc-carch.c
files.o:nd.h
cc-cfiles.c
utils.o:.h
cc-cutils.c
clean:
ay.o
.o
将长行用分开便于阅读,这和使用一个长行的作用是一样的。使用这个makefile创建
可执行文件“edit”时运行make就可以了;如果要将可执行文件和目标文件删除,执行make
clean
make重新编译这个编辑器时,每个更改的C文件必须重新编译;如果头文件更改了,
每个包含头文件的C文件必须重新编译;每次编译产生一个对应于原文件的目标文件。最
终,目标文件链接在一起产生新的可执行文件。
1.2规则简介
makefile中的规则是这样的:
TARGET…:DEPENDENCIES…
COMMAND
…
目标(TARGET)程序产生的文件,如可执行文件和目标文件;目标也可以是要执行的
动作,如“clean”。
依赖(DEPENDENCIES)是用来产生目标的输入文件,一个目标通常依赖于多个文件。
命令(COMMAND)是make执行的动作,一个可以有多个命令,每个占一行。注意:
每个命令行的起始字符必须为TAB字符!
有依赖关系规则中的命令通常在依赖文件变化时负责产生target文件,make执行这些
命令更新或产生target。规则可以没有依赖关系,如包含target“clean”的规则。
规则解释如何和何时重做该规则中的文件,make根据依赖关系执行产生或更新目标;
规则也说明如何和何时执行动作。有的规则看起来很复杂,但都符合上述模式。
1.3make工作原理
缺省make从第一个target开始(第一个非‘.‘开始的target),这称作缺省目标。在上
述的makefile中,缺省目标是更新执行程序‘edit‘,将这个目标置于最前面。当执行make的
时候,make程序从当前目录读入makefile开始处理第一个规则;在例子中,这个规则是重
新链接‘edit‘;在make处理这个规则之前,必须处理‘edit‘所依赖的那些文件的规则,例子中
是目标文件。这些文件按照他们自己的规则处理:通过编译源文件来更新每个‘.o‘文件;当
依赖关系中的源文件或头文件比目标文件新,或目标文件不存在时,必须重新编译。
其它的规则被处理是因为他们的target是目标的依赖,和目标没有依赖关系的规则不会
被处理,除非指定make处理(如makeclean)。
在重新编译目标文件之前,make会试图更新它的依赖:源文件和头文件。例子中的
makefile对源文件和头文件未指定任何操作:‘.c‘和‘.h‘文件不是任何规则的目标。确认所有
的目标文件都是最新的之后,make决定是否重新链接‘edit‘:如果‘edit‘不存在,或者任何一
个目标文件都比它新,华字 则链接工作将进行。
这样,如果我们改变inrt.c运行make,make会编译这个文件来更新‘inrt.o‘,然后链
接‘edit‘;如果修改了‘command.h‘运行make,‘kbd.o‘,‘command.o‘,‘files.o‘会重新生成,
链接‘edit‘。
1.4使用变量
在例子中,在规则‘edit‘中,目标文件被列出来两次:
edit:ay.o
.o
ay.o
.o
这样的重复容易出错:假设工程中加入了一个新的目标文件,可能只将其加入了一个列
表中;通过使用变量可以消除这种风险:变量允许一个预定义的字符串在多个地方被替换。
在makefile中,可以写这样一行来定义‘object‘变量:
objects=ay.o
.o
于是在需要目标文件名列表的地方,使用$(object)来代替变量的值。以下是使用了变
量以后的makefile:
objects=ay.o
.o
edit:$(objects)
cc-oedit$(objects)
main.o:.h
cc-cmain.c
kbd.o:nd.h
cc-ckbd.c
command.o:nd.h
cc-ccommand.c
display.o:r.h
cc-cdisplay.c
inrt.o:r.h
cc-cinrt.c
arch.o:r.h
cc-carch.c
files.o:nd.h
cc-cfiles.c
utils.o:.h
cc-cutils.c
clean:
rmedit$(objects)
1.5简化命令
为每个文件写出编译命令不是必要的,因为make可以自己来做;以‘.c‘文件更新‘.o‘文
件有一个隐含的规则,使用‘cc-c‘命令。Make将利用‘cc–cmain.c–omain.o‘来将main.c编
译为main.o,因此在生成目标文件的规则中,可以省略命令。
当‘.c‘文件以这样的方式使用时,将自动加入到依赖关系中;由是在省略命令的前提下,
可以将‘.c‘文件从依赖关系中省略。以下是简化过的makefile:
objects=ay.o
.o
edit:$(objects)
cc-oedit$(objects)
main.o:defs.h
kbd.o:nd.h
command.o:nd.h
display.o:r.h
inrt.o:r.h
arch.o:r.h
files.o:nd.h
utils.o:defs.h
.PHONY:clean
clean:
-rmedit$(objects)
1.6另一种风格
如果makefile中的目标都是以隐含规则生成,可以将规则按照依赖关系分组:
objects=ay.o
.o
edit:$(objects)
cc-oedit$(objects)
$(objects):defs.h
.o:command.h
.o:buffer.h
这里‘defs.h‘作为所有目标文件的依赖。这种风格是好是坏取决于个人喜好,它非常紧
凑,但是将每个目标的依赖信息放在一起看起来更清楚一些。
1.7清理
编写规则不至于编译程序。Makefile通常描述如何做其它事情:比如删除目录中的目标
文件和可执行文件来清理目录。例子中是这样写的:
clean:
rmedit$(objects)
实际情况是,我们需要处理一些意外事件:存在一个叫做‘clean‘的文件;如果rm出错,
并不希望make过程停止下来,修改过的版本如下:
.PHONY:clean
clean:
-rmedit$(objects)
这样的规则当然不能放在makefile的开始,因为这并不是我们缺省要做的工作。由
于‘clean‘并不是‘edit‘的依赖,在运行make时没有参数时,这条规则不会执行;要执行这个
规则,必须运行‘makeclean‘。
Makefile
Makefile中包含五种内容:显式规则,隐式规则,变量定义,指令(directive)和注释。
显式规则描述如何生成规则的目标,它列出了目标依赖的文件,指定了产生或更新
目标的命令
隐式规则描述如何生成基于文件名的一类文件,说明目标可能依赖于和其文件名类
似的文件,指定了相应的命令。
指令类似与编译器的伪指令,包含:
指示make读入另一个makefile
决定是否忽略makefile中的一部分
定义一个变量
一行中‗#‘开始是注释,直到行末,除非遇到续行符号。在‘define‘和命令中不能有
注释,其它情况下注释可出现在任何地方。
1.8makefile名字
缺省情况下,make以下列名字查找makefile:‘GNUmakefile‘,‘makefile‘和‘Makefile‘
(注意大小写)。通常你的makefile应叫做‘makefile‘或‘Makefile‘。‘GNUmakefile‘不推荐,
除非你的makefile是为GNU的make定制的,其它的make不认为该名字是一个makefile
的名字。
如果你使用非标准命名的makefile,必须用命令开关‘-f‘或‘—file‘。参数‘–fNAME‘
或‘—fileNAME‘告诉make读入NAME作为makefile。如果使用多个该开关,所有的文件将
按顺序连接起来。如果使用该选项,标准的makefile名字不会自动检测。
1.9包含
‗include‘指令告诉make暂停处理余下的内容,读入其它makefile。语法如下:
includeFILENAMES…
这一行起始可以有空格,但TAB字符不允许。如果文件名包含变量或函数,这些将被
扩展。
1.10‘MAKEFILE’变量
如果环境变量‘MAKEFILE‘已定义,make认为它的值是一系列空格隔开的文件名,这
些文件在处理其它makefile前被make程序读入。这类似于include指令;这些文件中的目
标不会影响缺省目标,而且如果文件未找到的话,make并不认为是错误。
这个变量的主要用途是递归引用make程序时通讯
1.11如何重新生成makefile
有时候makefile是从其它文件生成的,比如RCS或SCCS文件。如果makefile是由其
它文件生成的,需要make读入最新版本的makefile。
在读入所有makefile之后,make认为每个makefile是一个目标,试图去更新它;如果
makefile中有一条如何更新它的规则,或者有适用的隐式规则,需要的更新会进行。所有的
makefile检查完之后,如果有的改变了,make重新开始再读入(make会试图再做更新,但
通常不会再改变了,因为已经是最新的了)。
如果一个文件使用双冒号规则,提供了命令但没有依赖关系,文件始终会被更新。在
makefile的情况下,如果makefile双冒号规则,提供了命令但没有依赖关系,这样makefile
始终会重新生成,这会导致循环:make只是在不断更新makefile,却不干活。为避免这种
情况,make不会重新生成那些只有命令没有依赖关系的双冒号规则的makefile。
如果没有使用‘-f‘或‘--file‘选项,make会尝试缺省的makefile文件名。和指明‘-f‘或‘--file‘
选项不同,make不能确定这些文件是否应当存在。然而,如果缺省makefile不存在但可以
通过运行make规则生成,你可能希望这些规则被运行使得makefile可以使用。
因此,如果没有缺省makefile,make试图按照makefile名查找的顺序生成它,直到成
功或名字用完。注意如果make不能找到或生成makefile,这并不是错误;makefile不总是
必需的。
当使用‘-t‘或‘--touch‘选项时,不希望使用过时的makefile来决定那个目标来touch。所
以‘-t‘选项对makefile更新不起作用;类似‘-q‘(or‗—question‘)和‘-n‘(or‘—just-print‘)不
阻止makefile的更新,因为过时的makefile会产生错误的输出。这样‘make–fmfile–nfoo‘
会更新‘mfile‘,读入它,打印出更新‘foo‘需要执行的命令但不运行这些命令。与‘foo‘有关的
命令是更新过的‘mfile‘中的内容。
但是有时不希望更新makefile,可以将makefile作为命令行的目标,当makefile被显式
指定为目标时,‘-t‘选项也适用于它们。
这样‘make–fmfile–nmfilefoo‘会读入‘mfile‘,打印出更新执行的命令,‘foo‘的命令是
当前的‘mfile‘中的内容。
1.12重载makefile
可以使用‘include‘指令来包含其它makefile,增加目标的变量定义。然而,make不允许
同一个目标有不同的命令,有其它的途径可以达到目的。
假设有‘makefile‘和‘mfile‘,‘makfile‘要包含‘mfile‘,但都有对于目标‘foo‘的规则。这是
可以在‘makefile‘中写一条匹配任意模式的规则,指明当make在‘makefile‘中未找到目标时,
搜索‘mfile‘:
foo:
frobnicate>foo
%:force
@$(MAKE)-fmfile$@
force:;
当执行‘makefoo‘时,make找到‘makefile‘,执行命令‘frobnicate>foo‘;执行‘makebar‘
时,在‘makefile‘中未找到相应的规则,这时模式规则适用,执行命令‘make–fmfile
bar‘,‘makefile‘中未提及的其它目标也是类似的。
这种方法之所有工作手机黑色壁纸 是因为模式规则的模式是‘%‘,可以匹配任何的目标;这条规则的
依赖是‘force‘,保证即使目标存在命令也会执行;‘force‘规则的命令为空防止‘make‘为其搜
索隐式规则-这样会导致依赖循环。
规则
makefile中的规则描述如何生成特定的文件,即规则的目标。规则列出了目标的依赖文
件,指定生成或更新目标的命令。
规则的次序是不重要的,除非是确定缺省目标:缺省目标是第一个makefile中的第一个
规则;如果第一个规则有多个目标,第一个目标是缺省的。有两个例外:以‘.‘开头的目标不
是缺省目标;模式规则对缺省目标没有影响。
通常我们所写的地一个规则是编译整个或makefile中指定的所有程序。
1.13例子
foo.o:.h#modulefortwiddlingthefrobs
cc-c-gfoo.c
它的目标是‘foo.o‘,依赖于‘foo.c‘和‘defs.h‘,有一个命令‘cc–c–gfoo.c‘。命令行以TAB
字符开始标识它是一个命令。
这条规则说明两件事:
如何决定‘foo.o‘是旧的:如果它不存在,或者‘foo.c‘或者‘defs.h‘比它新。
如何更新‘foo.o‘文件:通过运行‘cc‘程序。命令未提及‘defs.h‘,担可以猜想‘foo.c‘
包含了它,这是‘defs.h‘被置于依赖关系中的理由。
1.14规则的语法
语法如下:
TARGETS:DEPENDENCIES
COMMAND
...
或者
TARGETS:DEPENDENCIES;COMMAND
COMMAND
...
TARGETS是以空格隔开的文件名,统配符可以使用。通常一个规则只有一个目标,偶
尔也有多个。
命令行以TAB键开始。第一条命令可在依赖关系的下一行;或者在同一行,在分号后
面;两种方式效果相同。
因为‘$‘符号被用做变量引用,如果要在规则中使用‘$‘符号,必须写两个:‘$$‘。可以用‘‘
符号来分割一个长行,这不是必须的,因为make对行的长度没有限制。
1.15通配符
规则中的文件名可以包含统配符,如‘*‘,‘?‘。
文件名前的字符‘~‘有特殊的含义。单独使用,或跟随一个‘/‘,代表用户的home目录,
比如‘~/bin‘扩展为/home/you/bin‘;如果‘~‘跟随一个单词,表示单词指示的那个用户的home
目录,如‘~john/bin‘扩展为‘/home/john/bin‘。
通配符在目标,依赖关系,命令中自动扩展,其它情况下,统配符的扩展除非显式使
用‘wildcard‘函数。通配符的特殊意义可以使用‘‘符号关闭。
例子:
clean:
rm-f*.o
和
print:*.c
lpr-p$?
touchprint
通配符在定义变量时并不扩展,例如:
objects=*.o
则objects的值是字符串‘*.o‘;但是如果你将objects用于目标,依赖或命令中,扩展会
进行。要将objects设置成扩展过的内容,使用:
objects:=$(wildcard*.o)
1.15.1通配符的缺陷
这是一个使用通配符的例子,但结果不是你所期望的。假设可执行文件‘foo‘是从当前目
录中的所有‘.o‘文件生成的:
objects=*.o
foo:$(objects)
cc-ofoo$(CFLAGS)$(objects)
objects变量的值是字符串‘*.o‘。通配符扩展在规则‘foo‘中进行,于是所有存在的‘.o‘文
件成为‘foo‘的依赖而且在需要时重新编译。
但如果删除了所有的‘.o‘文件呢?当通配符不匹配任何文件时,一切都保持原样:则‘foo‘
依赖于一个叫做‘*.o‘的文件;由于这个文件不大可能存在,‘make‘程序会报告一个无法生
成‘*.o‘文件的错误,这不是期待的结果。
实际上可以用通配符获得期望结果,但是需要复杂的技术,包括‘wildcard‘函数和字符
串替换函数。
1.15.2wildcard函数
通配符自动在规则中进行。但是在变量赋值的和函数的参数中通配符不会扩展,如果在
这些情况下需要通配符扩展,必须使用‘wildcard‘函数。语法如下:
$()
这个在makefile任何地方出现的字符串,会被匹配任何一个文件名格式的以空格隔开的
现有文件列表替换。如果没有任何文件匹配一个模式,这个模式从‘wildcard‘的输出中忽略,
注意,这和上述的通配符的处理是不一样的。
‗wildcard‘函数的一个功能是找出目录中所有的‘.c‘文件:
$(wildcard*.c)
可以通过替换后缀‘.c‘为‘.o‘从C文件列表得到目标文件的列表:
$(patsubst%.c,%.o,$(wildcard*.c))
这样,上节中的makefile改写为:
objects:=$(patsubst%.c,%.o,$(wildcard*.c))
foo:$(objects)
cc-ofoo$(objects)
这个makefile利用了编译C程序的隐含规则,所以不需要对编译写出显式的规则。(‘:=‘
是‘=‘的一个变体)
注意:‘PATTERN‘是大小写敏感的。
1.16目录搜索
对于大的系统,通常将源文件和目标文件放在不同的目录中。目录搜索功能可以让make
自动在多个目录中搜寻依赖文件,当你将文件重新分布是,不需要改变规则,更改搜索路径
即可。
1.16.1‘VPATH’
make变量‘VPATH‘列出make应当搜索的目录列表。很多情况下,当前目录不包含依赖
文件,‘VPATH‘描述一个对所有文件的搜索列表,包含那些是规则的目标的文件。
如果一个目标或者依赖文件在当前目录没找到的话,‘make‘在‘VPATH‘中列出的目录中
查找同名的文件。如果找到的话,那个文件成为依赖文件;规则可以象这些文件在当前目录
中一样来使用他们。
在‘VPATH‘变量中,目录名以冒号或空格隔开;目录列出的顺序决定make查找的顺序。
(注:在pSOSystem2.5移植到Win32的GNUmake目录名必须使用分号隔开,以下均简称
Win32GNUmake)。举例说明:
VPATH=src:../headers则规则
foo.o:foo.c
被解释为
foo.o:src/foo.c
假设‘foo.c‘在当前目录不存在,在‘src‘目录中可以找到。
1.16.2选择性搜索
与‘VPATH‘变量相似但更具选择性的是‘vpath‘指令(注意是小写),可以指定对于符合
特定模式文件的查找路径。这样可以为不同类型的文件指定不同的搜索路径。
‗vpath‘指令共有三中形式:
‗vpathPATTERNDIRECTORIES‘
为匹配PATTERN的文件名指定搜索路径DIRECTORIES,目录的分隔和‘VPATH‘的相
同
‗vpathPATTERN‘
清除为匹配PATTERN的文件名指定的搜索路径
‗vpath‘
清除所有以前用‘vpath‘指定的搜索路径
‗vpath‘的模式是包含‘%‘的字符串:这个字符串必须匹配需要搜索的依赖文件名,‘%‘
字符匹配0个或多个任意字符。例如:‘%.h‘匹配任何以‘.h‘结尾的文件(如果没有%,则
PATTERN必须和依赖文件完全一致,这种用法不太多)。
当当前目录中不存在依赖文件时,如果‘vpath‘中的PATTERN匹配依赖文件名,则指令
中DIRECTORIES列出的目录和‘VPATH‘中同样处理。举例:
vpath%.h../headers
告诉make在当前目录中未找到的‘.h‘文件在../headers目录中查找。
如果多个‘vapth‘的模式匹配依赖文件名,make将逐一处理,在所有指定的目录中搜索。
Make按照‘vapth‘在makefile中的次序;来处理它们,多个相同模式的‘vapth‘是相互独立的。
vpath%.cfoo
vpath%blish
vpath%.cbar
将按照‘foo‘,‗blish‘,‘bar‘的次序查找‘.c‘文件。而
vpath%.cfoo:bar
vpath%blish
按照‘foo‘,‘bar‘,‘blish‘的顺序搜索。
1.16.3使用自动变量
目录搜索的结果并不改变规则中的命令:命令按原样被执行。因此,必须写出与目录搜
索功相适应的命令。这可以通过使用‘$^‘这样的自动变量来完成。‘$^‘表示规则中的所有依
赖文件,包含它们所在的目录名(参见目录搜索);‘$@‘表示目标。例如:
foo.o:foo.c
cc-c$(CFLAGS)$^-o$@
通常情况下,依赖文件也包含头文件,但命令中并不提及这些文件:变量‘$<‘表示第一
个依赖文件:
VPATH=src:../headers
foo.o:.h
cc–c$(CFLAGS)$<-o$@
1.16.4目录搜索和隐含规则
使用‘VPATH‘和‘vpath‘指定目录搜索也会影响隐含规则。例如:文件‘foo.o‘没有显式规
则,make会考虑隐式规则:如果‘foo.c‘存在则编译它;如果这个文件不存在,则在相应的
目录中查找;如果‘foo.c‘在任一的目录中存在,则C编译的隐式规则被应用。
隐式规则的命令使用自动变量通常是必要的,这样无需其它努力即可以使用目录搜索得
到的文件名。
1.17PHONY目标
Phony目标并非实际的文件名:只是在显式请求时执行命令的名字。有两种理由需要使
用phony目标:避免和同名文件冲突,改善性能。
如果编写一个规则,并不产生目标文件,则其命令在每次make该目标时都执行。例如:
clean:
rm*.otemp
因为‘rm‘命令并不产生‘clean‘文件,则每次执行‘makeclean‘的时候,该命令都会执行。
如果目录中出现了‘clean‘文件,则规则失效了:没有依赖文件,文件‘clean‘始终是最新的,
命令永远不会执行;为避免这个问题,可使用‘.PHONY‘指明该目标。如:
.PHONY:clean
这样执行‘makeclean‘会无视‘clean‘文件存在与否。
已知phony目标并非是由其它文件生成的实际文件,make会跳过隐含规则搜索。这就
是声明phony目标会改善性能的原因,即使你并不担心实际文件存在与否。完整的例子如下:
.PHONY:clean
clean:
rm*.otemp
phony目标不应是真正目标文件的依赖。如果这样,每次make在更新此文件时,命令
都会执行。只要phony目标不是真正目标的依赖,规则的命令只有在指定此目标时才执行。
Phony目标可以有依赖关系。当一个目录中有多个程序是,将其放在一个makefile中会
更方便。因为缺省目标是makefile中的第一个目标,通常将这个phony目标叫做‘all‘,其依
赖文件为各个程序:
all:prog1prog2prog3
.PHONY:all
prog1:.o
.o
prog2:prog2.o
cc-oprog2prog2.o
prog3:.o
.o
这样,使用‘make‘将可以将三个程序都生成了。
当一个phony目标是另一个的依赖,其作用相当于子程序,例如:
.PHONY:cleanallcleanobjcleandiff
cleanall:cleanobjcleandiff
rmprogram
cleanobj:
rm*.o
cleandiff:
rm*.diff
1.18FORCE目标
当规则没有依赖关系也没有命令,而且其目标不是存在的文件名,make认为此规则运
行时这个目标总是被更新。这意味着如果规则依赖于此目标,其命令总是被执行。
clean:FORCE
rm$(objects)
FORCE:
例中目标‘FORCE‘满足这种特殊条件,这样依赖于它的目标‘clean‘被强制执行其命令。
名字‘FORCE‘没有特殊含义,只不过通常这样用而已。这种方式使用‘FORCE‘和‘.PHONY:
clean‘效果相同。使用‘.PHONY‘更加明确高效,担不是所有的‘make‘都支持;这样许多
makefile中使用了‘FORCE‘。
1.19空目标
空目标(emptytarget)是phony目标的变种:用来执行显式请求的一个动作。和phony
目标不同的是:这个目标文件可以真实存在,担文件的内容无关紧要,通常是空的。空目标
文件的目的是利用其最后修改时间来记录命令最近一次执行的时间,这是通过使用‘touch‘
命令更新目标文件来达到的。
print:.c
lpr-p$?
touchprint
利用这条规则,执行‘makeprint‘时如果自上次‘makeprint‘之后任一文件改变了,‘lpr‘
命令会执行。自动变量‘$?‘是为了只打印出那些变化了的文件。
1.20内建的特殊目标
某些名字作为目标存在时有特殊含义。
★.PHONY该目标的依赖被认为是phony目标,处理这些目标时,命令无条件
被执行,不管文件名是否存在及其最后修改时间
★.SUFFIXES该目标的依赖被认为是一个后缀列表,在检查后缀规则时使用
★.DEFAULT该目标的规则被使用在没有规则(显式的或隐含的)的目标上。如
果‘DEFAULT‘命令定义了,则对所有不是规则目标的依赖文件都会执行该组命令
★.PRECIOUS该目标的依赖文件会受到特别对待:如果make被kill或命令的执行
被中止,这些目标并不删除;而且如果该目标是中间文件,在不需要时不会被删除。
可以将隐含规则的目标模式(如%.o)做为‘.PRECIOUS‘的依赖文件,这样可以保存
这些规则产生的中间文件。
★.INTERMEDIATE该目标的依赖文件被当作中间文件;如果该目标没有依赖文件,
则makefile中所有的目标文件均被认为是中间文件。
★.IGNORE在执行该目标的依赖规则的命令时,make会忽略错误,此规则本身
的命令没有意义。如果该规则没有依赖关系,表示忽略所有命令执行的错误,这种用
法只是为了向后兼容;由于会影响到所有的命令,所以不是特别有用,推荐使用其它
更有选择性忽略错误的方法。
★.SILENT在执行该目标的依赖规则的命令时,make并不打印命令本身。该规
则的命令没有意义。在‘.SILIENT‘没有依赖关系时,表示执行makefile中的所有命令
都不会打印,该规则只是为了向后兼容提供的。
★.EXPORT_ALL_VARIABLES只是作为一个目标存在,指示make将所有变量输
出到子进程中。
定义的隐含规则的后缀作为目标时,也认为它是特殊目标;两个后缀的连接也是一样,
比如‘.c.o‘。这些目标是后缀规则,一中定义隐式规则的过时方法(但仍然广泛使用)。后缀
通常以‘.‘开始,所以特殊目标也以‘.‘开始。
1.21一个规则多个目标
一条有多个目标的规则和写多条规则,每条一个目标作用是等同的。同样的命令应用于
所有目标,但其效用会因将实际目标以‘$@‘代替而不同。规则中所有目标的依赖关系是一
样的。
这在两种情况下有用:
★只有依赖关系,不需要命令。例如:
.o:command.h
★所有的目标同样的命令。命令不需要完全相同,因为在命令中可以使用‘$@‘:
bigoutputlittleoutput:text.g
generatetext.g-$(substoutput,,$@)>$@
和
bigoutput:text.g
generatetext.g-big>bigoutput
littleoutput:text.g
generatetext.g-little>littleoutput
等同。这里假设程序‘generate‘产生两种输出:一种使用‘-big‘选项,一种使用‘-little‘
选项。如果想象使用‘$@‘变化命令那样来变化依赖关系,不能通过多目标的普通规则实现,
但是可以通过模式规则来实现。
1.22一个目标多条规则
一个文件可以是多条规则的目标,所有规则的依赖关系被合并。如果目标比任一个依赖
文件旧,命令被执行。
一个文件只能有一组命令执行。如果多个规则对于同一个文件都给出了命令,make使
用最后一组并打印错误信息(特殊情况:如果文件名以‘.‘开始,并不打印错误信息,这一点
是为了和其它make兼容)。没有任何理由需要将makefile写成这样,这是make给出错误信
息的理由。
一条只有依赖关系的附加规则可以一次给出许多文件的附加依赖文件。例如‘objects‘变
量表示系统中编译器的所有输出.,说明当‘config.h‘更改时所有文件必须重做的简单方法如
下:
objects=.o
foo.o:defs.h
bar.o:.h
$(objects):config.h
不用改变实际目标文件生成的规则,这条规则可以在需要增删附加的依赖关系时插入或
提出。另一个诀窍是附加的依赖关系可以用变量表示,在make执行时,可以给变量赋值:
extradeps=
$(objects):$(extradeps)
当命令`makeextradeps=foo.h'执行时会认为‘foo.h‘是每个目标文件的依赖文件,但简单
的‘make‘命令不是这样。
1.23静态模式规则
静态模式规则(staticpatternrules)可以指定多个目标,并且使用目标名字来建议依赖
文件的名字;比普通多目标规则更通用因为不需要依赖关系是相同的:依赖关系必须类似但
不需要相同。
1.23.1语法
COMMANDS
...
TARGETS列表指出规则应用的目标,可以包含通配符,于普通规则的目标相同。
TARGET-PATTERN和DEP-PATTERNS来表明目标的依赖关系如何计算:匹配
TARGET-PATTERN的目标从名字中抽出一部分,叫做词干(stem),词干被替换到
DEP-PATTERNS来形成依赖文件名。
每个模式通常包含一个‘%‘字符。当TARGET-PATTERN匹配一个目标时,‘%‘字符可以
匹配目标名中的任何部分;这部分即是词干,模式的其余部分必须完全匹配。例如‘foo.o‘
匹配‘%.o‘,‘foo‘是词干;目标‘foo.c‘和‘‘并不匹配这个模式。
目标的依赖文件名通过将DEP-PATTERNS中的‘%‘替换为词干形成:如果依赖模式
为‘%.c‘,在替换词干‘foo‘可以得到‘foo.c‘。依赖模式中不包含‘%‘也是合法的,此依赖文件
对所有的目标均有效。
如果需要在模式规则中使用‘%‘字符,必须在其前面加‘‘字符,如果‘%‘前的‘‘字符是有
实际意义的,必须在其前面加‘‘,其它的‘‘不必如此处理。如‘the%weird%pattern‘在有效
的‘%‘前是‘the%weird‘,其后是‘pattern‘。最后的‘‘保持原样是因为其并不影响‘%‘字符。
以下例子从相应的‘.c‘文件编译‘foo.o‘和‘bar.o‘:
objects=.o
$(objects):%.o:%.c
$(CC)-c$(CFLAGS)$<-o$@
每个目标必须匹配目标模式,对于不匹配的目标会给出警告。如果列表中只有部分文件
匹配模式,可以使用filter函数移去不匹配的文件名:
files=.o
$(filter%.o,$(files)):%.o:%.c
$(CC)-c$(CFLAGS)$<-o$@
$(filter%.elc,$(files)):%.elc:%.el
emacs-fbatch-byte-compile$<
例子中`$(filter%.o,$(files))'结果是`.o‘;`$(filter%.elc,$(files))'的结果是
`'。以下例子说明‘$*‘的使用:
bigoutputlittleoutput:%output:text.g
generatetext.g-$*>$@
命令`generate'执行时,‘$*‘扩展为词干‘big‘或‘little‘。
1.23.2静态模式规则和隐式规则
静态模式规则和隐式规则在作为模式规则是具有很多共同点,都有目标模式和构造依赖
文件名的模式,不同之处在于make决定何时应用规则的方法。
隐式规则可应用于匹配其模式的任何目标,但只限于没有指定命令的目标,如果有多条
可应用的隐式规则,只有一条被使用,取决于规则的顺序。
反之,静态模式规则适用于规则中明确目标列表,不适用于其它目标且总是适用于指定
的每个目标。如果有两条冲突的规则,且都有命令,这是一个错误。
静态模式规则比隐式规则优越之处如下:
★可为一些不能按句法分类,但可以显式列出的文件重载隐式规则
★不能判定目录中的精确内容,一些无关的文件可能导致make适用错误的隐式规则;
最终结果可能依赖于隐式规则的次序。适用静态模式规则时,这种不确定性是不存在
的:规则适用于明确指定的目标。
1.24双冒号规则
双冒号规则(Double-colonrules)的目标后是‘::‘而不是‘:‘,当一个目标出现在多条规则
中时,其处理和普通规则的处理不同。
当一个目标出现在多条规则中时,所有规则必须是相同类型的:都是普通的或者都是双
冒号的。如果是双冒号,规则之间相互独立;如果目标需要更新,则规则的命令被执行;结
果可能是没有执行,或者执行了其中一些,或者所有的规则都执行了。
同一目标的双冒号规则事实是完全孤立的,每条规则被被单独处理,就象不同目标的规
则一样;规则按照在makefile中出现的次序被处理,此类规则真正有意义的是那些于命令执
行次序无关的。
这种规则有时比较晦涩不是特别有用;它提供了一种机制:通过不同依赖文件的更新来
对目标进行不同的处理,这种情形很罕见。每个这种规则应当提供命令,如果没有,适用的
隐式规则将使用。
1.25自动生成依赖关系
在makefile中,许多规则都是一些目标文件依赖于一些头文件。例如:‘main.c‘通
过‘#include‘使用‘defs.h‘,这样规则:
main.o:defs.h
告诉make在‘defs.h‘变化时更新‘main.o‘。在程序比较大时,需要写许多这样的规则;
而且当每次增删‘#include‘时,必须小心的更新makefile。许多现代的编译器可以帮你写这些
规则,通常这是通过编译器的‘-M‘选项,例如命令:
cc–Mmain.c
输出以下内容:
main.o:.h
这样就不必写这些规则,有编译器代劳了。
注意这样的依赖关系中提及‘main.o‘,不会被隐式规则认为是中间文件,这意味这make
在使用过它之后不会将其删除。使用老的‘make‘程序时,习惯做法是使用‘makedepend‘命令
利用编译器的功能产生依赖关系,该命令会产生一个‘depend‘文件包含所有自动产生的依赖
关系,然后在makefile中使用‘include‘将其读入。
使用GNU的make时,重新生成makefile的功能使得这种做法变得过时:从不需要显
式请求更新依赖关系,因为它总是重新生成任何过时的makefile。
自动依赖关系生成推荐的做法是对每个源文件做一个makefile。对每个源文
件‘NAME.c‘,有一个makefile‘NAME.d‘,其中列出了目标文件‘NAME.o‘依赖的所有文件,
这样在源文件更新时,需要扫描来产生新的依赖关系。例子是一个从‘NAME.c‘产生依赖关
系文件‘NAME.d‘的模式规则:
%.d:%.c
$(SHELL)-ec'$(CC)-M$(CPPFLAGS)$<
|d'''s/($*).o[:]*/1$@/g'''>$@'
-e选项是当$(CC)命令失败时(exit状态非0),shell立刻退出。通常shell的返回值是
管道中最后一条命令(d)的返回值,这样make不会注意到编译器出错。
使用GNU的C编译器时(gcc),可以用‘-MM‘选项来代替‘-M‘选项,这样省略系统头
文件的依赖关系。‘d‘命令的目的是将
main.o:.h
转换为
.d:.h
这样使得每个‘.d‘文件依赖于‘.o‘文件相应源文件和头文件,make则可以在原文间或头
文件变化时更新依赖关系文件。
如果定义了生成‘.d‘文件的规则,可以使用‘include‘指令来读入所有的文件:
sources=.c
include$(sources:.c=.d)
例中使用替换变量来将源文件列表‘.c‘转换为依赖关系文件的列表。因为‘.d‘文
件和其它文件一样,不需要更多工作,make会在需要时重新生成它们。
编写命令
规则的命令是由一一执行的shell命令组成。除了以分号隔开写在依赖关系后的命令,
每个命令行必须以tab字符开始空行和注释行可以出现在命令行中,处理时被忽略(注意:
以tab字符开始的空行不是‘空‘行,是一条空命令)。
可以在命令中使用任何程序,但这些程序是由$(SHELL)来执行的。
1.26回显
通常make打印出要执行的命令,称之为回显,这和亲自敲命令的现象是一样的。当行
之前有‘@‘字符时,命令不再回显,字符‘@‘在传递给shell前丢弃。典型的用法是只对打印
命令有效,比如‘echo‘命令:
@echoAbouttomakedistributionfiles
当make使用‘-n‘或‘—just-print‘选项时,显示要发生的一切,但不执行命令。只有在这
种情况下,即使命令以‘@‘开始,命令行仍然显示出来。这个选项对查看make实际要执行
的动作很有用。
‗-s‘或‘—silent‘选项阻止make所有回显,就象所有命令以‘@‘开始一样;一条没有依赖
关系的‘.SILENT‘规则有相同的作用,但是‘@‘更加灵活。
1.27执行
在需要执行命令更新目标时,make为每一行创建一个子shell来执行。这意味着诸如为
进程设置局部变量的shell命令‘cd‘(改变进程的当前目录)不会影响以后的命令。如果需
要‘cd‘影响下一个命令,将它们放在一行上用分号隔开,这样make认为是一条命令传递给
shell程序(注意:这需要shell支持):
foo:bar/lo
cdbar;gobblelo>../foo
另一个形式使用续行符:
foo:bar/lo
cdbar;
gobblelo>../foo
shell程序的名字是通过‘SHELL‘变量来取得的。
(*UNIX)不象大多数变量,‘SHELL‘变量不是通过环境来设置的(即需要在makefile
中设置),因为‘SHELL‘环境是个人选择的,如果不同人的选择会影响makefile的功能的话,
这样很糟糕。
1.28并行执行
GNUmake可以一次执行几条命令。通常make一次执行一条命令,等待其返回,再执
行下一条。使用‘-j‘或‘—jobs‘可以同时执行多条命令。如果‘-j‘后梗一个正数,表示一次可以
执行的命令条数;如果‘-j‘之后没有参数,则不限制可执行的命令数。缺省的数量是一。
一个讨厌的问题是如果同时执行多条命令,它们的输出会混在一起;另一个问题是两个
进程不能从同一个设备获得输入。
1.29错误
每条shell命令返回时,make会检查其返回状态。如果命令执行成功,则下一条命令被
执行,最后一条命令执行完后,规则执行结束。
如果有错误(返回非0状态),make放弃当前规则,也可能是所有规则。
有时候命令执行错误并不是问题,比如使用‘mkdir‘命令确保目录存在:如果目录一存
在,则‘mkdir‘会报告错误,但仍希望make继续。
要忽略命令的错误,在命令之前使用‘-‗字符,‘-‗字符在传递给shell之前被丢弃:
clean:
-rm-f*.o
如果使用‘-i‘或‘—ignore-errors‘选项,make会忽略所有命令产生的错误;一条没有依赖
关系的‘.IGNORE‘规则有相同的作用,但‘-‗更灵活。
在忽略错误时,make将错误也认为是成功,只是通知你命令的退出状态和和错误被忽
略。如果make并未告知忽略错误,在错误发生时,表明该目标不能成功更新,直接或间接
依赖于此的目标当然也不能成功;这些目标的命令不会被执行,因为其先决条件不满足。
通常make会立即以非0状态退出。然而,如果给定‘-k‘或‘—keep-going‘选项,make在
退出前会处理其它的依赖关系,进行必要的更新。例如,在编译一个目标文件遇到错误,‘make
-k‘会继续编译其它的目标文件。
通常认为你的目的是更新指定的目标,当make知道这是不可能时,会立即报告失败;‘-k‘
选项指示真正目的是测试更新程序的更多可能性:在编译之前找出更多不相关的问题。
如果命令失败了,假设它更新的目标文件,这个文件是不完整的不能使用-至少不是完
全更新的。但文件的最后修改时间表明停已经是最新的,下一次make运行时,不会再更新
这个文件。这种情况和命令被kill相同;则通常情况下在命令失败时将目标删除是正确的;
当‘.DELETE_ON_ERROR‘是目标时make帮你做这件事。虽然你总是希望make这么做,
但这不是过去的习惯;所以必须显式要求make这样做(其它的make自动这样做)。
1.30中断make
如果make执行命令时遇到错误,可能会删除命令更新的目标文件:make检查文件的
修改时间是否变化。删除目标的目的是确保make下次执行时重新生成它。为什么这样做?
假设在编译器运行时按了‘Ctrl-c‘,此时编译器写生成目标文件‘foo.o‘。‘Ctrl-c‘kill了编译器,
留下一个不完整的文件,但它的修改时间比源文件‘foo.c‘新;此时make也受到‘Ctrl-c‘信号
删除这个不完整的文件,如果make不这样做,下次make运行时认为‘foo.o‘不需要更新,
会在链接时出现奇怪的错误。
可以使用‘.PRECIOUS‘规则来防止目标文件被删除。在make更新目标时,会检测其是
否为‘.PRECIOUS‘的依赖,决定在命令出错或中断时是否删除该目标。如果你希望目标的
更新是原子操作,或是用来记录修改时间,或必须一直存在防止其它类型的错误,这些理由
使得你必须这样做。
1.31递归使用
递归使用make就是在makefile中使用make命令。这种技术在你将一个大系统分解为
几个子系统,为每个自系统提供一个makefile时有用处。比如有一个子目录‘subdir‘中有自
己的makefile,希望make在自目录中运行,可以这样做:
subsystem:
cdsubdir;$(MAKE)
或者
subsystem:
$(MAKE)-Csubdir
可以照抄这个;例子来递归使用make
1.31.1‘MAKE’变量
递归的make必须使用‘MAKE‘变量,不是显式的make命令:
subsystem:
cdsubdir;$(MAKE)
该变量的值是被调用的make的名字。在命令中使用‘MAKE‘有特殊的功能:它改变了
`-t'(`--touch'),`-n'(`--just-print')和`-q'(`--question')选项的含义。使用上例来考虑‘make–t‘
命令(‘-t‘选项将目标标记为最新但不运行命令),更加‘-t‘选项的功能,该命令将创建一
个‘subsystem‘文件,实际希望的操作是运行‘cdsubdir;make–t‘;但这会执行命令,与‘-t‘的
原意不符。
这个特殊功能做了期望的工作。当命令行包含变量‘MAKE‘时,选项‘-t‘,‘-n‘和‘-q‘并不
适用。不管这些导致不会执行命令的标志,包含‘MAKE‘变量的命令始终会执行。正常
的‘MAKEFLAGS‘机制将这些标志传递到子make,这样打印命令的请求被传播到子系统中。
1.31.2传递变量到子make
上级(top-level)make中的变量可以显式通过环境传递到子make中。在子make中,
这些变量被缺省定义,但不会重载子makefile中的定义除非使用‘-e‘选项。
为向下传递,或输出变量,make在运行命令时将其加入到环境变量中;子make,可以
使用环境变量来初始化变量表。除非显式要求,make只输出初始环境中或命令行设置的变
量而且变量名只由字母,数字和下划线组成。一些shell不能处理有其它字符的环境变量。
特殊变量‘SHELL‘,‘MAKEFLAGS‘总是输出,如果‘MAKEFILE‘变量有值,也会输出。
Make自动通过‘MAKEFLAGS‘来输出命令行定义的变量。
如果想要输出特定变量,使用‘export‘指令:
如果要阻止输出一个变量,使用‘unexport‘指令:
为方便起见,可以在定义变量时输出它:
exportVARIABLE=value
和
VARIABLE=value
exportVARIABLE
作用相同。
如果要输出所有的变量,使用‘export‘指令本身就可以了。
变量‘MAKELEVEL‘在一级一级传递时会改变,这个变量的值是表示嵌套层数的字符
串,顶级‘make‘是,变量的值为‘0‘;子make的值为‘1‘;子子make的值为‘2‘,依此类推。
‘MAKELEVEL‘的用途是在条件指令中测试它,这样写出在递归运行时和直接运行时
表现不同的makefile。
以下内容拷贝自GNUMakeManual
命令行参数
`-b'
`-m'
Theoptionsareignoredforcompatibilitywithotherversionsof`make'.
`-CDIR'
`--directory=DIR'
iple
`-C'optionsarespecified,eachisinterpretedrelativetothe
previousone:`-C/-Cetc'iquivalentto`-C/etc'.Thisis
typicallyudwithrecursiveinvocationsof`make'(*note
RecursiveUof`make':Recursion.).
`-d'
`--debug'
debugginginformationsayswhichfilesarebeingconsideredfor
remaking,whichfile-timesarebeingcomparedandwithwhat
results,whichfilesactuallyneedtoberemade,whichimplicit
rulesareconsideredandwhichareapplied--everythinginteresting
abouthow`make'decideswhattodo.
`-e'
`--environment-overrides'
Givevariablestakenfromtheenvironmentprecedenceover
variablesfrommakefiles.*NoteVariablesfromtheEnvironment:
Environment.
`-fFILE'
`--file=FILE'
`--makefile=FILE'
ReadthefilenamedFILEasamakefile.
`-h'
`--help'
Remindyouoftheoptionsthat`make'understandsandthenexit.
`-i'
`--ignore-errors'
Ignoreallerrorsincommandxecutedtoremakefiles.
`-IDIR'
`--include-dir=DIR'
ral`-I'optionsare
udtospecifyveraldirectories,thedirectoriesarearched
intheorderspecified.
`-j[JOBS]'
`--jobs=[JOBS]'
Specifiesthenumberofjobs(commands)torunsimultaneously.
Withnoargument,`make'runsasmanyjobssimultaneouslyas
eismorethanone`-j'option,thelastoneis
effective.
`-k'
`--keep-going'
hetargetthat
failed,andthothatdependonit,cannotberemade,theother
dependenciesofthetargetscanbeprocesdallthesame.
`-l[LOAD]'
`--load-average[=LOAD]'
`--max-load[=LOAD]'
Specifiesthatnonewjobs(commands)shouldbestartedifthere
areotherjobsrunningandtheloadaverageisatleastLOAD(a
floating-pointnumber).Withnoargument,removesapreviousload
limit.*NoteParallelExecution:Parallel.
`-n'
`--just-print'
`--dry-run'
`--recon'
Printthecommandsthatwouldbeexecuted,butdonotexecutethem.
`-oFILE'
`--old-file=FILE'
`--assume-old=FILE'
DonotremakethefileFILEevenifitisolderthanits
dependencies,anddonotremakeanythingonaccountofchangesin
iallythefileistreatedasveryoldanditsrules
areignored.
`-p'
`--print-data-ba'
Printthedataba(rulesandvariablevalues)thatresultsfrom
readingthemakefiles;thenexecuteasusualorasotherwi
soprintstheversioninformationgivenbythe
`-v'switch(ebelow).Toprintthedatabawithouttryingto
remakeanyfiles,u`make-p-f/dev/null'.
`-q'
`--question'
"Questionmode".Donotrunanycommands,orprintanything;just
returnanexitstatusthatiszeroifthespecifiedtargetsare
alreadyuptodate,oneifanyremakingisrequired,ortwoifan
errorincountered.
`-r'
`--no-builtin-rules'
stilldefineyourownbywriting
`-r'optionalsoclearsoutthedefaultlist
canstilldefineyourownsuffixeswitha
rulefor`.SUFFIXES',andthendefineyourownsuffixrules.
`-s'
`--silent'
`--quiet'
Silentoperation;donotprintthecommandsastheyareexecuted.
`-S'
`--no-keep-going'
`--stop'
Canceltheeffectofthe`-k'nevernecessary
exceptinarecursive`make'where`-k'mightbeinheritedfrom
thetop-level`make'via`MAKEFLAGS'orifyout`-k'in`MAKEFLAGS'inyour
environment.
`-t'
`--touch'
Touchfiles(markthemuptodatewithoutreallychangingthem)
udtopretendthat
thecommandsweredone,inordertofoolfutureinvocationsof
`make'.
`-v'
`--version'
Printtheversionofthe`make'programplusacopyright,alist
ofauthors,andanoticethatthereisnowarranty;thenexit.
`-w'
`--print-directory'
Printamessagecontainingtheworkingdirectorybothbeforeand
ybeufulfortracking
downerrorsfromcomplicatednestsofrecursive`make'commands.
`--no-print-directory'
Disableprintingoftheworkingdirectoryunder`-w'.Thisoption
isufulwhen`-w'isturnedonautomatically,butyoudonot
wanttoetheextramessages.
`-WFILE'
`--what-if=FILE'
`--new-file=FILE'
`--assume-new=FILE'
ed
withthe`-n'flag,thisshowsyouwhatwouldhappenifyouwere
t`-n',itisalmostthesameas
runninga`touch'commandonthegivenfilebeforerunning`make',
exceptthatthemodificationtimeischangedonlyinthe
imaginationof`make'.
`--warn-undefined-variables'
Issueawarningmessagewhenever`make'esareferencetoan
nbehelpfulwhenyouaretryingto
debugmakefileswhichuvariablesincomplexways.
参考
1.32指令
`defineVARIABLE'
`endef'
Defineamulti-line,recursively-expandedvariable.
*NoteSequences::.
`ifdefVARIABLE'
`ifndefVARIABLE'
`ifeq(A,B)'
`ifeq"A""B"'
`ifeq'A''B''
`ifneq(A,B)'
`ifneq"A""B"'
`ifneq'A''B''
`el'
`endif'
Conditionallyevaluatepartofthemakefile.
`includeFILE'
Includeanothermakefile.
`overrideVARIABLE=VALUE'
`overrideVARIABLE:=VALUE'
`overrideVARIABLE+=VALUE'
`overridedefineVARIABLE'
`endef'
Defineavariable,overridinganypreviousdefinition,evenone
fromthecommandline.
`export'
Tell`make'toexportallvariablestochildprocessbydefault.
`exportVARIABLE'
`exportVARIABLE=VALUE'
`exportVARIABLE:=VALUE'
`exportVARIABLE+=VALUE'
`unexportVARIABLE'
Tell`make'whetherornottoexportaparticularvariabletochild
process.
`vpathPATTERNPATH'
Specifyaarchpathforfilesmatchinga`%'pattern.
*NoteThe`vpath'Directive:SelectiveSearch.
`vpathPATTERN'
RemoveallarchpathspreviouslyspecifiedforPATTERN.
`vpath'
Removeallarchpathspreviouslyspecifiedinany`vpath'
directive.
1.33函数
`$(substFROM,TO,TEXT)'
ReplaceFROMwithTOinTEXT.
`$(patsubstPATTERN,REPLACEMENT,TEXT)'
ReplacewordsmatchingPATTERNwithREPLACEMENTinTEXT.
`$(stripSTRING)'
RemoveexcesswhitespacecharactersfromSTRING.
`$(findstringFIND,TEXT)'
LocateFINDinTEXT.
`$(,TEXT)'
SelectwordsinTEXTthatmatchoneofthePATTERNwords.
`$(,TEXT)'
SelectwordsinTEXTthat*donot*matchafold nyofthePATTERNwords.
`$(sortLIST)'
SortthewordsinLISTlexicographically,removingduplicates.
`$()'
Extractthedirectorypartofeachfilename.
`$()'
Extractthenon-directorypartofeachfilename.
`$()'
Extractthesuffix(thelast`.'andfollowingcharacters)ofeach
filename.
`$()'
Extractthebaname(namewithoutsuffix)ofeachfilename.
`$()'
AppendSUFFIXtoeachwordinNAMES.
`$()'
PrependPREFIXtoeachwordinNAMES.
`$(joinLIST1,LIST2)'
Jointwoparallellistsofwords.
`$(wordN,TEXT)'
ExtracttheNthword(one-origin)ofTEXT.
`$(wordsTEXT)'
CountthenumberofwordsinTEXT.
`$()'
ExtractthefirstwordofNAMES.
`$()'
Findfilenamesmatchingashellfilenamepattern(*not*a`%'
pattern).夏天的成语有哪些
`$(shellCOMMAND)'
Executeashellcommandandreturnitsoutput.
`$(originVARIABLE)'
Returnastringdescribinghowthe`make'variableVARIABLEwas
defined.
`$(foreachVAR,WORDS,TEXT)'
EvaluateTEXTwithVARboundtoeachwordinWORDS,and
concatenatetheresults.
1.34自动变量
`$@'
Thefilenameofthetarget.
`$%'
Thetargetmembername,whenthetargetisanarchivemember.
`$<'
Thenameofthefirstdependency.
`$?'
Thenamesofallthedependenciesthatarenewerthanthetarget,
endencieswhicharearchive
members,onlythemembernamedisud
endencieswhicharearchive
members,onlythemembernamedisud
`$^'
`$+'
Thenamesofallthedependencies,
dependencieswhicharearchivemembers,onlythemembernamedis
ueof`$^'omitsduplicate
dependencies,while`$+'retainsthemandprervestheirorder.
`$*'
Thestemwithwhichanimplicitrulematches
`$(@D)'
`$(@F)'
Thedirectorypartandthefile-within-directorypartof`$@'.
`$(*D)'
`$(*F)'
Thedirectorypartandthefile-within-directorypartof`$*'.
`$(%D)'
`$(%F)'
Thedirectorypartandthefile-within-directorypartof`$%'
`$(
`$(
Thedirectorypartandthefile-within-directorypartof`$<'
`$(^D)'
`$(^F)'
Thedirectorypartandthefile-within-directorypartof`$^'
`$(+D)'
`$(+F)'
Thedirectorypartandthefile-within-directorypartof`$+'
`$(?D)'
`$(?F)'
Thedirectorypartandthefile-within-directorypartof`$?'
1.35特殊变量
`MAKEFILES'
Makefilestobereadoneveryinvocationof`make'.
`VPATH'
Directoryarchpathforfilesnotfoundinthecurrentdirectory.
`SHELL'
Thenameofthesystemdefaultcommandinterpreter,usually
`/bin/sh'.Youcant`SHELL'inthemakefiletochangethe
shelludtoruncommands.
`MAKE'
Thenamewithwhich`make'hisvariablein
commandshasspecialmeaning.
`MAKELEVEL'
Thenumberoflevelsofrecursion(sub-`make's).
`MAKEFLAGS'
Theflagsgivento`make'.Youcantthisintheenvironmentor
amakefiletotflags.
`SUFFIXES'
Thedefaultlistofsuffixesbefore`make'readsanymakefiles.
Make是一种代码维护工具.在大中型项目中,他将根据程序各个模块的更新情况,自动的维
护和生成目标.
下面是对上面的一些命令的中文解释
Make[option][macrodef][target]
Option指出make的工作行为,make的具体选项有:
-cdirmake在开始运行后的工作目录为指定目录
-e不允许在makefile中对环境的宏赋值
-ffilename使用指定的文件作makefiel
-k执行命令出错时,放弃改目标去维护其它目标
-n按实际运行时的执行顺序现回显命令,包括用@开头的命令,但不执行
-p打印makefile中所有的宏定义,和内部规则
-r忽略内部规则
-s执行但不显示命令,常用来检查makefile的正确性
-S执行make时出错即退出
-t修改每个目标文件的创建日期,但又不改变它的内容
-V打印make的版本号
-x将所有的宏定义输出到shell环境中
-i忽略运行make中的错误,而又不退出make
:^将指定的依赖文件和目标文件已有的依赖文件结合起来
:-清除目标文件原有的依赖文件,将指定文件为目标文件的唯一依赖文件
:!对每个更新过的依赖文件都执行一遍命令菜单
+当运行条件成熟(依赖文件过时)始终执行,即使make有-n-q-t选项
-当此行出错时,忽略继续运行make
@不显示本行命令(make执行使命令行在屏幕上打印)
.IGNORE类似于命令行中的减号,在本目标维护出错时.并不马上退出make而是继续运行
.SILENT类似于命令行中的@,维护本目标时不在屏幕上显示
.PRECIOUS保留中间文件
.LIBARY说明维护的目标是一个库
.SYMBOL说明维护的目标是指定入口的库成员
.LIBRARYM说明维护的是库的一个成员
$@当前目标文件的名字
$%同$@,不过若维护的目标是库时.$@指库名$%指库成员
$>适用于lib(member)的情况$>指库名如$@
$*目标文件,去掉后缀
$&当前目标文件.在所有依赖文件
$^当前目标文件在本单元中的依赖文件
$?当情目标文件在所有单元中比目标新的依赖文件
$<当前目标文件在本单元中比目标文件新的文件
这些宏只能用在命令行中,make提供可与此对应的动态宏用在依赖文件中.他们分别是在上
面的宏上在加一个$
$$@在依赖文件列表中,代表目标文件的名字
.o目标文件
.cc语言源文件
.Cc++语言源文件
.h头文件
LD:连接命令ld
LDFLAGEA:ld的选项
二、Gcc编译选项问题
GNUCC的命令选项
GNUC编译器集成了C,C++和目标C编译器,可以编译用C,C++和目标C编写的程
序。这章主要讨论GNUCC的命令选项,关于C/C++语言的语法不再论叙。另外还需要说
明的几个缩写:GCC是GNUC编译器的缩写,G++是GNUC++编译器的缩写,GDB是GNU
调试器的缩写。
当你调用GNUCC时,它通常进行预处理,编译,汇编,链接。使用命令选项,你可
以指示GNUCC如何完成以上过程。
几点说明:
gcc接收命令选项和文件名作为参数,很多选项的名字是多个字符的,因此多个单
字符选项不能组合使用,eg:-dr是不同于-d–r的。
你可以混合使用命令选项和其它参数。一般地,命令选项的顺序没什么关系。当你
使用几个同类的选项时它们的顺序就有关系了。比如,你使用-L选项多次,那么
目录查找按指定的顺序进行。
很多选项拥有以-f或-W开头的长名,它们的大部分都有肯定和否定两种形式。比
如:-ffoo的否定形式是-fno-foo。这本手册仅说明两种形式的一种,无论哪一种都
不是约定的。
Overall选项――控制输出种类的选项
-c-S-E-ofile-pipe-v-xlanguage
编译总是按顺序调用预处理,编译,汇编,链接四个阶段。前三个阶段应用于一个单一
的原文件并生成一个目标文件;链接将所有目标文件组合为一个可执行文件。
你可以用-x选项明确地指定输入语言
-xlanguage
明确地为接下来的输入文件指定编程语言,而不是让编译器根据文件名后缀选择一个缺
省的编程语言。这个选项在遇到下一个-x选项前是生效的。编程语言的可能值如下:
cobjective-cc++
c-headercpp-outputc++-cpp-output
asmblerasmbler-with-cpp
-xnone
关闭编程语言的指定。编译器直接根据随后文件名后缀选择一种缺省的编程语言处理这
些文件。
如果你仅想编译某些阶段,你可以使用-x(或文件名后缀)来告诉gcc在什么地方开始,
使用-c,-S,或-E之一来gcc在什么地方结束。
-E预处理阶段后停止,不运行编译阶段。按预处理阶段原代码形式输出。不需要预处
理的输入文件被忽略。
-S编译阶段后停止,不运行汇编阶段。输出汇编原代码文件。不需要编译的输入文件
被忽略。
-c编译或汇编原文件,不进行链接。输出目标文件。不需要编译或汇编的输入文件被
忽略。
-ofile输出文件file。既然只能指定一个输出文件,那么当编译多个输入文件时,使
用-o指定输出文件是没有意义的,除非你要产生一个可执行文件。如果不指定-o选项,缺
省是输出一个可执行文件。
-v打印执行的命令。
-pipe使用pipe而不是临时文件用于编译的各个阶段之间的通信。
C语言选项――控制C语言的选项
-ansi-fallow-single-precision-fcond-mismatch
-fno-asm-fno-builtin-fsigned-bitfields
-fsigned-char-funsigned-bitfields-funsigned-char
-fwritable-strings-traditional-traditional-cpp
-trigraphs
-ansi完全支持ANSI标准C语言。这个选项关闭GNUC的某些与ANSI标准C不
兼容的某些特性。
-fno-asm不将asm,inline或typeof作为关键字。-ansi隐含了-fno-asm。
-fno-builtin不识别没有以两个下划线开始的内部函数。受到影响的函数包括abort,
abs,alloca,cos,exit,fabs,ffs,labs,memcmp,memcpy,sin,sqrt,strcmp,
strcpy和strlen。通常,GCC生成更短小更快捷代码来更有效地处理内部函数,但是在调用
这些函数时不能设置短点。-ansi选项禁止将alloca和ffs作为内部函数。
-trigraphs支持ANSIC的trigraph(三线图形)。-ansi隐含了-trigraphs。
-traditional尝试支持传统C的一些特征。如果你包含任何依赖ANSIC特征的头文件,
你不能使用-traditional。
-traditional-cpp尝试支持传统C预处理器的一些特征。
-fcond-mismatch允许条件表达式的第二第三个参数的类型不匹配。
-funsigned-char将类型char当作unsignedchar。
-fsigned-char将类型char当作signedchar。-fsigned-char等价于-fno-unsigned-char,同
样地,-funsigned-char等价于-fno-signed-char。
-fsigned-bitfields
-funsigned-bitfields
-fno-signed-bitfields
-fno-unsigned-bitfields
当定义没有使用signed或unsigned时,这些选项控制一个位域是否是signed还是
unsigned。缺省情况下,位域是signed。
-fwritable-strings将字符串常量保存到可写的数据段。这是为了与旧程序兼容。
-fallow-single-precision即使使用-traditional选项,也不提倡单精度数学运算作用于双精
度数。当用ANSI或GNUC约定编译时,这个选项不起作用。
C++语言选项――控制C++语言的选项
略
告警选项――要求或禁止告警的选项
告警选项是以-W开头的选项,有肯定和否定两种形式,它反映了编译过程中的各种告
警消息。
-fsyntax-only-pedantic-pedantic-errors
-w-W-Wall-Waggregate-return-Wbad-function-cast
-Wcast-align-Wcast-qual-Wchar-subscript-Wcomment
-Wconversion-Wenum-clash-Werror-Wformat
-Wid-clash-len-Wimplicit-Wimport-Winline
-Wlarger-than-len-Wmissing-declarations
-Wmissing-prototypes-Wnested-externs
-Wno-import-Woverloaded-virtual-Wparenthes
-Wpointer-arith-Wredundant-decls-Wreorder
-Wreturn-type-Wshadow-Wstrict-prototypes
-Wswitch-Wsynth-Wtemplate-debugging-Wtraditional
-Wtrigraphs-Wuninitialized-Wunud-Wwrite-strings
-fsyntax-only检查代码的语法错误。
-pedantic产生由严格的ANSI标准C要求的告警,拒绝所有使用禁止扩展性的程序。
带上这个选项,某些GNU的扩展性被拒绝。该选项是仅为了满足学究式人物的要求而设立。
建议不用。
-pedantic-errors除了产生错误和告警之外,像-pedantic一样。
-w禁止所有告警消息。
-Wno-import禁止关于使用#import的告警消息。
-Wchar-subscript如果数组下标是char类型的,那么产生告警。
-Wcomment无论何时注释符号对/**/中又出现/*或//中又出现/,那么产生告警。
-Wformat检查printf和scanf等等的调用,确保参数的类型的正确性。
-Wimplicit一个函数或参数无论何时被隐式声明,那么产生告警。
-Wparenthes如果圆括号不配对,那么产生告警。
-Wreturn-type一个函数无论何时被定义了一个int的返回类型,那么产生告警。
-Wswitch一个switch语句无论何时有一个枚举型的索引并且没有ca,那么产生
告警。有ca但超出枚举型的范围,也产生告警。
-Wtrigraphs如果遇上了任何trigraph(三线图形),那么产生告警。
-Wunud一个变量,一个静态函数或一个标号无论何时被声明但没有被使用,
那么产生告警。
-Wuninitialized一个自动变量没有初始化就被使用,那么产生告警。这些告警仅仅在
优化编译中才可能产生。
-Wenum-clash在不同枚举类型之间进行转换,产生告警。仅仅C++才有。
-Wreorder当代码中给出的成员初试化的顺序不匹配它们必须被执行的顺序时产生
告警。仅仅C++才有。
-Wtemplate-debugging当在C++程序中使用模板时,如果调试器还不能完全可用则产生
告警。仅仅C++才有。
-Wall以上所有-W选项的组合。建议避免使用。
剩下的-W选项没有被-Wall隐含。
-W打印告警信息。
-Wtraditional关于某些在传统C和ANSIC中有不同表现的结构,产生告警。
-Wshadow一个局部变量无论何时屏蔽另一个局部变量,产生告警。
-Wid-clash-len两个截然不同的标示符无论何时在第一个len字符匹配,产生告警。
-Wlarger-than-len一个比len字节更大的对象无论何时被定义,产生告警。
-Wpointer-arith关于依赖sizeof一个函数类型或void(指针)的任何东西。GNUC
给这些类型分配一个1的大小(asizeof1)。
-Wbad-function-cast无论何时一个函数调用被分配给一个不匹配的类型,则产生告
警。比如:如果将intmalloc()的函数指针赋给anything*的指针,则产生告警。
-Wcast-qual如果将一个指针分配给该指针类型除去类型限定词所定义的另一个指针,
则产生告警。比如:如果将constchar*的指针赋给普通的char*的指针,则产生告警。
-Wcast-align将一种类型的指针赋给另一种类型的指针则产生告警。比如:如果将char
*的指针赋给int*的指针,则产生告警。
-Wwrite-strings将一个字符串常量指针赋给另一个非字符串常量指针则产生告警。
比如:如果将constchar*的指针赋给non-constchar*的指针,则产生告警。
-Wconversion将一种类型的值(常量或表达式)赋给另一种类型的变量则产生告警。
比如:x是无符号的变量,如果使用x=-1,则产生告警。
-Waggregate-return如果定义或调用任何返回结构或联合的函数,则产生告警。
-Wstrict-prototypes如果一个函数被声明或定义但没有指明参数的类型则产生告警。
-Wmissing-prototypes如果一个全局函数被定义但在前面没有原形声明则产生告警。
-Wmissing-declarations如果一个全局函数被定义但在前面没有声明则产生告警。
-Wredundant-decls如果在同一作用域范围内任何东西被定义多次则产生告警。
-Wnested-externs如果在一个函数内遇到了extern的声明则产生告警。
-Winline如果一个函数不能被内联但它要么被声明为内联要么带有-finline-functions选
项,则产生告警。
-Woverloaded-virtual在定义的虚函数中,当取自类的函数声明可能是错误的时产生告
警。仅仅C++才有。
-Wsynth仅仅C++才有。
-Werror将所有的告警当作错误。
调试选项――调试程序或GCC的选项
-a-ax-dletters-fpretend-float
-g-glevel-gcoff-gdwarf-gdwarf+
-ggdb-gstabs-gstabs+-gxcoff-gxcoff+
-p-pg-print-file-name=library
-print-libgcc-file-name-print-prog-name=program
-save-temps
-print-prog-name=program-print-arch-dirs-save-temps
-g按操作系统固有的格式(stabs,COFF,XCOFF,或DWARF)产生调试信息。GDB
可以用这种调试信息工作。在大部分使用stabs格式的系统上,-g允许使用仅仅GDB可以
使用的附加的调试信息。
-ggdb按固有的格式产生调试信息,包括GDB扩展。
-gstabs按固有的格式产生调试信息,不包括GDB扩展。这是在大部分BSD系统上
DBX使用的格式。
-gstabs+按stabs格式产生调试信息,使用仅仅GNU调试器(GDB)理解的GNU扩
展。
-gcoff按COFF格式产生调试信息。这是在大部分SystemV系统上由SDB使用的格
式。
-gxcoff按XCOFF格式产生调试信息。这是在IBMRS/6000系统上由DBX调试器使
用的格式。
-gxcoff+按XCOFF格式产生调试信息,使用仅仅GNU调试器(GDB)理解的GNU
扩展。
-gdwarf按DWARF格式产生调试信息,这是在大部分SystemVRelea4系统上由
SDB使用的格式。
-gdwarf+按DWARF格式产生调试信息,使用仅仅GNU调试器(GDB)理解的GNU
扩展。
-glevel
-ggdblevel
-gstabslevel
-gcofflevel
-gxcofflevel
-gdwarflevel
要求调试信息,而且也使用level来指定调试信息的多少。缺省level是2。Level1产
生最少信息,足够回溯但不能调试。Level2产生的调试信息包括函数和外部变量的描叙,
但不包括局部变量和行号。Level3包括附加的信息,诸如全部的宏定义,某些调试器还支
持宏扩展。
-p产生附加代码来生成适合分析程序prof.的简要信息。
-pg产生附加代码来生成适合分析程序gprof.的简要信息。
-a产生附加代码来生成用于基本块的简要信息,它将记录基本块执行的次数,基本块
的开始地址,包含基本块的函数名。
-ax产生附加代码来简要描叙基本块,这个输出是-a选项输出的超集。附加的输出信息
包括:发生跳转的基本块的原和目的地址,跳转执行的次数,执行基本块的完成顺序。
-dletters在编译期间,按letters指定的时期转存调试信息。Letters可能的值及其意义如
下:
`M'Dumpallmacrodefinitions,attheendofpreprocessing,andwritenooutput.
`N'Dumpallmacronames,attheendofpreprocessing.
`D'Dumpallmacrodefinitions,attheendofpreprocessing,inadditiontonormaloutput.
`y'Dumpdebugginginformationduringparsing,tostandarderror.
`r'DumpafterRTLgeneration,writingoutputto`'.
`x'yudwith`r'.
`j'Dumpafterfirstjumpoptimization,writingoutputto`'.
`s'DumpafterCSE(includingthejumpoptimizationthatsometimesfollowsCSE),writing
outputto`'.
`L'Dumpafterloopoptimization,writingoutputto`'.
`t'DumpafterthecondCSEpass(includingthejumpoptimizationthatsometimes
followsCSE),writingoutputto`2'.
`f'Dumpafterflowanalysis,writingoutputto`'.
`c'Dumpafterinstructioncombination,tothefile`e'.
`S'Dumpafterthefirstinstructionschedulingpass,to`'.
`l'Dumpafterlocalregisterallocation,writingoutputto`'.
`g'Dumpafterglobalregisterallocation,writingoutputto`'.
`R'Dumpafterthecondinstructionschedulingpass,to`2'.
`J'Dumpafterlastjumpoptimization,writingoutputto`2'.
`d'Dumpafterdelayedbranchscheduling,writingoutputto`'.
`k'Dumpafterconversionfromregisterstostack,writingoutputto`'.
`a'Produceallthedumpslistedabove.
`m'Printstatisticsonmemoryusage,attheendoftherun,tostandarderror.
`p'Annotatetheasmbleroutputwithacommentindicatingwhichpatternandalternative
wasud.
-fpretend-float当运行一个交叉编译器时,假定目标机和主机使用相同的浮点格式。
-save-temps永久地保存临时的中间文件,将它们放在当前目录中并基于原文件给它们
命名。
-print-file-name=library仅仅打印出完整的绝对的库文件名library。
-print-prog-name=program查找并打印出完整的绝对的文件名program。
-print-libgcc-file-name等价于-print-libgcc-file-name=libgcc.a。当你使用选项`-nostdlib'
或`-nodefaultlibs'时是有用的。
-print-arch-dirs打印安装目录名,程序名列表和库目录。
最优化选项――控制最优化的选项
-fcaller-saves-fcombine-statics-fc-follow-jumps-fc-skip-blocks
-fdelayed-branch-fexpensive-optimizations
-ffast-math-ffloat-store-fforce-addr-fforce-mem
-ffunction-ctions-finline-functions-fkeep-inline-functions
-fno-default-inline-fno-defer-pop-fno-function-c
-fno-inline-fno-peephole-fomit-frame-pointer
-frerun-c-after-loop-fschedule-insns
-fschedule-insns2-fshorten-lifetimes-fstrength-reduce-fthread-jumps
-funroll-all-loops-funroll-loops
-O-O0-O1-O2-O3
-O
-O0不优化。
-O1优化。编译器尽力缩减代码的大小和运行时间。指定-o(其缺省值是-o1)打开
`-fthread-jumps',`-fdefer-pop',`-fdelayed-branch'和`-fomit-frame-pointer'。在某些机器也打
开其它标志。
-O2更大的优化。指定-02,GNUCC执行几乎所有支持的优化,只是不执行循环
的展开和函数的内联。
-O3最大的优化。-o3打开所有支持的优化。
-fno-defer-pop函数一返回就弹出参数给每个函数调用。
-fforce-mem在对内存操作数进行运算之前,强制将它们拷入寄存器。-o2打开了这个
选项。
-fforce-addr在对内存地址常量进行运算之前,强制将它们拷入寄存器。
-fomit-frame-pointer对于不需要帧指针的函数,不将它们保存进寄存器。
-fno-inline不关心inline关键字。
-finline-functions将所有简单的函数集成进它们的调用程序。
-fkeep-inline-functions即使对一个给出函数的所有调用被集成,并且这个函数被声明为
静态的。仍然输出一个独立的运行时可调用的函数版本。
-fkeep-static-consts即使变量不被引用,当优化没有被打开时,将声明的变量指定为
静态常量。缺省情况下,这个选项是打开的。
-fno-function-c不将函数地址放入寄存器中。
-fno-function-c这个选项允许GCC违背某些优化代码速度的ANSI或IEEE的约定。
以下选项控制特殊的优化,当使用"fine-tuning"时,以下选项很少使用。
-fstrength-reduce执行循环优化。
-fthread-jumps执行分支优化。
-fc-follow-jumps消除公用子表达式。例如:if…el…
-fc-skip-blocks有条件的跳过程序块。例如:if…
-frerun-c-after-loop执行循环优化或后,消除公用子表达式。
-frerun-c-after-loop执行许多局部的优化。
-fdelayed-branch如果目标机支持,尝试重排子令以利用延迟分支子令后的子令时间
片。
-fschedule-insns如果目标机支持,尝试重排子令来消除由于必要的数据不可用而造成
的执行停止。
-fschedule-insns2与-fschedule-insns相似。
-fshorten-lifetimes缩短被分配给专门的硬设备寄存器的虚寄存器的生命期。
-fcombine-statics将静态变量放入一个专门的块来允许编译器消除多余的地址装载。
-fcaller-saves允许将被函数连续调用的值分配在寄存器中。
-funroll-loops执行循环展开优化。`-funroll-loop'隐含了`-fstrength-reduce'和
`-frerun-c-after-loop'。它的反复次数仅仅在编译时或运行时被决定。
-funroll-all-loops执行循环展开优化。`-funroll-loop'隐含了`-fstrength-reduce'和
`-frerun-c-after-loop'。对所有的循环适用。
-fno-peephole禁止任何机器特定的优化。
预处理器选项――控制预处理器的选项
-Aquestion(answer)-C-dD-dM-dN
-Dmacro[=defn]-E-H
-idirafterdir
-includefile-imacrosfile
-iprefixfile-iwithprefixdir
-iwithprefixbeforedir-isystemdir
-M-MD-MM-MMD-MG-nostdinc-P-trigraphs
-undef-Umacro-Wp,option
-includefile在处理正常输入文件之前将file当作输入文件处理。命令行上的任何-D
和-U选项总是在-includefile之前处理。所有-include和-imacros选项按顺序被处理。
-imacrosfile在处理正常输入文件之前,将file当作输入文件处理,丢弃作为结果的输
出。
-idirafterdir将目录dir增加到第二个包含路径。当一个头文件在主包含路径的任何目
录中没有找到,则在第二个包含路径搜寻。
-iprefixprefix为后面的-iwithprefix选项指定prefix作为前缀。
-iwithprefixdir将目录dir增加到第二个包含路径。目录名为prefix+dir。
-iwithprefixbeforedir将目录dir增加到主包含路径。目录名为prefix+dir。
-isystemdir将目录dir增加到第二个包含路径的开始,将它标记为系统目录,以便它
与标准的系统目录有相同的待遇。
-nostdinc对头文件查找时不查找标准的系统目录,仅仅查找用-I选项指定的目录。
-undef不预定义任何非标准的宏(包括体系结构宏)。
-E仅仅运行C预处理器。
-C告诉预处理器不要丢弃注释。与-E选项一起使用。
-P告诉预处理器不要产生#line子令。与-E选项一起使用。
-M告诉预处理器输出一种适合make描叙每个目标文件的相互关系的规则。-M隐含
了-E。指定make规则输出的另一种方法是通过设置环境变量DEPENDENCIES_OUTPUT。
-MM与-M类似,但输出仅仅涉及用#include―file‖包含的用户头文件。
-MD与-M类似,但相关信息被写入一个文件,这个文件是在输入文件末尾用.d代
替.c生成的。
-MMD与-MD类似,但仅仅涉及用户头文件,不包括系统头文件。
-MG将不存在的头文件作为被生成的文件并假定它们与原文件在同一目录。如果指
定了-MG选项,你必须也指定-M或-MM。但-MG不与-MD或-MMD一起使用。
-H除了其它正常的活动之外,打印每个被使用的头文件。
-Aquestion(answer)确定问题的答案,假定它被一个预处理条件诸如#if
#question(answer)测试。
-Dmacro用字符串‘1’作为宏的定义来定义宏macro。
-Dmacro=defn定义宏macro为defn。命令行上的所有-D选项在-U选项之前处理。
-Umacro取消宏macro的定义。-U选项在任何`-include'和`-imacros'选项之前处理。
-dM告诉预处理器仅仅输出在预处理结束是有效的宏定义的列表。与-E选项一起
使用。
-dD告诉预处理器将所有宏定义按它们的顺序传递给输出。
-dN除了宏参数和内容被省略,与-dD一样。
-trigraphs支持ANSIC的trigraph(三线图形)。-ansi选项也有这个功能。
-Wp,option将option作为选项传给预处理器。如果option包含逗号,则它被逗号划
分为多个选项。
汇编器选项――传递选项给汇编器
-Wa,option
-Wa,option将option作为选项传给汇编器。如果option包含逗号,则它被逗号划分
为多个选项。
连接器选项――用于连接器的选项
当编译器将目标文件连接为一个可执行的输出文件时,这些选项开始生效。
object-file-name-llibrary
-nostartfiles-nodefaultlibs-nostdlib
-s-static-shared-symbolic
-Wl,option-Xlinkeroption
-usymbol
object-file-name一个不以专门的可辨认的后缀结束的文件被认为是一个目标文件或
库文件。连接器可以根据文件的内容将目标文件和库文件区分开来。
-c
-S
-E
如果这些选项的任何一个被使用,则连接器不运行,目标文件名也不应该被用作参数。
-llibrary当进行连接时,查找命名为library的库。
-lobjc为了连接一个目标C程序,你需要使用这个选项。
-nostartfiles当进行连接时,不使用标准系统启动文件。除非-nostdlib和-nodefaultlibs
被使用,否则正常情况下标准系统库被使用。
-nodefaultlibs当进行连接时,不使用标准系统库。仅仅你指定的文件被传给连接器。除
非nostartfiles被使用,否则正常情况下标准启动文件被使用。
-nostdlib当进行连接时,不使用标准系统启动文件或库。没有任何启动文件并且仅仅你
指定的库被传给连接器。在大部分情况下,即使当你想避开其它标准库时你还是需要
libgcc.a。换句句说,当你指定-nostdlib和-nodefaultlibs时,通常你也应该指定-lgcc。
-s从可执行程序中删除所有符号表和重定位信息。
-static在支持动态连接的系统中,这防止用共享库进行连接。在其它系统中,这个选
项无效。
-shared产生一个共享的目标程序,以后,这个目标程序可以与其它目标程序一起被连
接成一个可执行的文件。
-symbolic当建立一个共享的目标文件时,将引用绑定到全局符号。仅仅少数系统支
持这个选项。
-Xlinkeroption将option作为选项传给连接器。当传递带有参数的选项时,必须使
用-Xlinker两次。例如:为了传递-asrtdefinitions,你必须写-Xlinker-asrt-Xlinker
definitions,而不是-Xlinker"-asrtdefinitions"。
-Wl,option将option作为选项传给连接器。如果option包含逗号,则它被逗号划分
为多个选项。
-usymbol假定符号symbol没有定义,以便强迫连接的库模块来定义它。你可
以用不同的符号多次使用-u以便强迫加载附加的库模块。
目录选项――用于目录查找的选项
这些选项指定目录以便查找头文件,库文件和编译器部分。
-Bprefix-Idir-I--Ldir
-Idir增加目录dir到目录列表的头部以便查找头文件。
-I-你用在-I-选项之前的-I选项指定的任何目录仅仅被用于#include"file"的查找;它们
不用于#include
目录被用于所有#include指令的查找。通常,所有的-I选项被用在-I-选项之后。另外,-I-选
项禁止将当前目录作为用于#include"file"的第一个查找目录。
-Ldir增加目录dir到目录列表以便被用于-l的查找。
-Bprefix这个选项指定了在什么地方查找可执行文件,库文件,包含文件和编译器自己
的数据文件。
目标选项――指定目标机和编译器的版本
-bmachine-Vversion
-bmachine参数machine指定了用于编译的目标机。当你安装GNUCC作为一个交叉
编译程序时,这个参数是有效的
-Vversion参数version指定了运行的GNUCC的版本。
机器相关选项――硬件模式和配置
略
代码产生选项――用于代码产生约定的选项
-fcall-saved-reg-fcall-ud-reg
-ffixed-reg-finhibit-size-directive
-fno-common-fno-ident-fno-gnu-linker
-fpcc-struct-return-fpic-fPIC
-freg-struct-return-fshared-data-fshort-enums
-fshort-double-funaligned-pointers
-funaligned-struct-hack-fvolatile-fvolatile-global
-fverbo-asm-fpack-struct+e0+e1
fpcc-struct-return象更长的结构和联合值一样返回内存中而不是寄存器中的short结构
和联合的值。
-freg-struct-return使用这种约定在可能的时候,在寄存器中返回结构和联合的值。
-fshort-enums分配给一个枚举类型它所需要的字节数。
-fshort-double设置double和float使用同样的大小。
-fshared-data要求数据和这次编译的非常量变量是共享数据而不是私有数据。
-fno-common将没有初始化的全局变量分配在目标文件的bss段内,而不是将它们
生成为公用块。使用这个选项的唯一理由是为了保证这个程序能够总是以这种方式在其它系
统上工作。
-fno-ident忽略#ident指令。
-fno-gnu-linker不将全局初始化输出到GNU连接器使用的表单中。当你想要使用一
个non-GNU连接器。
-finhibit-size-directive不输出一条.size的汇编指令。
-fverbo-asm将调试信息放入产生的汇编代码中以便阅读。
-fvolatile将所有的通过指针进行的内存引用当作volatile的。
-fvolatile-global将所有的内存当作extern的,将所有的全局数据项当作volatile的。
-fpic如果目标机支持,产生适合在共享库中使用的位置无关代码。
-fPIC产生位置无关代码。位置无关代码要求特殊的支持,因此,仅仅在某些系统上
起作用。
-ffixed-reg将命名为reg的寄存器当作一个固定的寄存器;生成的代码决不能引用它。
-fcall-ud-reg将命名为reg的寄存器当作一个由函数调用频繁访问的可分配的寄存
器。
-fcall-saved-reg将命名为reg的寄存器当作一个由函数保存的可分配的寄存器。
-fpack-struct将所有的结构成员无缝挤压在一起。通常最好不要使用这个选项。
+e0
+e1
控制在类中的虚函数定义是否被用于产生代码,或仅仅用于为它们的调用程序定义借
口。仅仅C++使用。
-funaligned-pointers假定所有指针包含不对齐的地址。
-funaligned-struct-hack总是用公开大小的装载和存储访问结构域。强烈建议不要使用这
个选项。
影响GNUCC的环境变量
这些环境变量通过指定目录或前缀生效,当查找各种类型的文件时使用。
TMPDIRGCC_EXEC_PREFIX
COMPILER_PATH
LIBRARY_PATH
C_INCLUDE_PATHCPLUS_INCLUDE_PATHOBJC_INCLUDE_PATH
DEPENDENCIES_OUTPUT
TMPDIR如果设置了这个变量,它指定用于临时文件的目录。
GCC_EXEC_PREFIX如果设置了这个变量,它指定一个前缀用在由编译器运行的子文
件名中。
COMPILER_PATH这个变量的值是一个以冒号分割开的目录列表。如果在
GCC_EXEC_PREFIX指定的目录中没有找到,再用COMPILER_PATH指定的目录查找。
LIBRARY_PATH这个变量的值是一个以冒号分割开的目录列表。
C_INCLUDE_PATH
CPLUS_INCLUDE_PATH
OBJC_INCLUDE_PATH
这些环境变量适合于专门的语言。每个变量的值是一个以冒号分割开的目录列表。
DEPENDENCIES_OUTPUT如果设置了这个变量,那么它的值指定了怎样输出用于
Make的依赖关系,这些依赖关系是基于编译器处理的头文件的。
三、GNU连接器ld
ld汇总
ld[-
[-Aarchitecture][-binput-format]
[-Bstatic][-Bdynamic][-Bsymbolic]
[-cMRI-commandfile][-d|-dc|-dp]
[-defsymsymbol=expression]
[-dynamic-linkerfile][-embedded-relocs][-export-dynamic]
[-eentry][-F][-Fformat]
[-formatinput-format][-g][-Gsize]
[-help][-i][-larchive][-Larchdir]
[-M][-Mapmapfile][-memulation]
[-N|-n][-noinhibit-exec][-no-keep-memory]
[-oformatoutput-format][-Rfilename]
[-relax][-retain-symbols-filefilename]
[-r|-Ur][-rpathdir][-rpath-linkdir]
[-S][-s][-sonamename][-shared]
[-sort-common][-stats][-Tcommandfile]
[-房思琪的初恋乐园全文免费阅读 Ttextorg][-Tdataorg]
[-Tbssorg][-t][-traditional-format]
[-usymbol][-V][-v][-verbo][-version]
[-warn-common][-warn-constructors][-warn-once]
[-ysymbol][-X][-x]
[-([archives]-)]
[--start-group[archives]--end-group]
[-split-by-reloccount][-split-by-file]
[--whole-archive]
这些选项是过剩的,在实际应用中很少被使用。比如,以下是ld在一种支持Unix系统的标
准上连接标准的Unix目标文件hello.o的一个常见的用法:
ld-ooutput/lib/.o-lc
这告诉ld产生一个称为output的文件作为将文件/lib/crt0.o与hello.o和库libc.a连接在一起
的结果,其中libc.a取自标准搜寻目录。请看以下关于‘-l’选项的讨论。
Ld的命令行选项与顺序无关。objfile…表示的目标文件列表可以放在命令行选项的前面,后
面或也可以与命令行选项混合在一起放,但必须保证objfile参数不放在命令行选项和它的
参数之间。
通常,连接器至少与一个目标文件一起被调用,但你可以用‘-l’,‘-R’指定其他形式的二
进制文件和脚本命令语言。如果根本没有任何二进制输入文件被指定,则连接器不产生任何
输出,并产生‘没有输入文件’的消息。
如果连接器不能辨别一个目标文件的格式,它将假定它是一个连接器脚本。这样指定的脚本
增加用于连接的主连接器脚本。这种特性允许连接器来连接一个似乎是一个目标或存档的文
件,但实际上仅仅定义了一些符号值,或使用INPUT或GROUP来加载其他目标文件。
对于名字为单个字母的选项,选项参数必须要么跟着选项字母,没有插入空格,要么紧跟着
需要它们的选项作为独立的参数被给出。
对于名字为多个字母的选项,要么一个短划线或两个短划线可以放在选项名之前;比如
‘--oformat’等价于‘-oformat’。多字母选项的参数必须要么被一个等号与选项名隔离开,
要么紧跟着需要它们的选项作为独立的参数被给出。比如‘--oformatsrec’等价于
‘--oformat=srec’。多字母选项名的唯一缩写被接受。
体系结构:-Aarchitecture
Inthecurrentreleaofld,
thatldconfiguration,thearchitectureargumentidentifiestheparticulararchitectureinthe960
family,tionld
andtheIntel960family,releasofldmaysupportsimilarfunctionalityfor
otherarchitecturefamilies.
输入格式:-binput-format
ldisconfiguredthisway,
youcanuthe`-b'optiontospecifythebinaryformatforinputobjectfilesthatfollowthisoption
enldisconfiguredtosupportalternativeobjectformats,youdon't
usuallyneedtospecifythis,asldshouldbeconfiguredtoexpectasadefaultinputformatthemost
-formatisatextstring,thenameofaparticularformat
supportedbytheBFDlibraries.(Youcanlisttheavailablebinaryformatswith`objdump-i'.)
`-formatinput-format'hasthesameeffect,tionBFD.
Youmayw
alsou`-b'toswitchformatxplicitly(whenlinkingobjectfilesofdifferentformats),by
including`-binput-format'ault
tionEnvironmentVariables.
Youcanalsodefinetheinputformatfromascript,usingthecommandTARGET;ection
OptionCommands.
-Bstatic
onlymeaningfulonplatformsforwhichshared
librariesaresupported.
-Bdynamic
onlymeaningfulonplatformsforwhichsharedlibrariesare
tionisnormallythedefaultonsuchplatforms.
-Bsymbolic
Whencreatingasharedlibrary,bindreferencestoglobalsymbolstothedefinitionwithinthe
sharedlibrary,ly,itispossibleforaprogramlinkedagainstasharedlibraryto
tionisonlymeaningfulonELFplatforms
whichsupportsharedlibraries.
-cMRI-commandfile
为了与MRI提出的连接器兼容,
ForcompatibilitywithlinkersproducedbyMRI,ldacceptsscriptfileswritteninanalternate,
restrictedcommandlanguage,uceMRI
scriptfileswiththeoption`-c';uthe`-T'optiontorunlinkerscriptswritteninthe
-cmdfiledoesnotexist,ldlooksforitinthe
directoriesspecifiedbyany`-L'options.
-d-dc-dp
Thethreeoptionsareequivalent;multipleformsaresupportedforcompatibilitywithother
signspacetocommonsymbolvenifarelocatableoutputfileisspecified(with
`-r').ThescriptcommandFORCE_COMMON_tion
OptionCommands.
-defsymsymbol=expression
Createaglobalsymbolintheoutputfile,
mayuthisoptionasmanytimesasnecessarytodefinemultiplesymbolsinthecommandline.A
limitedformofarithmeticissupportedfortheexpressioninthiscontext:youmaygivea
hexadecimalconstantorthenameofanexistingsymbol,oru+and-toaddorsubtract
eedmoreelaborateexpressions,considerusingthe
linkercommandlanguagefromascript(ectionAssignment:DefiningSymbols).Note:there
shouldbenowhitespacebetweensymbol,theequalssign("="),andexpression.
-dynamic-linkerfile
onlymeaningfulwhengeneratingdynamicallylinked
aultdynamiclinkerisnormallycorrect;don'tuthisunlessyouknow
whatyouaredoing.
-embedded-relocs
ThisoptionisonlymeaningfulwhenlinkingMIPSembeddedPICcode,generatedbythe
-esthelinkertocreateatable
whichmaybeudatruntimetorelocateanydatawhichwasstaticallyinitializedtopointer
codeintestsuite/ld-empicfordetails.
入口点:-eentry
使用entry作为开始执行你的程序的清晰的标记,而不是缺省的入口点。关于指定入口点的
缺省的和其他的方法讨论,请看章节:入口点。
-export-dynamic
WhencreatinganELFfile,ly,thedynamic
tionisneededfor
someusofdlopen.
-F-Fformat
derlinkersudthisoptionthroughoutacompilationtoolchainforspecifying
hanismsldusforthispurpo
(the`-b'or`-format'optionsforinputfiles,`-oformat'optionortheTARGETcommandinlinker
scriptsforoutputfiles,theGNUTARGETenvironmentvariable)aremoreflexible,butldaccepts
the`-F'optionforcompatibilitywithscriptswrittentocalltheoldlinker.
-formatinput-format
Synonymfor`-binput-format'.
-g
edforcompatibilitywithothertools.
-Gvalue-Gvalue
SetthemaximumsizeofobjectstobeoptimizedusingtheGPregistertosizeunderMIPSECOFF.
Ignoredforotherobjectfileformats.
帮助:-help
将命令行选项汇总打印到标准输出并退出。
-i
Performanincrementallink(sameasoption`-r').
增加存档文件到连接文件列表:-lar
增加存档文件到连接文件列表。这个选项可以被使用任意次。ld将为每个指定的存档文件搜
索它的路径列表,查找libar.a的出现。
增加查找路径:-Larchdir-Larchdir
增加查找路径到ld查找存档库和ld控制脚本的路径列表中。你可以使用这个选项任意次。
路径按它们在命令行上被指定的顺序被查找。在命令行上指定的路径在缺省路径之前被查
找。所有的-L选项适用于所有的-l选项,不管它们的顺序。如果没有用‘-L’指定查找路径,
ld查找缺省路径。
打印连接映像:-M
打印连接映像--关于符号被ld映像在那里的诊断信息和关于全局公共存储区分配的信息。
打印连接映像到文件mapfile:-Mapmapfile
打印连接映像到文件mapfile,连接映像指关于符号被ld映像在那里的诊断信息和关于全局
公共存储区分配的信息。
-memulation-memulation
listtheavailableemulationswiththe`--verbo'or`-V'
aultdependsonhowyourldwasconfigured.
设置正文段和数据段为可读写的:-N
设置正文段和数据段为可读的和可写的。
设置正文段为只读的:-n
设置正文段为只读的,并且如果可能,标记输出为NMAGIC。
-noinhibit-exec
ly,thelinkerwillnotproduce
anoutputfileifitencounterrrorsduringthelinkprocess;itexitswithoutwritinganoutputfile
whenitissuesanyerrorwhatsoever.
-no-keep-memory
ldnormallyoptimizesforspeedovermemoryusagebycachingthesymboltablesofinputfilesin
tiontellsldtoinsteadoptimizeformemoryusage,byrereadingthesymboltables
yberequiredifldrunsoutofmemoryspacewhilelinkingalarge
executable.
指定输出文件名:-ooutput
使用output作为被ld产生的程序名;如果这个选项没有被指定,那么名字‘’缺省地
被使用。脚本命令OUTPUT也指定输出文件名。
-oformatoutput-format
ldisconfiguredthisway,
youcanuthe`-oformat'
whenldisconfiguredtosupportalternativeobjectformats,youdon'tusuallyneedtospecifythis,
asldshouldbeconfiguredtoproduceasadefaultoutputformatthemostusualformatoneach
-formatisatextstring,thenameofaparticularformatsupportedbytheBFD
libraries.(Youcanlisttheavailablebinaryformatswith`objdump-i'.)Thescriptcommand
OUTPUT_FORMATcanalsospecifytheoutputformat,tion
BFD.
-Rfilename
Readsymbolnamesandtheiraddressfromfilename,butdonotrelocateitorincludeitinthe
lowsyouroutputfiletorefersymbolicallytoabsolutelocationsofmemorydefined
inotherprograms.
-relax
tlythisoptionisonlysupportedontheH8/300
platforms,the`-relax'option
performsglobaloptimizationsthatbecomepossiblewhenthelinkerresolvesaddressinginthe
program,suchasrelaxingaddressmodesandsynthesizingnewinstructionsintheoutputobject
formswherethisisnotsupported,`-relax'isaccepted,butignored.
-retain-symbols-filefilename
Retainonlythesymbolslistedinthefilefilename,meissimplyaflat
file,tionispeciallyufulinenvironments(suchas
VxWorks)wherealargeglobalsymboltableisaccumulatedgradually,toconrverun-time
memory.`-retain-symbols-file'doesnotdiscardundefinedsymbols,orsymbolsneededfor
onlyspecify`-retain-symbols-file'rides`-s'
and`-S'.
-rpathdir
udwhenlinkinganELFexecutable
-rpathargumentsareconcatenatedandpasdtotheruntimelinker,which
-rpathoptionisalsoudwhenlocatingshared
objectswhichareneededbysharedobjectxplicitlyincludedinthelink;ethedescriptionof
-rpathisnotudwhenlinkinganELFexecutable,thecontentsofthe
environmentvariableLD_RUN_-rpathoptionmayalsobe
ult,onSunOS,thelinkerwillformaruntimearchpatchoutofallthe-L
-rpathoptionisud,theruntimearchpathwillbeformedexclusively
usingthe-rpathoptions,nbeufulwhenusinggcc,whichadds
many-LoptionswhichmaybeonNFSmountedfilesystems.
-rpath-linkDIR
WhenusingELForSunOS,ppenswhenanld
-elinkerencounterssucha
dependencywhendoinganon-shared,non-relocateablelink,itwillautomaticallytrytolocatethe
requiredsharedlibraryandincludeitinthelink,aca,the
--rpath-linkoptionmayspecify
aquenceofdirectorynameitherbyspecifyingalistofnamesparatedbycolons,orby
kerusthefollowingarchpathstolocaterequiredshared
libraries.
Anydirectoriesspecifiedby-rpath-linkoptions.
ferencebetween-rpathand-rpath-linkisthat
directoriesspecifiedby-rpathoptionsareincludedintheexecutableandudatruntime,whereas
the-rpath-linkoptionisonlyeffectiveatlinktime.
OnanELFsystem,ifthe-rpathandrpath-linkoptionswerenotud,archthecontentsofthe
environmentvariableLD_RUN_PATH.
OnSunOS,ifthe-rpathoptionwasnotud,archanydirectoriesspecifiedusing-Loptions.
Foranativelinker,thecontentsoftheenvironmentvariableLD_LIBRARY_PATH.
Thedefaultdirectories,normally`/lib'and`/usr/lib'.
Iftherequiredsharedlibraryisnotfound,thelinkerwillissueawarningandcontinuewiththe
link.
产生可重定位的输出:-r
产生可重定位的输出--比如,产生一个输出文件,它反过来又可以作为输入传给ld。这通常
被称为部分连接(partiallinking)。如果这个选项不被指定,一个绝对文件被产生。当连接
C++程序时,这个选项不能解决构造器的引用问题;为了解决它,使用‘-Ur’。该选项与‘-i’
完成同样的事情。
-S
Omitdebuggersymbolinformation(butnotallsymbols)fromtheoutputfile.
-s
Omitallsymbolinformationfromtheoutputfile.
-sonamename
WhencreatinganELFsharedobject,ttheinternalDT_SONAMEfieldtothespecifiedname.
WhenanexecutableislinkedwithasharedobjectwhichhasaDT_SONAMEfield,thenwhenthe
executableisrunthedynamiclinkerwillattempttoloadthesharedobjectspecifiedbythe
DT_SONAMEfieldratherthantheusingthefilenamegiventothelinker.
-shared
S,
thelinkerwillautomaticallycreateasharedlibraryifthe-eoptionisnotudandthereare
undefinedsymbolsinthelink.
-sort-common
Normally,whenldplacestheglobalcommonsymbolsintheappropriateoutputctions,itsorts
omealltheonebytesymbols,thenallthetwobytes,thenallthefourbytes,
topreventgapsbetweensymbolsduetoalignmentconstraints.
Thisoptiondisablesthatsorting.
-split-by-reloccount
Trystocreatextractionsintheoutputfilesothatnosingleoutputctioninthefilecontains
ufulwhengeneratinghugerelocatablefordownloadinginto
certainrealtimekernelswiththeCOFFobjectfileformat;sinceCOFFcannotreprentmorethan
atthiswillfailtoworkwithobjectfileformatswhich
kerwillnotsplitupindividualinputctionsfor
redistribution,soifasingleinputctioncontainsmorethancountrelocationsoneoutputction
willcontainthatmanyrelocations.
-split-by-file
Similarto-split-by-relocbutcreatesanewoutputctionforeachinputfile.
-stats
Computeanddisplaystatisticsabouttheoperationofthelinker,suchaxecutiontimeand
memoryusage.
指定起始地址:-Tbssorg-Tdataorg-Ttextorg
使用org作为分别用于输出文件的bss,data或text段的起始地址。Org必须是一个单一的十
六进制整数,为了与其他连接器兼容,你可能省略通常与十六进制值连用的前置的‘0x’。
-Tcommandfile-Tcommandfile
ommandsreplaceld'sdefaultlinkscript
(ratherthanaddingtoit),socommandfilemustspecifyeverythingnecessarytodescribethetarget
andfiledoesnotexist,ldlooksforitinthe
directoriesspecifiedbyanypreceding`-L'le`-T'optionsaccumulate.
-t
Printthenamesoftheinputfilesasldprocessthem.
-traditional-format
Forsometargets,theoutputofldisdifferentinsomewaysfromtheoutputofsomeexistinglinker.
mple,onSunOS,ldcombines
nreducethesizeofanoutputfilewithfull
unately,theSunOSdbxprogramcannotread
theresultingprogram(gdbhasnotrouble).The`-traditional-format'switchtellsldtonotcombine
duplicateentries.
-usymbol
hismay,forexample,
triggerlinkingofadditionalmodulesfromstandardlibraries.`-u'mayberepeatedwithdifferent
optionargumentstoenteradditionalundefinedsymbols.
-Ur
ForanythingotherthanC++programs,thisoptioniquivalentto`-r':itgeneratesrelocatable
doesresolvereferencestoconstructors,unlike`-r'.Itdoesnotworktou`-Ur'onfilesthatwere
themlv秋日校园 eslinkedwith`-Ur';oncetheconstructortablehasbeenbuilt,
`-Ur'onlyforthelastpartiallink,and`-r'fortheothers.
--ve八一勋章获得者 rbo
ywhichinput
filescanandcannotbeopened.
-v-V
-Voptionalsoliststhesupportedemulations.
-version
Displaytheversionnumberforldandexit.
-warn-common
Warnwhenacommonsymboliscombinedwithanothercommonsymbolorwithasymbol
nkersallowthissomewhatsloppypractice,butlinkersonsomeotheroperating
tionallowsyoutofindpotentialproblemsfromcombiningglobalsymbols.
Unfortunately,someClibrariesuthispractice,soyoumaygetsomewarningsaboutsymbolsin
rethreekindsofglobalsymbols,illustratedhere
byCexamples:
`inti=1;'
Adefinition,whichgoesintheinitializeddatactionoftheoutputfile.
`externinti;'
Anundefinedreference,ustbeeitheradefinitionora
commonsymbolforthevariablesomewhere.
`inti;'
eareonly(oneormore)commonsymbolsforavariable,itgoesinthe
kermergesmultiplecommonsymbolsforthe
areofdifferentsizes,
linkerturnsacommonsymbolintoadeclaration,ifthereisadefinitionofthesamevariable.
The`-warn-common'rningconsistsofapair
oflines:thefirstdescribesthesymboljustencountered,andtheconddescribestheprevious
othofthetwosymbolswillbeacommon
symbol.
Turningacommonsymbolintoareference,becauthereisalreadyadefinitionforthesymbol.
file(ction):warning:commonof`symbol'
overriddenbydefinition
file(ction):warning:definedhere
Turningacommonsymbolintoareference,becaualaterdefinitionforthesymbolis
thesameasthepreviousca,exceptthatthesymbolsareencounteredina
differentorder.
file(ction):warning:definitionof`symbol'
overridingcommon
file(ction):warning:commonishere
Mergingacommonsymbolwithaprevioussame-sizedcommonsymbol.
file(ction):warning:multiplecommon
of`symbol'
file(ction):warning:previouscommonishere
Mergingacommonsymbolwithapreviouslargercommonsymbol.
file(ction):warning:commonof`symbol'
overriddenbylargercommon
file(ction):warning:largercommonishere
thesameasthe
previousca,exceptthatthesymbolsareencounteredinadifferentorder.
file(ction):warning:commonof`symbol'
overridingsmallercommon
file(ction):warning:smallercommonishere
-warn-constructors
formatslikeCOFForELF,thelinkercannotdetecttheuofglobalconstructors.
-warn-once
Onlywarnonceforeachundefinedsymbol,
eacharchivementionedonthecommandline,includeeveryobjectfileinthearchiveinthelink,
normallyudtoturnan
archivefileintoasharedlibrary,forcingeveryobjecttobeincludedintheresultingsharedlibrary.
删除所有临时局部符号:-X
删除所有临时局部符号。对于大多数target,这是所有名字以‘-L’开始的局部符号。
删除所有局部符号:-x
删除所有局部符号。
-ysymbol
tionmaybegivenanynumber
tionisufulwhen
youhaveanundefinedsymbolinyourlinkbutdon'tknowwherethereferenceiscomingfrom.
-(archives-)--start-grouparchives--end-group
ybeeitherexplicitfilenames,or`-l'options.
Thespecifiedarchivesarearchedrepeatedlyuntilnonewundefinedreferencesarecreated.
Normally,anarchi
asymbolinthatarchiveisneededtoresolveanundefinedsymbolreferredtobyanobjectinan
archivethatappearslateronthecommandline,thelinkerwouldnotbeabletoresolvethat
pingthearchives,theyallbearchedrepeatedlyuntilallpossiblereferences
sttouitonlywhen
thereareunavoidablecircularreferencesbetweentwoormorearchives.
四、GNUBinaryUtilities问题
.odjump的使用
objdump有点象那个快速查看之流的工具,就是以一种可阅读的格式让你更多地了解二进制
文件可能带有的附加信息。对于一般只想让自己程序跑起来的程序员,这个命令没有更多意
义,对于想进一步了解系统的程序员,应该掌握这种工具,
objdump-显示二进制文件信息
它的命令格式为:
[-a][-bbfdname|
--target=bfdname][-C][--debugging]
[-d][-D]
[--disasmble-zeroes]
[-EB|-EL|--endian={big|little}][-f]
[-h][-i|--info]
[-jction|--ction=ction]
[-l][-mmachine][--prefix-address]
[-r][-R]
[-s|--full-contents][-S|--source]
[--[no-]show-raw-insn][--stabs][-t]
[-T][-x]
[--start-address=address][--stop-address=address]
[--adjust-vma=offt][--version][--help]
--archive-headers
-a显示档案库的成员信息,与artv类似
objdump-alibpcap.a
和ar-tvlibpcap.a显示结果比较比较
显然这个选项没有什么意思。
--adjust-vma=offt
Whendumpinginformation,ufulifthec-
tionaddressdonotcorrespondtothesymboltable,whichcanhappenwhenputtingctionsat
particularaddresswhenusingaformatwhichcannotreprentctionaddress,.
-bbfdname
--target=bfdname
指定目标码格式。这不是必须的,objdump能自动识别许多格式,
比如:objdump-boasys-mvax-hfu.o显示fu.o的头部摘要信息,明确指出该文件是Vax系
统下用Oasys编译器生成的目标文件。objdump-i将给出这里可以指定的目标码格式列表
--demangle
-C将底层的符号名解码成用户级名字,除了去掉所有开头的下划线之外,还使得C++函数
名以可理解的方式显示出来。
--debugging
显示调试信息。企图解析保存在文件中的调试信息并以C语言的语法显示出来。仅仅支持
某些类型的调试信息。
--disasmble
-d反汇编那些应该还有指令机器码的ction
--disasmble-all
-D与-d类似,但反汇编所有ction
--prefix-address
反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式。
显示效果并不理想,但可能会用到其中的某些显示,自己可以对比。
--disasmble-zeroes
一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。
-EB
-EL
--endian={big|little}
这个选项将影响反汇编出来的指令。
little-endian就是我们当年在dos下玩汇编的时候常说的高位在高地址,x86都是这种。
--file-headers
-f显示objfile中每个文件的整体头部摘要信息。
--ction-headers
--headers
-h显示目标文件各个ction的头部摘要信息。
--help简短的帮助信息。
--info
-i显示对于-b或者-m选项可用的架构和目标格式列表。
--ction=name
-jname仅仅显示指定ction的信息
--line-numbers
-l用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用,使用-ld和使用-d
的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。
--architecture=machine
-mmachine
指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述架构信息的时候(比如
S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构。
--reloc
-r显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示
出来。
--dynamic-reloc
-R显示文件的动态重定位入口,仅仅对于动态目标文件有意义,比如某些共享库。
--full-contents
-s显示指定ction的完整内容。
objdump--ction=.
--source
-S尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。
隐含了-d参数。
--show-raw-insn
反汇编的时候,显示每条汇编指令对应的机器码,除非指定了
--prefix-address,这将是缺省选项。
--no-show-raw-insn
反汇编时,不显示汇编指令的机器码,这是指定--prefix-address选项时的缺省设置。
--stabs
,.,only
ufulonsystems(suchasSolaris2.0)buggingsymbol-tableentriesarecarriedin
otherfileformats,debug-gingsymbol-tableentriesareinterleavedwith
linkagesymbols,andarevisibleinthe--symsoutput.
--start-address=address
从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。
--stop-address=address
显示数据直到指定地址为止,该选项影响-d、-r和-s选项的输出。
--syms
-t显示文件的符号表入口。类似于nm-s提供的信息
--dynamic-syms
-T显示文件的动态符号表入口,仅仅对动态目标文件有意义,比如某些共享库。它显示的
信息类似于nm-D|--dynamic显示的信息。
--version版本信息
objdump–version
--all-headers
-x显示所有可用的头信息,包括符号表、重定位入口。-x等价于-a-f-h-r-t同时指定。
nm[`-a'|`--debug-syms'][`-g'|`--extern-only']
[`-B'][`-C'|`--demangle'[=style]][`-D'|`--dynamic']
[`-s'|`--print-armap'][`-A'|`-o'|`--print-file-name']
[`-n'|`-v'|`--numeric-sort'][`-p'|`--no-sort']
[`-r'|`--rever-sort'][`--size-sort'][`-u'|`--undefined-only']
[`-t'radix|`--radix='radix][`-P'|`--portability']
[`--target='bfdname][`-f'format|`--format='format]
[`--defined-only'][`-l'|`--line-numbers'][`--no-demangle']
[`-V'|`--version'][`-X32_64'][`--help'][]
arelistedasarguments,nmassumesthefile`'.
Foreachsymbol,nmshows:
Thesymbolvalue,intheradixlectedbyoptions(ebelow),orhexadecimalby
default.
tthefollowingtypesareud;othersare,aswell,dependingon
rca,thesymbolislocal;ifupperca,thesymbolisglobal
(external).
A
Thesymbol'svalueisabsolute,andwillnotbechangedbyfurtherlinking.
B
Thesymbolisintheuninitializeddataction(knownasBSS).
C
nking,multiple
ymbolisdefinedanywhere,the
edetailsoncommon
symbols,ethediscussionof--warn-commoninction`Linkeroptions'inTheGNU
linker.
D
Thesymbolisintheinitializeddataction.
G
jectfileformats
permitmoreefficientaccesstosmalldataobjects,suchasaglobalintvariableasoppod
toalargeglobalarray.
I
aGNUextensiontothe
ectfileformatwhichisrarelyud.
N
Thesymbolisadebuggingsymbol.
R
Thesymbolisinareadonlydataction.
S
Thesymbolisinanuninitializeddatactionforsmallobjects.
T
Thesymbolisinthetext(code)ction.
U
Thesymbolisundefined.
V
eakdefinedsymbolislinkedwithanormal
definedsymbol,eakundefined
symbolislinkedandthesymbolisnotdefined,thevalueoftheweaksymbolbecomes
zerowithnoerror.
W
Thesymbolisaweaksymbolthathasnotbeenspecificallytaggedasaweakobject
eakdefinedsymbolislinkedwithanormaldefinedsymbol,thenormal
eakundefinedsymbolislinkedandthe
symbolisnotdefined,thevalueoftheweaksymbolbecomeszerowithnoerror.
-
ca,thenextvaluesprinted
arethestabsotherfield,thestabsdescfield,ymbolsareudto
einformation,ection`StabsOverview'inThe
"stabs"debugformat.
?
Thesymboltypeisunknown,orobjectfileformatspecific.
Thesymbolname.
Thelongandshortformsofoptions,shownhereasalternatives,are
equivalent.
-A
-o
--print-file-name
Precedeeachsymbolbythenameoftheinputfile(orarchivemember)inwhichitwas
found,ratherthanidentifyingtheinputfileonceonly,beforeallofitssymbols.
-a
--debug-syms
Displayallsymbols,evendebugger-onlysymbols;normallythearenotlisted.
-B
Thesameas`--format=bsd'(forcompatibilitywiththeMIPSnm).
-C
--demangle[=style]
Decode(demangle)sremovingany
initialunderscoreprependedbythesystem,thismakesC++functionnamesreadable.
ionaldemanglingstyle
argum
ction9.c++filt,formoreinformationondemangling.
--no-demangle
thedefault.
-D
--dynamic
onlymeaningfulfor
dynamicobjects,suchascertaintypesofsharedlibraries.
-fformat
--format=format
Utheoutputformatformat,whichcanbebsd,sysv,
thefirstcharacterofformatissignificant;itcanbeeitherupperorlowerca.
-g
--extern-only
Displayonlyexternalsymbols.
-l
--line-numbers
Foreachsymbol,udebugginginformationtotrytofindafilenameandlinenumber.
Foradefinedsymbol,
undefinedsymbol,lookforthelinenumberofarelocationentrywhichreferstothe
numberinformationcanbefound,printitaftertheothersymbol
information.
-n
-v
--numeric-sort
Sortsymbolsnumericallybytheiraddress,ratherthanalphabeticallybytheirnames.
-p
--no-sort
Donotbothertosortthesymbolsinanyorder;printthemintheorderencountered.
-P
--portabil大馄饨的包法 ity
lentto`-f
posix'.
-s
--print-armap
Whenlistingsymbolsfromarchivemembers,includetheindex:amapping(storedinthe
archivebyarorranlib)ofwhichmodulescontaindefinitionsforwhichnames.
-r
--rever-sort
Revertheorderofthesort(whethernumericoralphabetic);letthelastcomefirst.
--size-sort
eiscomputedasthedifferencebetweenthevalueofthe
eofthesymbolis
printed,ratherthanthevalue.
-tradix
--radix=radix
be`d'fordecimal,`o'for
octal,or`x'forhexadecimal.
--target=bfdname
Specifyanobjectcodeformatotherthanyoursystem'tion15.1
TargetSelection,formoreinformation.
-u
--undefined-only
Displayonlyundefinedsymbols(thoexternaltoeachobjectfile).
--defined-only
Displayonlydefinedsymbolsforeachobjectfile.
-V
--version
Showtheversionnumberofnmandexit.
-X
soneparameter
whichmustbethestring`32_64'.ThedefaultmodeofAIXnmcorrespondsto`-X32',
whichisnotsupportedbyGNUnm.
--help
Showasummaryoftheoptionstonmandexit.
y
[-Fbfdname|--target=bfdname]
[-Ibfdname|--input-target=bfdname]
[-Obfdname|--output-target=bfdname]
[-S|--strip-all][-g|--strip-debug]
[-Ksymbolname|--keep-symbol=symbolname]
[-Nsymbolname|--strip-symbol=symbolname]
[-x|--discard-all][-X|--discard-locals]
[-bbyte|--byte=byte]
[-iinterleave|--interleave=interleave]
[-Rctionname|--remove-ction=ctionname]
[--debugging]
[--gap-fill=val][--pad-to=address]
[--t-start=val][--adjust-start=incr]
[--adjust-vma=incr]
[--adjust-ction-vma=ction{=,+,-}val]
[--adjust-warnings][--no-adjust-warnings]
[--t-ction-flags=ction=flags]
[--add-ction=ctionname=filename]
[--remove-leading-char]
[-v|--verbo][-V|--version][--help]
infile[outfile]
infile
outfile
Thesourceandoutputfiles,onotspecifyoutfile,objcopycreatesa
temporaryfileanddestructivelyrenamestheresultwiththenameofinfile.
-Ibfdname
--input-target=bfdname
Considerthesourcefile'sobjectformattobebfdname,ratherthanattemptingtodeduceit.
-Obfdname
--output-target=bfdname
Writetheoutputfileusingtheobjectformatbfdname.
-Fbfdname
--target=bfdname
,simply
transferdatafromsourcetodestinationwithnotranslation.
-Rctionname
--remove-ction=ctionname
tionmaybegiven
atusingthisoptioninappropriatelymaymaketheoutputfile
unusable.
-S
--strip-all
Donotcopyrelocationandsymbolinformationfromthesourcefile.
-g
--strip-debug
Donotcopydebuggingsymbolsfromthesourcefile.
--strip-unneeded
Stripallsymbolsthatarenotneededforrelocationprocessing.
-Ksymbolname
--keep-symbol=symbolname
tionmaybegivenmorethan
once.
-Nsymbolname
--strip-symbol=symbolname
tionmaybegivenmore
thanonce,andmaybecombinedwithstripoptionsotherthan-K.
-x
--discard-all
Donotcopynon-globalsymbolsfromthesourcefile.
-X
--discard-locals
Donotcopycompiler-generatedlocalsymbols.(Theusuallystartwith`L'or`.'.)
-bbyte
--byte=byte
Keeponlyeverybytethbyteoftheinputfile(headerdataisnotaffected).bytecanbein
therangefrom0tointerleave-1,whereinterleaveisgivenbythe`-i'or
`--interleave'option,tionisufulforcreatingfilesto
picallyudwithansrecoutputtarget.
-iinterleave
--interleave=interleave
whichbytetocopywiththe-bor
`--byte'yignoresthisoptionifyoudonotspecifyeither
`-b'or`--byte'.
--debugging
Convertdebugginginformation,notthedefaultbecauonlycertain
debuggingformatsaresupported,andtheconversionprocesscanbetimeconsuming.
--gap-fillval
donebyincreasingthesizeofthectionwith
theloweraddress,andfillingi四字反义词 ntheextraspacecreatedwithval.
--pad-toaddress
donebyincreasingthesizeof
raspaceisfilledinwiththevaluespecifiedby`--gap-fill'
(defaultzero).
--t-startval
objectfileformatssupportttingthestart
address.
--adjust-startincr
objectfileformatssupportttingthestart
address.
--adjust-vmaincr
Adjusttheaddressofallctions,aswellasthestartaddress,ject
atthisdoes
notrelocatethections;iftheprogramexpectsctionstobeloadedatacertainaddress,
andthisoptionisudtochangethectionssuchthattheyareloadedatadifferent
address,theprogrammayfail.
--adjust-ction-vmaction{=,+,-}val
`='isud,thectionaddressistto
i,comments
under`--adjust-vma',iondoesnotexistintheinputfile,awarningwill
beissued,unless`--no-adjust-warnings'isud.
--adjust-warnings
If`--adjust-ction-vma'isud,andthenamedctiondoesnotexist,issuea
thedefault.
--no-adjust-warnings
Donotissueawarningif`--adjust-ction-vma'isud,evenifthenamedction
doesnotexist.
--t-ction-flagsction=flags
gsargumentisacommaparatedstringof
ognizednamesare`alloc',`load',`readonly',`code',`data',
and`rom'.Notallflagsaremeaningfulforallobjectfileformats.
--add-ctionctionname=filename
tentsofthenew
eofthectionwillbethesizeofthefile.
Thisoptiononlyworksonfileformatswhichcansupportctionswitharbitrarynames.
--remove-leading-char
Ifthefirstcharacterofaglobalsymbolisaspecialsymbolleadingcharacterudbythe
objectfileformat,tcommonsymbolleadingcharacteris
canbeufulifyouwanttolinktogetherobjectsofdifferentfileformatswithdifferent
conventionsforsymbolnames.
-V
--version
Showtheversionnumberofobjcopy.
-v
--verbo
Verbooutput:aofarchives,`objcopy-V'lists
allmembersofthearchive.
--help
Showasummaryoftheoptionstoobjcopy.
本文发布于:2023-03-18 12:23:03,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/052eb1baaf8fbdc2d84bf9ac2557b103.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:目标文件.doc
本文 PDF 下载地址:目标文件.pdf
留言与评论(共有 0 条评论) |