当前浏览

海思笔记

分类目录

展开|收起

看你喜欢

(1) (1) (42) (1) (1) (1) (16) (2) (1) (1) (4) (1) (2) (7) (4) (1) (1) (1) (1) (3) (1) (5) (1) (1) (1) (1) (1) (2) (1) (4) (4) (3) (1) (1) (2) (1) (37) (2) (1) (5) (3) (1) (4) (1) (1) (11) (3) (1) (9) (3) (1) (23) (2) (1) (2) (1) (1) (1) (1)

最新精华

如何编写makefile【4】- 要点分析(2)

接着上一篇文章继续分析。

7.模式规则

模式规则类似于普通规则,只是在模式规则中,目标的定义中需要包含“%”字符(确切地说是一个),包含“%”的目标被用来匹配一个文件名,“%”可以匹配任何非空字符串。规则的依赖文件中同样可以使用“%”,依赖中的“%”的取值情况由目标中的“%”来决定。例如:

这个规则描述了一个.o目标文件如何由对应的.c文件创建。规则的命令行中使用了自动化变量“$<”和“$@”,其中自动化变量“$<”代表规则的依赖,“$@”代表规则的目标文件。此规则在执行时,命令行中的自动化变量将根据实际的目标文件区对应值。

(1)自动化变量

在模式规则中,规则的目标和依赖文件名代表了一类文件名。命令是对所有这一类文件重建过程的描述,显然,在命令中不能指定特定的文件名,否则模式规则将没有了意义。那么在模式规则的命令行中该如何表示文件,将成我们这一小节的讨论重点。make中使用了“自动环变量”来实现这个目的,自动化变量的取值是根据具体的规则决定的,就是说对不同的规则其所代表的文件名不同。下面对常用的自动化变量进行说明:

$@ 代表规则中的目标文件名。如果目标是一个文档(Linux中,一般称.a文件为文档),那么它代表这个文档的文件名。在多目标的模式规则中,它代表的是哪个触发规则被执行的目标文件名。

$< 规则的第一个依赖文件名。如果是隐含规则,则它代表通过目标指定的第一个依赖文件。

$^ 规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件名,它所代表的只能是所有库成员(.o文件)名。一个文件可重复的出现在目标的依赖中,变量“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。

$+ …

【阅读全文】

如何编写makefile【3】- 要点分析(1)

看了上一篇文章的简单例子,我们就会对makefle有了个基本的认识。但是当我们打开一个实际工程的makefile文件时,发现还是看不懂,虽然知道这是一个规则,但不能理解这些规则为什么这样写,而且里面还有一些奇奇怪怪的符号,看一个实际的例子:

根据我自己的体会,初次看到上面的内容一定会发晕,$、%、$@、ifeq、@echo这样奇怪的符号是什么意思?搞不懂的话,没法再往下继续看,所以猜测很多人看到类似的内容就打道回府了,呵呵。其实这些很简单,都有约定好的意义。本节的目的就是讲解实际makefile代码中的一些要点问题,包括这些奇怪的符号,当然还有其它许多更重要的问题。为满足你的好奇心,先把这个例子中的这几个奇怪符号解释一下:

$(OBJ):就是取变量OBJ的值,变量OBJ 定义成目标文件的路径。

%.o:是模式匹配,只要后缀是.o都能匹配。我们知道信令子系统的模块很多,而且各个模块又含很多的的.c文件,如果我们为编译每个.c文件都写一个规则,这样规则就非常多,实际中应用一条规则就可以搞定。就是采用这里的模式匹配技术,比如对tcp模块,其代码(\tcp\source)包括:tcpFunc.c、tcpMoni.c和tcpLink.c,其目标文件分别是tcpFunc.o tcpMoni.o tcpLink.o 。可以写一个规则,其目标是tcp模块整的目标文件,而倚赖文件是这四个文件。根据上一节的介绍,要生成tcp模块整的目标文件,必须要生成各个依赖文件,所以make就会去找如何生成它们的规则,最后都可以匹配到这一条模式匹配规则。这种模式匹配在实际的makefile代码中大量应用,实际也是必须使用,因为每个文件的编译基本是类似的,也不可能每个文件写一个规则。

$@:代表规则中的目标文件名,在多目标的模式规则中,它代表的是那个触发规则被执行的目标文件名。后文可以看出,多目标的规则,可分解成多个单个目标的规则(依赖和命令都一样),多个单目标规则会依次执行,$@表示执行到哪个单目标规则时的目标名。本例的规则只有一个目标,但也这样引用,当然你用$(OBJ)/%.o也可以。

@echo:echo是DOS的回显命令,前面价格@表示不显示echo命令本身,这些都是DOS命令本身的规则,非makefile的定义。实际我们在编译版本时在屏幕上看到的一系列提示信息都是用这样的方法显示出来的。

ifeq:是makefile的一个关键字,和C语言中的条件编译类似,ifeq (_OS_LINUX, $(_OS_TYPE))的意思就是判断_OS_TYPE变量的值(因为其前面有个$)是否等于_OS_LINUX,就是说如果是Linux系统,就这样处理,否则就按else中的那样处理。类似的关键字还有ifneq(判断是否不等),ifdef(判断变量是否已定义),ifndef(判断变量是否没有定义)。…

【阅读全文】

如何编写makefile【2】- 例子

Make工具的每个版本都带一个make info文档,里面详细说明了如何编写makefile文件。网上有一个徐海兵翻译的makeV3.8版本的《GNU make中文手册》,可以很好地用来学习makefile,这里把一些重点的,实际应用中必须掌握的makefile语法规则作一个说明,相当于make手册的精华版。

一个简单的例子:

此例子由3个头文件和8个C文件组成。我们讲述写一个简单的Makefile,来描述如何创建最终的可执行文件“edit”,此可执行文件依赖于8个C源文件和3个头文件。Makefile文件的内容如下:

1.规则的概念

在解释这些语句的意义之前先解释一个makefile中的一个非常重要的概念:规则。上面的文件实际由10个规则组成,如其中的一个:

这个规则说明了编译出main.o需要倚赖两个文件main.c和defs.h,“cc –c main.c”的意思是实际编译main.o的命令行语句(实际编译命令还要包含很多的编译参数,这里只是为了示例)。Makefile中最核心的就是这些规则,其它的内容都是为书写规则服务的。规则可以用下面的描述来抽象表示:…

【阅读全文】

如何编写makefile【1】- 综述

对于一个大型的软件工程,需要进行必要的模块划分,每个模块的代码又是由很多的源文件组成的,如何把所有模块的代码编译成一个最终的版本文件是一个看似很复杂的问题,但实际我们却能很轻易地做到,一般只需点击编译按钮或执行一个命令行命令即可。我们都知道生成一个程序,需要编译+链接两个过程,但由于我们在学校里大多数人都是用IDE编译一个工程的,只管往里面加文件,点击按钮就可以启动IDE的编译。实际这就造成我们对命令行的编译方式几乎是从不关心。参加工作以后,公司里面的版本编译常常没有IDE了,全靠命令行的编译方式,所以造成大家理解版本编译过程的困难。

实际上理解版本的编译过程对理解代码的整体框架非常有好处,而且对你调试代码也有好处,最有名的就是-g开关选项,经常看一些牛人找到一个什么.mak文件然后去掉或加上一个-g开关,如果你对makefile有点研究,就会发现这不过是一个最简单的gcc编译选项,-g选项是在编译时产生调试信息(一般包括每条指令和代码行号,文件名的对应记录),这样你才可以在调试时用调试器进行设断点,单步调试等。显然这样会增加版本的大小,所以一般在RELEASE版本的编译中会关闭这个开关。而且即使在debug版本调试时,由于代码是按模块编译的,如果你只想调试你想调试的模块,实际你可以把别的模块的-g开关关闭,这样可以减少整个的.o调试版本文件大小。还有一个比较有名的,就是优化选项-O2,工作一段时间后肯定会在某个时候听某个老员工说什么-O2选项没打开,CPU占用率升高。这个-O2(O是字母,优化选项OPTIMIZATION OPTION,不是数值0,呵呵)其实也只是gcc的一个简单的优化选项,其兄弟选项还有-O0、-O1、-O3以及-O等,优化得太多有时候产生的代码其执行结果并不是你想要的,而-O2是一个既能提高代码执行效率又比较安全的选项。那么该在哪里设置这个开关呢?如果你搞懂makefile,你就会发现原来很简单。

我们以前从C语言教材得到的编译和链接是这样的,编译以文件为单位进行的,如.c文件和.s(汇编源文件),最后形成一个.o文件(目标文件),然后多个.o文件再连接成一个可执行文件。一切似乎很简单明了,但这里面隐含了一个重要的细节,而恰恰是这个才是理解编译和链接的关键。就是.o文件是一种可重定位的文件,也就是说可以把.o文件再来一次链接再形成一个.o文件,并可以继续重复这样的操作,这个是靠链接器(linker)的-r选项来实现的,用这个选项链接生成的不是可执行文件(因为这时还有一部分符号没有得到解析,从编译器的术语说就是没有定位),而是生成可重定位输出,也就是说, 生成的输出文件能够再次成为 ld 的输入, 一般称之为不完全(partial) 链接。

GNU的编译工具编译器gcc和ld链接器生成的文件格式如.o以及最终的可执行文件,采用的是一种叫ELF(Executable and linking format)的格式,ELF是x86 Linux系统下的一种常用目标文件(object file)格式,有三种主要类型: …

【阅读全文】