将持续更新c++
一,gcc和g++编译命令基础objective-c
gcc/g++在执行编译工做的时候,总共须要4步shell
1.预处理,生成.i的文件[预处理器cpp]
2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs]
3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as]
4.链接目标代码,生成可执行程序[连接器ld]编程
[参数详解]
-x language filename
设定文件所使用的语言,使后缀名无效,对之后的多个有效.也就是根
据约定C语言的后缀名称是.c的,而C++的后缀名是.C或者.cpp,若是
你很个性,决定你的C代码文件的后缀名是.pig 哈哈,那你就要用这
个参数,这个参数对他后面的文件名都起做用,除非到了下一个参数
的使用。
可使用的参数吗有下面的这些
`c', `objective-c', `c-header', `c++', `cpp-output',
`assembler', and `assembler-with-cpp'.
看到英文,应该能够理解的。
例子用法:
gcc -x c hello.pig
-x none filename
关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型
例子用法:
gcc -x c hello.pig -x none hello2.c
-c
只激活预处理,编译,和汇编,也就是他只把程序作成obj文件
例子用法:
gcc -c hello.c
他将生成.o的obj文件 windows
-S
只激活预处理和编译,就是指把文件编译成为汇编代码。
例子用法
gcc -S hello.c
他将生成.s的汇编代码,你能够用文本编辑器察看编辑器
-E
只激活预处理,这个不生成文件,你须要把它重定向到一个输出文件里
面.
例子用法:
gcc -E hello.c > pianoapan.txt
gcc -E hello.c | more
慢慢看吧,一个hello word 也要与处理成800行的代码ide
-o
指定目标名称,缺省的时候,gcc 编译出来的文件是a.out,很难听,若是
你和我有同感,改掉它,哈哈
例子用法
gcc -o hello.exe hello.c (哦,windows用习惯了)
gcc -o hello.asm -S hello.c函数
-pipe
使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问
题
gcc -pipe -o hello.exe hello.c工具
-ansi
关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一
些asm inline typeof关键字,以及UNIX,vax等预处理宏,测试
-fno-asm
此选项实现ansi选项的功能的一部分,它禁止将asm,inline和typeof用做
关键字。
-fno-strict-prototype
只对g++起做用,使用这个选项,g++将对不带参数的函数,都认为是没有显式
的对参数的个数和类型说明,而不是没有参数.
而gcc不管是否使用这个参数,都将对没有带参数的函数,认为城没有显式说
明的类型
-fthis-is-varialble
就是向传统c++看齐,可使用this当通常变量使用.
-fcond-mismatch
容许条件表达式的第二和第三参数类型不匹配,表达式的值将为void类型
-funsigned-char
-fno-signed-char
-fsigned-char
-fno-unsigned-char
这四个参数是对char类型进行设置,决定将char类型设置成unsigned char(前
两个参数)或者 signed char(后两个参数)
-include file
包含某个代码,简单来讲,就是便以某个文件,须要另外一个文件的时候,就能够
用它设定,功能就至关于在代码中使用#include
例子用法:
gcc hello.c -include /root/pianopan.h
-imacros file
将file文件的宏,扩展到gcc/g++的输入文件,宏定义自己并不出如今输入文件
中
-Dmacro
至关于C语言中的#define macro
-Dmacro=defn
至关于C语言中的#define macro=defn
-Umacro
至关于C语言中的#undef macro
-undef
取消对任何非标准宏的定义
-Idir
在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头
文件,若是没有找到,他回到缺省的头文件目录找,若是使用-I制定了目录,他
回先在你所制定的目录查找,而后再按常规的顺序去找.
对于#include,gcc/g++会到-I制定的目录查找,查找不到,而后将到系
统的缺省的头文件目录查找
-I-
就是取消前一个参数的功能,因此通常在-Idir以后使用
-idirafter dir
在-I的目录里面查找失败,讲到这个目录里面查找.
-iprefix prefix
-iwithprefix dir
通常一块儿使用,当-I的目录查找失败,会到prefix+dir下查找
-nostdinc
使编译器再也不系统缺省的头文件目录里面找头文件,通常和-I联合使用,明确
限定头文件的位置
-nostdin C++
规定不在g++指定的标准路经中搜索,但仍在其余路径中搜索,.此选项在建立
libg++库使用
-C
在预处理的时候,不删除注释信息,通常和-E使用,有时候分析程序,用这个很
方便的
-M
生成文件关联的信息。包含目标文件所依赖的全部源代码
你能够用gcc -M hello.c来测试一下,很简单。
-MM
和上面的那个同样,可是它将忽略由#include形成的依赖关系。
-MD
和-M相同,可是输出将导入到.d的文件里面
-MMD
和-MM相同,可是输出将导入到.d的文件里面
-Wa,option
此选项传递option给汇编程序;若是option中间有逗号,就将option分红多个选
项,而后传递给会汇编程序
-Wl.option
此选项传递option给链接程序;若是option中间有逗号,就将option分红多个选
项,而后传递给会链接程序.
-llibrary
制定编译的时候使用的库
例子用法
gcc -lcurses hello.c
使用ncurses库编译程序
-Ldir
制定编译的时候,搜索库的路径。好比你本身的库,能够用它制定目录,否则
编译器将只在标准库的目录找。这个dir就是目录的名称。
-O0
-O1
-O2
-O3
编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最
高
-g
只是编译器,在编译的时候,产生条是信息。
-gstabs
此选项以stabs格式声称调试信息,可是不包括gdb调试信息.
-gstabs+
此选项以stabs格式声称调试信息,而且包含仅供gdb使用的额外调试信息.
-ggdb
此选项将尽量的生成gdb的可使用的调试信息.
-static
此选项将禁止使用动态库,因此,编译出来的东西,通常都很大,也不须要什么
动态链接库,就能够运行.
-share
此选项将尽可能使用动态库,因此生成文件比较小,可是须要系统由动态库.
-traditional
试图让编译器支持传统的C语言特性
二,静态库,共享库的编译与使用
1.静态库建立及使用
示例:
base.h->a.cpp , baes.h->b.cpp g++ -c a.cpp g++ -c b.cpp ar -r libsay.a a.o b.o # 编译静态库:将全部目标文件打包入库中 g++ main.cpp libsay.a -o run
2.共享库(动态库)建立及使用
示例:
1 g++ -shared -fpic avg.cpp -o avg.so (编译动态库) 2 3 g++ main.cpp avg.so -o run
三,makefile的编写
1.makefile的规则
target (目标文件或label) : prerequisites (生成target所须要的东西)
command (执行的命令)
解释:
最终要生成的目标(run.bin) :中间的目标文件(a1.o a2.o a3.o)
编译命令
2.makefile中经常使用函数表
(一)、字符串处理函数
1.$(subst FROM,TO,TEXT)
函数名称:字符串替换函数—subst。
函数功能:把字串“TEXT”中的“FROM”字符替换为“TO”。
返回值:替换后的新字符串。
2.$(patsubst PATTERN,REPLACEMENT,TEXT)
函数名称:模式替换函数—patsubst。
函数功能:搜索“TEXT”中以空格分开的单词,将否符合模式“TATTERN”替换为“REPLACEMENT”。参数“PATTERN”中可使用模
式通配符“%”来表明一个单词中的若干字符。若是参数“REPLACEMENT”中也包含一个“%”,那么“REPLACEMENT”中的“%”将是
“TATTERN”中的那个“%”所表明的字符串。在“TATTERN”和“REPLACEMENT”中,只有第一个“%”被做为模式字符来处理,后续的做为字符本上来处理。在两个参数中当使用第一个“%”本是字符自己时,可以使用反斜杠“\”对它进行转义处理。
返回值:替换后的新字符串。
函数说明:参数“TEXT”单词之间的多个空格在处理时被合并为一个空格,但前导和结尾空格忽略。
3.$(strip STRINT)
函数名称:去空格函数—strip。
函数功能:去掉字串(若干单词,使用若干空字符分割)“STRINT”开头和结尾的空字符,并将其中多个连续空字符合并为一个空字符。
返回值:无前导和结尾空字符、使用单一空格分割的多单词字符串。
函数说明:空字符包括空格、[Tab]等不可显示字符。
4.$(findstring FIND,IN)
函数名称:查找字符串函数—findstring。
函数功能:搜索字串“IN”,查找“FIND”字串。
返回值:若是在“IN”之中存在“FIND”,则返回“FIND”,不然返回空。
函数说明:字串“IN”之中能够包含空格、[Tab]。搜索须要是严格的文本匹配。
5.$(filter PATTERN…,TEXT)
函数名称:过滤函数—filter。
函数功能:过滤掉字串“TEXT”中全部不符合模式“PATTERN”的单词,保留全部符合此模式的单词。可使用多个模式。模式中通常须要包含模式字符“%”。存在多个模式时,模式表达式之间使用空格分割。
返回值:空格分割的“TEXT”字串中全部符合模式“PATTERN”的字串。
函数说明:“filter”函数能够用来去除一个变量中的某些字符串,咱们下边的例子中就是用到了此函数。
6.$(filter-out PATTERN...,TEXT)
函数名称:反过滤函数—filter-out。
函数功能:和“filter”函数实现的功能相反。过滤掉字串“TEXT”中全部符合模式“PATTERN”的单词,保留全部不符合此模式的单词。能够有多个模式。存在多个模式时,模式表达式之间使用空格分割。。
返回值:空格分割的“TEXT”字串中全部不符合模式“PATTERN”的字串。
函数说明:“filter-out”函数也能够用来去除一个变量中的某些字符串,(实现和“filter”函数相反)。
7.$(sort LIST)
函数名称:排序函数—sort。
函数功能:给字串“LIST”中的单词以首字母为准进行排序(升序),并取掉重复的单词。
返回值:空格分割的没有重复单词的字串。
函数说明:两个功能,排序和去字串中的重复单词。能够单独使用其中一个功能。
8.$(word N,TEXT)
函数名称:取单词函数—word。
函数功能:取字串“TEXT”中第“N”个单词(“N”的值从1开始)。
返回值:返回字串“TEXT”中第“N”个单词。
函数说明:若是“N”值大于字串“TEXT”中单词的数目,返回空字符串。若是“N”为0,出错!
9.$(wordlist S,E,TEXT)
函数名称:取字串函数—wordlist。
函数功能:从字串“TEXT”中取出从“S”开始到“E”的单词串。“S”和“E”表示单词在字串中位置的数字。
返回值:字串“TEXT”中从第“S”到“E”(包括“E”)的单词字串。
函数说明:“S”和“E”都是从1开始的数字。
当“S”比“TEXT”中的字数大时,返回空。若是“E”大于“TEXT”字数,返回从“S”开始,到“TEXT”结束的单词串。若是“S”大于“E”,返回空。
10.$(words TEXT)
函数名称:统计单词数目函数—words。
函数功能:字算字串“TEXT”中单词的数目。
返回值:“TEXT”字串中的单词数。
11.$(firstword NAMES…)
函数名称:取首单词函数—firstword。
函数功能:取字串“NAMES…”中的第一个单词。
返回值:字串“NAMES…”的第一个单词。
函数说明:“NAMES”被认为是使用空格分割的多个单词(名字)的序列。函数忽略“NAMES…”中除第一个单词之外的全部的单词。
(二)、文件名处理函数
1.$(dir NAMES…)
函数名称:取目录函数—dir。
函数功能:从文件名序列“NAMES…”中取出各个文件名目录部分。文件名的目录部分就是包含在文件名中的最后一个斜线(“/”)(包括斜线)以前的部分。
返回值:空格分割的文件名序列“NAMES…”中每个文件的目录部分。
函数说明:若是文件名中没有斜线,认为此文件为当前目录(“./”)下的文件。
2.$(notdir NAMES…)
函数名称:取文件名函数——notdir。
函数功能:从文件名序列“NAMES…”中取出非目录部分。目录部分是指最后一个斜线(“/”)(包括斜线)以前的部分。删除全部文件名中的目录部分,只保留非目录部分。
返回值:文件名序列“NAMES…”中每个文件的非目录部分。
函数说明:若是“NAMES…”中存在不包含斜线的文件名,则不改变这个文件名。以反斜线结尾的文件名,是用空串代替,所以当“NAMES…”中存在多个这样的文件名时,返回结果中分割各个文件名的空格数目将不肯定!这是此函数的一个缺陷。
3.$(suffix NAMES…)
函数名称:取后缀函数—suffix。
函数功能:从文件名序列“NAMES…”中取出各个文件名的后缀。后缀是文件名中最后一个以点“.”开始的(包含点号)部分,若是文件名中不包含一个点号,则为空。
返回值:以空格分割的文件名序列“NAMES…”中每个文件的后缀序列。
函数说明:“NAMES…”是多个文件名时,返回值是多个以空格分割的单词序列。若是文件名没有后缀部分,则返回空。
4.$(basename NAMES…)
函数名称:取前缀函数—basename。
函数功能:从文件名序列“NAMES…”中取出各个文件名的前缀部分(点号以后的部分)。前缀部分指的是文件名中最后一个点号以前的部分。
返回值:空格分割的文件名序列“NAMES…”中各个文件的前缀序列。若是文件没有前缀,则返回空字串。
函数说明:若是“NAMES…”中包含没有后缀的文件名,此文件名不改变。若是一个文件名中存在多个点号,则返回值为此文件名的最后一个点号以前的文件名部分。
5.$(addsuffix SUFFIX,NAMES…)
函数名称:加后缀函数—addsuffix。
函数功能:为“NAMES…”中的每个文件名添加后缀“SUFFIX”。参数“NAMES…”为空格分割的文件名序列,将“SUFFIX”追加到此序列的每个文件名的末尾。
返回值:以单空格分割的添加了后缀“SUFFIX”的文件名序列。
6.$(addprefix PREFIX,NAMES…)
函数名称:加前缀函数—addprefix。
函数功能:为“NAMES…”中的每个文件名添加前缀“PREFIX”。参数“NAMES…”是空格分割的文件名序列,将“SUFFIX”添加到此序列的每个文件名以前。
返回值:以单空格分割的添加了前缀“PREFIX”的文件名序列。
7.$(join LIST1,LIST2)
函数名称:单词链接函数——join。
函数功能:将字串“LIST1”和字串“LIST2”各单词进行对应链接。就是将“LIST2”中的第一个单词追加“LIST1”第一个单词字后合并为一个单词;将“LIST2”中的第二个单词追加到“LIST1”的第一个单词以后并合并为一个单词,……依次列推。
返回值:单空格分割的合并后的字(文件名)序列。
函数说明:若是“LIST1”和“LIST2”中的字数目不一致时,二者中多余部分将被做为返回序列的一部分。
8.$(wildcard PATTERN)
函数名称:获取匹配模式文件名函数—wildcard
函数功能:列出当前目录下全部符合模式“PATTERN”格式的文件名。
返回值:空格分割的、存在当前目录下的全部符合模式“PATTERN”的文件名。
函数说明:“PATTERN”使用shell可识别的通配符,包括“?”(单字符)、“*”(多字符)等。
(三)、其它函数
1.$(foreach VAR,LIST,TEXT)
函数功能:函数“foreach”不一样于其它函数。它是一个循环函数。相似于Linux的shell中的循环(for语句)。这个函数的工做过程是这样
的:若是必要(存在变量或者函数的引用),首先展开变量“VAR”和“LIST”;而表达式“TEXT”中的变量引用不被展开。执行时把“LIST”中使
用空格分割的单词依次取出赋值给变量“VAR”,而后执行“TEXT”表达式。重复直到“LIST”的最后一个单词(为空时结束)。“TEXT”中的变量
或者函数引用在执行时才被展开,所以若是在“TEXT”中存在对“VAR”的引用,那么“VAR”的值在每一次展开式将会到的不一样的值。
返回值:空格分割的屡次表达式“TEXT”的计算的结果。
2.$(if CONDITION,THEN-PART[,ELSE-PART])
函数功能:函数“if”提供了一个在函数上下文中实现条件判断的功能。就像make所支持的条件语句—ifeq。第一个参数“CONDITION”,在函
数执行时忽略其前导和结尾空字符并展开。“CONDITION”的展开结果非空,则条件为真,就将第二个参数“THEN_PATR”做为函数的计算表达
式,函数的返回值就是第二表达式的计算结果;“CONDITION”的展开结果为空,将第三个参数
“ELSE-PART”做为函数的表达式,返回结果为第三个表达式的计算结果。
返回值:根据条件决定函数的返回值是第一个或者第二个参数表达式的计算结果。当不存在第三个参数“ELSE-PART”,而且“CONDITION”展开为空,函数返回空。
函数说明:函数的条件表达式“CONDITION”决定了,函数的返回值只能是“THEN-PART”或者“ELSE-PART”两个之一的计算结果。
3.$(call VARIABLE,PARAM,PARAM,...)
函数功能:“call”函数是惟一一个能够建立定制参数化的函数的引用函数。咱们能够将一个变量定义为一个复杂的表达式,用“call”函数根据不一样的参数对它进行展开来得到不一样的结果。
在执行时,将它的参数“PARAM”依次赋值给临时变量“$(1)”、“$(2)”(这些临时变量定义在“VARIABLE”的值中,参考下边的例
子)……
call函数对参数的数目没有限制,也能够没有参数值,没有参数值的“call”没有任何实际存在的意义。执行时变量“VARIABLE”被展开为在函数
上下文有效的临时变量,变量定义中的“$(1)”做为第一个参数,并将函数参数值中的第一个参数赋值给它;变量中的“$(2)”同样被赋值为函数的第二个
参数值;依此类推(变量$(0)表明变量“VARIABLE”自己)。以后对变量“VARIABLE” 表达式的计算值。
返回值:参数值“PARAM”依次替换“$(1)”、“$(2)”…… 以后变量“VARIABLE”定义的表达式的计算值。
函数说明:1.
函数中“VARIBLE”是一个变量名,而不是对变量的引用。所以,一般“call”函数中的“VARIABLE”中不包含“$”(固然,除了此变量名是
一个计算的变量名)。2.
当变量“VARIBLE”是一个make内嵌的函数名时(如“if”、“foreach”、“strip”等),对“PARAM”参数的使用须要注意,因
为不合适或者不正确的参数将会致使函数的返回值难以预料。3. 函数中多个“PARAM”之间使用逗号分割。4.
变量“VARIABLE”在定义时不能定义为直接展开式!只能定义为递归展开式。
4.value函数
$(value VARIABLE)
函数功能:不对变量“VARIBLE”进行任何展开操做,直接返回变量“VARIBALE”表明的值。这里“VARIABLE”是一个变量名,通常不包含“$”(固然,除了计算的变量名),
返回值:变量“VARIBALE”所定义文本值(不展开其中的变量或者函数应用)。
5.eval函数
函数功能:函数“eval”是一个比较特殊的函数。使用它咱们能够在咱们的Makefile中构造一个可变的规则结构关系(依赖关系链),其中可使用其
它变量和函数。函数“eval”对它的参数进行展开,展开的结果做为Makefile的一部分,make能够对展开内容进行语法解析。展开的结果能够包含
一个新变量、目标、隐含规则或者是明确规则等。也就是说此函数的功能主要是:根据其参数的关系、结构,对它们进行替换展开。
返回值:函数“eval”的返回值时空,也能够说没有返回值。
函数说明:“eval”函数执行时会对它的参数进行两次展开。第一次展开过程发是由函数自己完成的,第二次是函数展开后的结果被做为Makefile内容
时由make解析时展开的。明确这一点对于使用“eval”函数很是重要。在理解了函数“eval”二次展开的过程后。实际使用时,当函数的展开结果中存
在引用(格式为:$(x))时,那么在函数的参数中应该使用“$$”来代替“$”。由于这一点,因此一般它的参数中会使用函数“value”来取一个变量
的文本值。
6.origin函数
$(origin VARIABLE)
函数功能:函数“origin”查询参数“VARIABLE”(一般是一个变量名)的出处。
函数说明:“VARIABLE”是一个变量名而不是一个变量的引用。所以一般它不包含“$”(固然,计算的变量名例外)。
返回值:返回“VARIABLE”的定义方式。用字符串表示。
. undefined
变量“VARIABLE”没有被定义。
. default
变量“VARIABLE”是一个默认定义(内嵌变量)。如“CC”、“MAKE”、“RM”等变量。若是在Makefile中从新定义这些变量,函数返回值将相应发生变化。
. environment
变量“VARIABLE”是一个系统环境变量,而且make没有使用命令行选项“-e”(Makefile中不存在同名的变量定义,此变量没有被替代)。
. environment override
变量“VARIABLE”是一个系统环境变量,而且make使用了命令行选项“-e”。Makefile中存在一个同名的变量定义,使用“make -e”时环境变量值替代了文件中的变量定义。
. file
变量“VARIABLE”在某一个makefile文件中定义。
. command line
变量“VARIABLE”在命令行中定义。
. override
变量“VARIABLE”在makefile文件中定义并使用“override”指示符声明。
. automatic
变量“VARIABLE”是自动化变量。
7.shell函数
不一样于除“wildcard”函数以外的其它函数。make可使用它来和外部通讯。
函数功能:函数“shell”所实现的功能和shell中的引用(``)相同。实现了命令的扩展。意味着须要一个shell
命令做为它的参数,而返回的结果是此命令在shell中的执行结果。make仅仅对它的回返结果进行处理;make将函数的返回结果中的全部换行符
(“\n”)或者一对“\n\r”替换为单空格;并去掉末尾的回车符号(“\n”)或者“\n\r”。函数展开式时,它所调用的命令(它的参数)获得执
行。除了对它的引用出如今规则的命令行中和递归的变量定义引用之外,其它决大多数状况下,make在读取Makefile时函数shell就被扩展。
返回值:函数“shell”的参数在shell中的执行结果。
函数说明:函数自己的返回值是其参数的执行结果,没有进行任何处理。对结果的处理是由make进行的。当对函数的引用出如今规则的命令行中,命令行在执行
时函数引用才被展开。展开过程函数参数的执行时在另一个shell进程中完成的,所以对于出如今规则命令行的多级“shell”函数引用须要谨慎处理,
不然会影响效率(每一级的“shell”函数的参数都会有各自的shell进程)。
8.error 函数
$(error TEXT…)
函数功能:产生致命错误,并提示“TEXT…”信息给用户,以后退出make的执行。须要说明的是:“error”函数是在函数展开式(函数被调用时)才
提示信息并结束make进程。所以若是函数出如今命令中或者一个递归的变量定义中时,在读取Makefile时不会出现错误。而只有包含
“error”函数引用的命令被执行,或者定义中引用此函数的递归变量被展开时,才会提示致命信息“TEXT…”同时make退出执行。
返回值:空字符
函数说明:“error”函数通常不出如今直接展开式的变量定义中,不然在make读取Makefile时将会提示致命错误。
9. warning 函数
$(warning TEXT…)
函数功能:函数“warning”相似于函数“error”,区别在于它不会致使致命错误(make不退出),而只是提示“TEXT…”,make的执行过程继续。
返回值:空字符
函数说明:用法和“error”相似,展开过程相同。
3.makefile模板
GXX=g++
GCC=gcc CXXFLAG=-fopenmp -march=core2 -O3 -fomit-frame-pointer -pipe CFLAG=$(CXXFLAG) DIR_INC=./include DIR_SRC=./src DIR_OBJ=./obj DIR_BIN=./bin DIR_LIB=/home/your_dir/env/lib_dir1/ LDFLAG=-Wl,--rpath=$(DIR_LIB)/lib,--rpath=/home/your_dir/env/lib,--rpath=$(PWD)/lib,-O3 -fopenmp #指定include的路径 INCLUDE=-I$(DIR_INC) -I./lib/include -I $(DIR_LIB)/include -I$(DIR_LIB)/include/h_file_dir #指定lib的路径 LIBS=-L $(DIR_LIB)/lib -lxxx1 -lxxx2 -lxxx3 -L/home/your_dir/env/lib -L $(PWD)/lib -lxxx4 TARGET=$(DIR_BIN)/exe_name DEF= -DLINUX #-DPATH #-DDEBUG SRC=$(wildcard ${DIR_SRC}/*.cpp) OBJS=$(SRC:$(DIR_SRC)/%.cpp=$(DIR_OBJ)/%.o) $(TARGET):$(OBJS) $(GXX) $(GXXFLAG)$(LDFLAG) -o $@ $(OBJS) $(LIBS) #$(TARGET):$(OBJS) # ar cru $(TARGET) $(OBJS) $(DIR_OBJ)/%.o:$(DIR_SRC)/%.cpp $(GXX) -o $@ -c $< $(CXXFLAG) $(INCLUDE) $(DEF) clean: rm -fr $(OBJS) $(TARGET);
说明:(1)利用自动化变量“$@”,这个变量表示着目前规则中全部的目标的集合。
(2)$<是第一个"prerequisite", 不知道怎么翻译,就是target:后面的列表里的第一个.
(Often the prerequisites include header files as well, which you do not want to mention in the recipe. The automatic variable `$<' is just the first prerequisite:)
示例:
VPATH = src:../headers
foo.o : foo.c defs.h hack.h
cc -c $(CFLAGS) $< -o $@
这里$<就是foo.c
四,其余问题
1.rpath连接选项
SDK库的名称为liba.so, 其依赖于libb.so和libc.so,那么在编译应用程序的时候使用如下命令:
+++++++++++++++++++++++++++++++++++++++++++++
gcc -o test test.c -I. -L. -la -lb -lc
+++++++++++++++++++++++++++++++++++++++++++++
将SDK库即liba.so交给其余的开发人员,其余的开发人员可不想编译的时候,显示的连接liba.so所依赖的库。他们更愿意编译的时候,只显示地连接liba.so。
rpath连接选项主要有两个功能:
(1)程序运行时,优先到rpath指定的目录去寻找依赖库
(2)程序连接时,在指定的目录中,隐式的连接那些动态库所须要的连接库。
每每咱们都熟知第一个功能,忽略第二个功能。而第二个功能正是如今所须要的。
咱们将liba.so,libb.so 和libc.so拷贝的同一个目录中,而后利用rpath连接应用程序,这样编译便不须要显示的去连接liba.so所依赖的库了。
+++++++++++++++++++++++++++++++++++++++++++++
gcc -o test test.c -I. -L. -la -Wl,-rpath=.
+++++++++++++++++++++++++++++++++++++++++++++