您的位置:首页 > 运维架构 > Linux

一个linux程序分析讲解(入门级)

2011-10-09 14:59 295 查看
1 #最终文件

2 EXECUTABLE := test

3 #编译器及标志

4 CC=gcc

5 CXX=g++

6 CFLAGS := -g -Wall

7 CXXFLAGS := $(CFLAGS)

8 CXXFLAGS+= -MD

9 #库和路径

10 LIBS :=-lstlport_gcc_stldebug

11 LIBPATH:=-L/usr/local/lib

12 INCLUDEPATH:=-I/usr/local/include/stlport/

13 OBJSPATH:=../Obj/test/

14 EXECUTABLEPATH:=../Execute/

15 RM := rm -f

16 #源

17 SOURCE := $(wildcard *.c) $(wildcard *.cpp)

18 OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))

19 DEPS := $(patsubst %.o,%.d,$(OBJS))

20 #规则

21 .SUFFIXES: .cpp .c .o .so .a .d

22 $(OBJSPATH)%.o:%.c

23 $(CC) $(CXXFLAGS) -c $< -o $@

24 $(OBJSPATH)%.o:%.cpp

25 $(CXX) $(CXXFLAGS) -c $< -o $@

26 $(OBJSPATH)%.d:%.cpp

27 $(CXX) -MM $< >$@

28 #主体部分

29 .PHONY : all deps objs clean rebuild

30 all : $(EXECUTABLE)

31 $(CXX) $(CXXFLAGS) $(INCLUDEPATH) $(LIBS) $(LIBPATH) $(addprefix $(OBJSPATH),$(OBJS)) -o $(EXECUTABLEPATH)$(EXECUTABLE)

32 deps : $(addprefix $(OBJSPATH),$(DEPS))

33 objs : $(addprefix $(OBJSPATH),$(OBJS))

34 clean :

35 @$(RM) $(OBJSPATH)*.o

36 @$(RM) $(OBJSPATH)*.d

37 @$(RM) $(EXECUTABLEPATH)$(EXECUTABLE)

38 rebuild : clean all

39 -include $(addprefix $(OBJSPATH),$(DEPS))

40 $(EXECUTABLE) : objs

以上就是全部了,呵呵,下面开始讲解, 有不对的还请多多指教:

1 以#开始的一行为注释,和c++的//符号一样;

2 在make中可以定义宏,就类似于c++中的宏,其实就是对等号左边的由右边的来替换,它有两种形式,一种是:=表是立刻进行替换,另一种是=表示不直接进行替换而是用时才进行替换,也就是说如果你在之后改变其值左值也会随着改变,而:=则以第一个次为准;宏在使用时用$(宏名)的形式,比较奇特;

4,5 以make中有些是它自身预定义的宏名字,比如CC和CXX,CC会在编译c文件时指定编译器名字,CXX则在编译c++文件时指定编译器名字,后面就会提到;

6,7,8 同样为内定的宏,CFLAG为编译c文件时指定的参数,CXXFLAG为编译c++文件时指定的编译器参数;

10-14 为几个目录的定义,以后会用到,-l,-L,-I分别为gcc编译时指定路径时的选项;

15 内定宏(我记得是),指定删除文件所用的命令形式;

17-19 定这源,目标和依赖文件的路径以备后用,在这里要说的是,make内部有很多内定的函数,为了方便我们使用,呵呵,用法是$(函数名 参数,参数...)这里用到的几个函数的意思是:wildcard所有满足后面条件的值的枚举,patsubst是将所有第三个参数中符合第一个参数形式的文件改变成第二个参数的形式,有点绕,还有很多函数,找手册吧。

21 .SUFFIXES为make中的关键字,表示不使用之后的文件扩展名的缺省规则,在make中是有一些预先定义好的缺省规则的,比如你要编译c文件,你并不需要指定其规则,make就知道怎么去处理,在这里,去掉这些规则是为了使用我们自己的自定义规则

22-27 我们自定义的规则来了,呵呵,就这几行,我花了一个星期才试明白,它的语法很简单,%为通配符,就是dir命令中的那个*,:表示前一个由后边的依赖产生的,通过什么产生的,通过下边的那个式子,23行中$(CC)表示的是c的编译器,就是我们前面定义的gcc,然后后面是一堆参数加值,反正最后就是我们要的那个式子了。这句的整个意思是说,当遇到*.o文件要处理时,找到*.c文件,注意这个*指的是相同的文件,找到之后怎么处理用下面的式子进行编译,当然你也可以编写类似的语句处理其它语言的编译,这就是make的混合编译了吧,哈哈。还有,$<和$@都是内定宏,$<表示:后边的那些,$@表示的是:前的第一个(如果有多个文件的话)。还有就是27的那个>是什么意思你可能不明白,.d文件就是由编译器自动查找文件的依赖时产生的文件,而>表示阄它输出的结果重定向到>后面的文件中,要不它可能会输出到屏亩,这并不是我们想要的结果,至于为什么要.d文件,后面会讲到,呵呵,有点吊胃口吧

29 .PHONY 也是一关键字,表示所有后面的标志都要强制生成

30-38 主体部分,呵呵,我们在使用make的时候可能经常要这么用,make all这时make就会找文件中的all标志,如果有就会继续,其它几个也都一样.这里还要谈到一个make文件中的基本问题,呵呵,现在讲好象有点晚了,是就在make文件中有一个固定的规则匹配方式,就是:前的表示目标,:后的表示目标依赖的文件,而下面的那个就表示满足依赖后进行的处理,就是说当make找到all时就会去找all的:后面的依赖,如果所有依赖都完成或没有变化,就去执行下面的那个处理程序,就这么简单,而所有的一切都是为了达到这个目的..PHONY是说不管依赖有没有发生变化都要进行强制的处理,对于依赖文件它会从前到后一个一个找,比如38行它会先进行clean的处理(找clean的依赖)然后再进行all的处理,而它没有本身的处理.

39 include和c的#include一样,包含所有gcc自动生成的依赖文件(26-27生成),这样就不用我们自己来找了,前面的-表示当没有找到文件时,不进行报错而继续下面的工作,addprefix表示在第二个参数的每个项前面加上第一个参数表示的前缀.

40 最后我们给我们要最后生成的文件作一个依赖,完成
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: