购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.3 Linux环境编程入门

1.3.1 GCC介绍

通常所说的GCC是GUN Compiler Collection的简称,除了编译程序之外,它还包含其他相关工具,所以它能把易于人类使用的高级语言编写的源代码构建成计算机能够直接执行的二进制代码。GCC是Linux平台下最常用的编译程序,它是Linux平台编译器的事实标准。同时,在Linux平台下的嵌入式开发领域,GCC也是用得最普遍的一种编译器。GCC之所以被广泛采用,是因为它能够支持各种不同的目标体系结构。例如,它既支持基于宿主的开发(简单讲就是要为某平台编译程序,就在该平台上编译),也支持交叉编译(即在A平台上编译的程序是供平台B使用的)。目前,GCC支持的体系结构有四十余种,常见的有X86系列、Arm、PowerPC等。同时,GCC还能运行在不同的操作系统上,如Linux、Solaris、Windows等。

GCC是一个基于命令行的程序,可以把C、C++源程序编译、链接生成可执行程序。其基本的命令行格式为:

其中,-o选项用来指定生成的可执行文件的名字为test,如果不使用命令行选项指定输出文件名,则默认生成名字为a.out的可执行文件。在Linux系统中,可执行文件没有统一的后缀,系统从文件的访问属性来区分是否是可执行文件。而GCC通过输入文件名的后缀来区别文件的类别,下面是部分GCC遵循的规则。

(1).c为后缀的文件,C语言源代码文件。

(2).a为后缀的文件,是由目标文件构成的档案库文件。

(3).h为后缀的文件,是程序所包含的头文件。

(4).i 为后缀的文件,是已经预处理过的C源代码文件。

(5).o为后缀的文件,是编译后的二进制目标文件。

(6).s为后缀的文件,是经过预处理的汇编语言源代码文件。

(7).S为后缀的文件,是汇编语言源代码文件。

关于GCC的常用命令行选项,将在后续交叉编译器的使用章节中介绍。

1.3.2 GNU Make 基本语法

几乎每一个开发平台都有自己的工程管理工具,用来对工程的编译过程进行控制。在Linux下,通常使用GNU的make工具来构建一个自己的工程。可以试想一下,有一个成百上千个源文件的代码构成的项目,如果其中只有一个或少数几个文件进行了修改,如果再从头到尾将每一个文件都重新编译,则是个比较烦琐的过程。为此,引入了Make工程管理器的概念,工程管理器管理较多的文件,它是自动管理器,能根据文件时间自动发现更新过的文件而减少编译的工作量,同时通过读入Makefile文件来执行大量的编译工作。

要使用make工具,我们需要在执行make命令的目录下有一个Makefile文件,M可以大写或者小写,如果该目录下同时存在Makefile和makefile两个文件,则优先使用makefile文件。当然,我们也可以使用命令行的选项指定make命令使用哪个文件作为要读取的文件。

Makefile文件由一个或者多个规则组成,规则由目标、依赖和命令组成,格式如下。

必须注意的是,在写command命令行的时候,必须要在前面按Tab键,一个规则的命令可以有一个,也可以有多个。

例如,有Makefile文件,内容如下。

我们可以使用make [目标名]来读取Makefile文件的对应规则。如果make后面不跟目标,则读取该Makefile文件的第一个目标。

对于该Makefile文件,执行make命令时,程序处理过程如下。

(1)make程序首先读到第1行的目标文件main.exe和它的两个依赖文件main.o和func.o;然后比较文件main.exe和main.o/func.o的产生时间,如果main.exe比main.o/func.o旧,则执行第2条命令,以产生目标文件main.exe。

(2)在执行第2行的命令前,首先查看makefile中的其他定义,看有没有以第1行main.o和func.o为目标文件的依赖文件,如果有,继续按照(1)、(2)的方式匹配下去。

(3)根据(2)的匹配过程,make程序发现第3行有目标文件main.o依赖于main.cpp,则比较目main.o与它的依赖文件main.cpp的文件新旧,如果main.o比main.cpp旧,则执行第4行的命令以产生目标文件main.o。在执行第4条命令时,main.cpp在文件makefile不再有依赖文件的定义,make程序不再继续往下匹配,而是执行第4条命令,产生目标文件main.o。

(4)目标文件func.o按照上面同样的方式判断产生。

(5)执行(3)、(4)产生完main.o和func.o以后,则第2行的命令可以顺利地执行了,最终产生了第1行的目标文件main.exe。

如表1.17所示是make命令的常用命令行选项。

表1.17 make命令的常用命令行选项

1)Makefile中特殊处理与伪目标

.PHONY是Makefile文件的关键字,表示它后面列表中的目标均为伪目标,伪目标能保证该规则的命令一定会被执行。格式如下。

在命令前面可以加“@”字符表示执行make时,在终端上不打印这条命令。

伪目标通常用在清理文件、强制重新编译等情况下。

示例:main.c函数,func.c函数为前面计算+,-,*,/运算的程序

保存退出,注意,和shell编程相同,在Makefile中,也用“#”号表示注释。

再执行下面的命令。

如果不用系统默认的文件名Makefile,而是用户随便起的一个名字,如果#vi Makefile11,则make 后面必须要加上 -f Makefile11。例如,

2)变量、规则与函数

随着软件项目的变大、变复杂,源文件也越来越多,如果采用前面的方式写Makefile文件,将会使Makefile也变得复杂而难于维护。通过make支持的变量定义、规则和内置函数,可以写出通用性较强的Makefile文件,使得同一个Makefile文件能够适应不能的项目。

(1)变量,即用来代替一个文本字符串。

① 定义变量的两种方法如下。

② 使用变量的一般方法如下。

示例如下。

③ 变量类型。

变量分为用户自定义变量、预定义变量、自动变量、环境变量。其中,自动变量指在使用的时候,自动用特定的值替换。

常用的变量如表1.18所示。

表1.18 常用的变量

用自动变量的示例如下。

预定义变量指内部事先定义好的变量,但是它的值是固定的,并且有些的值是为空的。

AR:库文件打包程序默认为ar。

AS:汇编程序,默认为as。

CC:c编译器默认为cc。

CPP:c预编译器,默认为$(CC) -E。

CXX:c++编译器,默认为g++。

RM:删除,默认为rm -f。

ARFLAGS:库选项,无默认。

ASFLAGS:汇编选项,无默认。

CFLAGS:c编译器选项,无默认。

CPPFLAGS:c预编译器选项,无默认。

CXXFLAGS:c++编译器选项。

根据内部变量,可以将makefile改写为如下所示的程序。

(2)规则分为普通规则、隐含规则、模式规则。

① 隐含规则://*.o文件自动依赖*.c或*.cc文件,所以可以省略main.o:main.cpp等。

② 模式规则:通过匹配模式找字符串,%匹配1或多个任意字符串。

%.o: %.cpp任何目标文件的依赖文件是与目标文件同名的并且扩展名为.cpp的文件。

另外,还可以指定将*.o、*.exe、*.a、*.so等编译到指定的目录中。

注意,当OBJS里面有多项的时候,此时$(DIR)$(OBJS)只能影响到OBJS中的第一个,后面的全部无效,因此需要全部列出来。

1.3.3 Makefile 通用模块

Makefile里还可以有函数,下面是常用的三个函数。

(1)wildcard搜索当前目录下的文件名,展开成一列所有符合由其参数描述的文件名,文件间以空格间隔。SOURCES = $(wildcard *.cpp)把当前目录下所有的“.cpp”文件存入变量 SOURCES 里。

(2)字符串替换函数:$(patsubst要查找的子串,替换后的目标子串,源字符串)。将源字符串(以空格分隔)中的所有要查找的子串替换成目标子串,如OBJS=$(patsubst %.cpp,%.o,$(SOURCES))把SOURCES中的“.cpp”替换为'.o' ,然后把替换后的字符串存入变量OBJS。

(3)$(addprefix 前缀,源字符串)函数把第二个参数列表的每一项前缀上第一个参数值。

下面是一个较为通用的Makefile模块。 PinZJmcqNmvVIUY9RR59+NHyIMsq9OA9xUPXigYeC73iaU9nMU/9UPtStMzwsycg

点击中间区域
呼出菜单
上一章
目录
下一章
×