makefile学习

Posted sunnypoem

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了makefile学习相关的知识,希望对你有一定的参考价值。

Makefile基础

一.Makefile基础

1.1 步骤:编译-链接

编译(compile):把源文件编译成中间目标文件(object file/.o .obj文件)

链接(link):将中间目标文件合成执行文件

库文件(library file):中间目标文件太多,将中间目标文件打包。(.lib 或 .a 文件)

 

1.2 makefile的规则

Target ... : prerequisites ...

Command

...

...

Target: 可以是object file,也可以是一个执行文件,还可以是一个标签(label)

Prerequisites: 生成该target所依赖的文件或target

Command:该target要执行的命令(任意的shell命令)

 

这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说:

 

prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。

这就是makefile的规则,也就是makefile中最核心的内容。

 

1.3 一个简单的例子

edit : main.o kbd.o command.o display.o

insert.o search.o files.o utils.o

cc -o edit main.o kbd.o command.o display.o

insert.o search.o files.o utils.o

main.o : main.c defs.h

cc -c main.c

kbd.o : kbd.c defs.h command.h

cc -c kbd.c

command.o : command.c defs.h command.h

cc -c command.c

display.o : display.c defs.h buffer.h

cc -c display.c

insert.o : insert.c defs.h buffer.h

cc -c insert.c

search.o : search.c defs.h buffer.h

cc -c search.c

files.o : files.c defs.h buffer.h command.h

cc -c files.c

utils.o : utils.c defs.h

cc -c utils.c

clean :

rm edit main.o kbd.o command.o display.o

insert.o search.o files.o utils.o

 

1.4 make 工作流程

  1. A.  Make会在当前目录下找名字叫makefile或Makefile的文件
  2. B.  如果找到,它会找文件中第一个目标文件(edit),并把这个文件作为最终的目标文件
  3. C.  如果edit文件不存在或是edit所依赖的.o文件的文件修改时间比edit新,那么会执行后面的command生成edit
  4. D.  如果edit所依赖的.o文件也不存在,那么make会在当前文件找目标为.o文件的依赖性,如果找到则再根据规则生成.o文件。

比如,如果我们改变了command.h,那么kdb.o,command.o,file.o都会重新编译,并且edit会重新链接。

1.5 make自动推导

隐晦规则:

只要make看到一个.o文件,它自动把.c文件加到依赖关系中,并且cc -c .c的command也会被推导出来。

objects = main.o kbd.o command.o display.o

insert.o search.o files.o utils.o

edit : $(objects)

cc -o edit $(objects)

$(objects) : defs.h

kbd.o command.o files.o : command.h

display.o insert.o search.o files.o : buffer.h

.PHONY : clean

clean :

rm edit $(objects)

 

1.6 makefile内容

A. 显示规则

B. 隐晦规则

C. 变量定义

D. 文件指示( include foo.make *.mk $(bar) )

E. 注释(#)

F. 命令(必须以Tab键开始)

 

1.7 make的工作方式

A. 读入所有的Makefile

B. 读入被include的其它Makefile

C. 初始化文件中的变量

D. 推导隐晦规则,并分析所有规则

E. 为所有的目标文件创建依赖关系链

F. 根据依赖关系链,决定哪些目标要重新生成

G. 执行生成命令

 

1.8 规则中的通配符

~ :~/test  = $HOME/test

~usr/test = usr宿主目录下的test

* : *.c 所有后缀为c的文件,文件中有通配符的用转义字符 (如*)

 

1.9 搜索路径

VPATH = src: ../headers  (目录由冒号分割)

make 依赖和目标文件在当前目录找不到的情况下会在VPATH目录中寻找

2.0 伪目标

.PHONY : clean

表示并不生成clean这个文件,clean只是一个标签,make 无法生成它的依赖关系和决定它是否执行,只有显示的指明这个标签才能让其生效。

 

2.1 多目标

bigoutput littleoutput : text.g

generate text.g -$(subst output,,[email protected]) > [email protected]

 

上述规则等价于:

bigoutput : text.g

generate text.g -big > bigoutput

littleoutput : text.g

generate text.g -little > littleoutput

2.2 静态模式

静态模式可以更容易地定义多目标的规则

<targets ...> : <target-pattern> : <prereq-patterns ...>

<commands>

 

例子:

objects = foo.o bar.o

all: $(objects)

$(objects): %.o: %.c

$(CC) -c $(CFLAGS) $< -o [email protected]

展开:

foo.o : foo.c

$(CC) -c $(CFLAGS) foo.c -o foo.o

bar.o : bar.c

$(CC) -c $(CFLAGS) bar.c -o bar.o

 

2.3 定义命令包

define run-yacc

yacc $(firstword $^)

mv y.tab.c [email protected]

endef

 

2.4 变量

Variable = xxx   Variable变量 = 赋值

$(Variable)   括号是为了更安全的使用变量

 

X := foo

Y := $(X) bar

X := later

用:= 赋值变量 ,前面的变量不能使用后面的变量,只能使用前面已经定义好的变量

 

?=  如果变量已经定义,则什么也不做

赋值语句后#的注释注意:

Dir := /foo/bar   # directory

那么$(Dir)/file  会是/foo/bar   /file,因为赋值后有四个空格

 

2.5 变量替换

$(var : a=b) 把变量var中所有以a字串结尾的a替换成b字串

$(var:%.o=%.c)

 

2.6 追加变量值

Var += other

Var := $(Var) other

 

2.7 环境变量

 

 

2.8 条件判断

ifeq ifneq ifdef ifndef

else

endif

 

ifeq (<arg1>, <arg2>)

ifeq ‘<arg1>‘ ‘<arg2>‘

ifeq "<arg1>" "<arg2>"

ifeq "<arg1>" ‘<arg2>‘

ifeq ‘<arg1>‘ "<arg2>"

 

2.9 make的运行

其他功能

? all:这个伪目标是所有目标的目标,其功能一般是编译所有的目标。

? clean:这个伪目标功能是删除所有被make创建的文件。

? install:这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目

标中去。

? print:这个伪目标的功能是例出改变过的源文件。

? tar:这个伪目标功能是把源程序打包备份。也就是一个tar文件。

? dist:这个伪目标功能是创建一个压缩文件,一般是把tar文件压成Z文件。或是gz文件。

? TAGS:这个伪目标功能是更新所有的目标,以备完整地重编译使用。

? check和test:这两个伪目标一般用来测试makefile的流程。

 

3.0 隐含规则

常用的隐含规则

1. 编译C程序的隐含规则。

<n>.o 的目标的依赖目标会自动推导为<n>.c ,并且其生成命令是$(CC) -c

$(CPPFLAGS) $(CFLAGS)

2. 编译C++程序的隐含规则。

<n>.o 的目标的依赖目标会自动推导为<n>.cc 或是<n>.C ,并且其生成命令是

$(CXX) -c $(CPPFLAGS) $(CFLAGS)。(建议使用.cc作为C++源文件的后缀,而

不是.C)

 

模式规则示例

%.o : %.c

$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o [email protected]

 

 

二.Makefile分析

#当前模块的配置

CURRENT_MODULE_PATH:=$(shell pwd)

 

INC_FLAGS:=-I$(CURRENT_MODULE_PATH)/inc #加入模块头文件路径

#工程的公共配置

ROOT_PATH:=$(CURRENT_MODULE_PATH)/..

PROJECT_COMMON_PATH:=$(ROOT_PATH)/common

 

INC_FLAGS+=-I$(PROJECT_COMMON_PATH)/inc #加入工程公共头文件路径

INC_FLAGS+=-I$(PROJECT_COMMON_PATH)/inc/test #加入工程公共头文件路径

LIB_FLAGS:=-L$(PROJECT_COMMON_PATH)/lib #加入工程公共库文件路径

#相关的配置

SRV_PATH:=$(ROOT_PATH)/SRV

SRV_INC_PATH:=$(SRV_PATH)/include

SRV_LIB_PATH:=$(SRV_PATH)/lib

 

SRV_INC_FLAGS:=-I$(SRV_INC_PATH)

                -I$(SRV_INC_PATH)/pub-sub

                -I$(SRV_INC_PATH)/infra

                -I$(SRV_INC_PATH)/3rdparty

                -I$(SRV_INC_PATH)/saturn

                -I$(SRV_INC_PATH)/common

 

INC_FLAGS+=$(SRV_INC_FLAGS) #加入SRV头文件路径

LIB_FLAGS+=-L$(SRV_LIB_PATH)

#需要连接的库

SYS_LIBS:=-lpthread -lz -ldl -lrt -lcrypto -lssl -lm

SRV_LIBS:=-lpubsub -linfra -lentry -lsaturn -ltimer -lprotobuf -lrestful_server -lserved -lre2 -lboost_system

                -ldpdk -lcurl

PROJECT_COMMON_LIBS:= #

TEST_LIBS:= -lgtest_main -lmockcpp

LINK_LIBS:= $(SRV_LIBS) $(SYS_LIBS) $(PROJECT_COMMON_LIBS)

 

 

#测试代码路径

CURRENT_MODULE_TEST_PATH:=$(CURRENT_MODULE_PATH)/test

 

GCOVRFLAGS:= -fprofile-arcs -ftest-coverage

 

#中间文件相关

CURRENT_MODULE_BUILD_PATH:=$(CURRENT_MODULE_PATH)/build

MODULE_SRC:=$(notdir $(wildcard $(CURRENT_MODULE_PATH)/src/*.cpp))

MODULE_DEBUG_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/debug/,$(patsubst %.cpp,%.o,$(MODULE_SRC)))

MODULE_RELEASE_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/release/,$(patsubst %.cpp,%.o,$(MODULE_SRC)))

MODULE_TEST_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/test/,$(filter-out main.o,$(patsubst %.cpp,%.o,$(MODULE_SRC))))

 

 

COMMON_SRC:=$(notdir $(wildcard $(PROJECT_COMMON_PATH)/src/*.cpp))

COMMON_DEBUG_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/debug/,$(patsubst %.cpp,%.o,$(COMMON_SRC)))

COMMON_RELEASE_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/release/,$(patsubst %.cpp,%.o,$(COMMON_SRC)))

COMMON_TEST_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/test/,$(patsubst %.cpp,%.o,$(COMMON_SRC)))

 

TEST_SRC:=$(notdir $(wildcard $(CURRENT_MODULE_TEST_PATH)/*.cpp))

TEST_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/test/,$(patsubst %.cpp,%.o,$(TEST_SRC)))

 

#顶级目标

DEBUG_TARGET:=$(CURRENT_MODULE_PATH)/build/DLocationCalc

RELEASE_TARGET:=$(CURRENT_MODULE_PATH)/build/RLocationCalc

TEST_TARGET:=$(CURRENT_MODULE_PATH)/build/TLocationCalc

 

RELEASE_FLAGS:= -DNDEBUG

DEBUG_FLAGS:=-g -DDEBUG

TEST_FLAGS:=-g -DDEBUG  -DTEST

CXXFLAGS+=-std=c++11

 

.PHONY:default release debug test clean pre_build

 

default:debug

 

pre_build:

         mkdir -p $(CURRENT_MODULE_BUILD_PATH)/release

         rm -f $(CURRENT_MODULE_BUILD_PATH)/release/RLocationCalc

         mkdir -p $(CURRENT_MODULE_BUILD_PATH)/debug

         rm -f $(CURRENT_MODULE_BUILD_PATH)/debug/DLocationCalc

         mkdir -p $(CURRENT_MODULE_BUILD_PATH)/test

         rm -f $(CURRENT_MODULE_BUILD_PATH)/test/TLocationCalc

 

#编译调试版本

debug:pre_build $(DEBUG_TARGET)

 

$(DEBUG_TARGET): $(MODULE_DEBUG_OBJS) $(COMMON_DEBUG_OBJS)

         $(CXX) $(CXXFLAGS) -o [email protected] $^ $(LIB_FLAGS) $(LINK_LIBS)

 

#编译发布版本

release:pre_build $(RELEASE_TARGET)

 

$(RELEASE_TARGET):$(MODULE_RELEASE_OBJS) $(COMMON_RELEASE_OBJS)

         $(CXX) $(CXXFLAGS) -o [email protected] $^ $(LIB_FLAGS) $(LINK_LIBS)

 

#编译测试用例并运行

move_sample:

         cp $(CURRENT_MODULE_TEST_PATH)/test.csv $(CURRENT_MODULE_BUILD_PATH)/

test:pre_build move_sample $(TEST_TARGET)

         export LD_LIBRARY_PATH=$(SRV_LIB_PATH) &&

         ./build/TLocationCalc --gtest_output=xml:./build/gtest.xml &&

         gcovr -r . &&

         lizard src -l cpp -C 8 -L 100 -a 6

 

$(TEST_TARGET): $(MODULE_TEST_OBJS) $(COMMON_TEST_OBJS) $(TEST_OBJS)

         $(CXX) $(CXXFLAGS) -o [email protected] $^ $(LIB_FLAGS) $(TEST_LIBS) $(LINK_LIBS) $(GCOVRFLAGS)

 

#清除

clean:

         rm -rf $(CURRENT_MODULE_BUILD_PATH)

 

 

# debug 版本

$(CURRENT_MODULE_BUILD_PATH)/debug/%.o:$(CURRENT_MODULE_PATH)/src/%.cpp

         $(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) $(INC_FLAGS) -o [email protected] -c $^

$(CURRENT_MODULE_BUILD_PATH)/debug/%.o:$(PROJECT_COMMON_PATH)/src/%.cpp

         $(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) $(INC_FLAGS) -o [email protected] -c $^

 

#release 版本

$(CURRENT_MODULE_BUILD_PATH)/release/%.o:$(CURRENT_MODULE_PATH)/src/%.cpp

         $(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(INC_FLAGS) -o [email protected] -c $^

$(CURRENT_MODULE_BUILD_PATH)/release/%.o:$(PROJECT_COMMON_PATH)/src/%.cpp

         $(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(INC_FLAGS) -o [email protected] -c $^

 

#test 版本

$(CURRENT_MODULE_BUILD_PATH)/test/%.o:$(CURRENT_MODULE_PATH)/src/%.cpp

         $(CXX) $(CXXFLAGS) $(INC_FLAGS) $(TEST_FLAGS) $(GCOVRFLAGS) -o [email protected] -c $^

$(CURRENT_MODULE_BUILD_PATH)/test/%.o:$(PROJECT_COMMON_PATH)/src/%.cpp

         $(CXX) $(CXXFLAGS) $(INC_FLAGS) $(TEST_FLAGS) $(GCOVRFLAGS) -o [email protected] -c $^

$(CURRENT_MODULE_BUILD_PATH)/test/%.o:$(CURRENT_MODULE_TEST_PATH)/%.cpp

         $(CXX) $(CXXFLAGS) $(INC_FLAGS) $(TEST_FLAGS) -o [email protected] -c $^

 

 

 

三.常用命令

A. 通配符自动展开

   在makefile的规则中,通配符会被自动展开,但是在变量的定义和函数引用时,通配符将失效,这种情况下如要用通配符,就要用函数wildcard,用法$(wildcard PATTERN..)

例子:objects := $(wildcard *.c) 来获取工作目录中所有.c 文件列表

B . 模式字符串替换patsubst函数

例子:$(patsubst %.c, %.o, $(dir)) 把$(dir) 中的变量符合.c结尾的全部替换为.o

C. 去掉路径notdir($src)

D. 字符串替换subst

$(subst FROM, TO, TEXT) 将TEXT中的FROM替换成TO

E. 过滤函数filter

例子:$(filter %.o, $(files)) 从files中过滤出.o 的文件

F. 首单词函数firstword

G. $( strip <string>) 去掉字串开头和结尾的空字符

H. $(findstring <find>,<in>) 在in中查找find字串,找到返回find,否则返回空字串

I. $(filter <pattern...>, <text>)以pattern模式过滤text中的单词,保留符合模式的单词,模式可以多个

J. $(filter-out <pattern...>, <text>) 反过滤函数,返回不符合模式的单词

K. $(sort <list>) 排序(升序),去掉相同的单词

L. word,wordlist,firstword,words

M. $(dir <names ...>) 取目录

N. $(notdir <names ...>) 取文件函数

O. $(suffix <names ...>)取后缀函数

P. $(basename <names...>)取前缀函数

Q. $(addsuffix <suffix>,<names...>) 添加后缀

R. $(addprefix <prefix>,<names...>) 添加前缀

S. $(join <list1>,<list2>)把list2中的单词对应加到list1的后面

T. $(foreach <var>,<list>,<test>)将list中单词逐个取出放到var变量中,然后在执行test所包含的表达式

U. $(if <condition>,<then-part>,<else-part>)

 

四. 自动变量

[email protected]: 目标集合

$<: 所有的依赖目标集第一个目标,如果依赖是模式定义的,取出一系列

$^: 所有的依赖目标的集合,以空格分割

$+ : 类似$^,去除重复的依赖

$? : 所有比目标更新的依赖集合

objects = foo.o bar.o

all: $(objects)

$(objects): %.o: %.c

$(CC) -c $(CFLAGS) $< -o [email protected]

展开:

foo.o : foo.c

$(CC) -c $(CFLAGS) foo.c -o foo.o

bar.o : bar.c

$(CC) -c $(CFLAGS) bar.c -o bar.o

 

五. 编译器g++

gcc and g++分别是gnu的c & c++编译器 gcc/g++在执行编译工作的时候,总共需要4步

1.预处理,生成.i的文件[预处理器cpp]

2.将预处理后的文件转换成汇编语言,生成文件.s[编译器egcs]

3.由汇编变为目标代码(机器代码)生成.o的文件[汇编器as]

4.连接目标代码,生成可执行程序[链接器ld]

 

常用参数:

-ansi 只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色,

例如 asm 或 typeof 关键词。

-c 只编译并生成目标文件。

-DMACRO=DEFN 以字符串“DEFN”定义 MACRO 宏。

-g 生成调试信息。GNU 调试器可利用该信息。

-IDIRECTORY 指定额外的头文件搜索路径DIRECTORY。

-LDIRECTORY 指定额外的函数库搜索路径DIRECTORY。

-lLIBRARY 连接时搜索指定的函数库LIBRARY。

-o  FILE 生成指定的输出文件。用在生成可执行文件时。

 

[参数详解]

-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文件

-S

  只激活预处理和编译,就是指把文件编译成为汇编代码。

  例子用法

  gcc -S hello.c

  他将生成.s的汇编代码,你可以用文本编辑器察看

-E

  只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面.

  例子用法:

  gcc -E hello.c > pianoapan.txt

  gcc -E hello.c | more

  慢慢看吧,一个hello word 也要与处理成800行的代码

-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<filename>

  例子用法:

  gcc hello.c -include /root/pianopan.h

  

-i macros file

  将file文件的宏,扩展到gcc/g++的输入文件,宏定义本身并不出现在输入文件中

  

-D macro

  相当于C语言中的#define macro

  

-D macro=defn

  相当于C语言中的#define macro=defn

  

-U macro

  相当于C语言中的#undef macro

-undef

  取消对任何非标准宏的定义

  

-Idir

  在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头文件,如果没有找到,他回到缺省的头文件目录找,如果使用-I制定了目录,他

  回先在你所制定的目录查找,然后再按常规的顺序去找.

  对于#include<file>,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<file>造成的依赖关系。

  

-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语言特性

 

以上是关于makefile学习的主要内容,如果未能解决你的问题,请参考以下文章

Makefile学习----初步理解

gdbmake/makefile学习心得

gdbmake/makefile学习心得

Makefile学习笔记

Linux学习记录:Makefile

[转]Linux学习笔记——例说makefile 头文件查找路径