工欲善其事,必先利其器。要在Linux下写程序,首先要了解基本的工具——gcc/g++/make。 用gcc/g++生成可执行的C或C++程序需要经过四步: 1.预处理程序对源文件(*.c, *.cpp, *.C, *.cxx)等进行宏扩展和条件处理,导入前导文件,生成.i文件(可用gcc -E filename生成,结果输出到标准输出) 2.编译程序将*.i文件中的C或C++源代码转换成汇编代码,生成.s文件(可用gcc -S filename生成) 3.汇编程序将*.s文件中的汇编代码转换成目标代码(机器代码),生成.o文件(可用gcc -c filename生成) 4.连接程序将*.o文件与库文件进行连接,生成可执行程序(可用gcc filename生成,默认输出文件名为a.out) 一、gcc的使用 1.gcc/g++命令格式: gcc [options] filename g++ [options] filename 多个选项要分开写 2.一些常用的选项: gcc -o filename 改变输出文件的文件名,默认生成的可执行文件名为a.out gcc -O0/O1/O2/O3 -O0 表示关闭编译器优化功能,其他三个优化程度不断加深,-O1就等同于-o 二、make的使用 make就是一个gcc/g++的调度器,通过读入一个文件(默认文件名为Makefile或者makefile),执行一组以gcc/g++为主的 shell命令序列。输入文件主要用来记录文件之间的依赖关系和命令执行顺序。 1.Makefile规则的组成:包含一个依赖行和多条以Tab开头的命令行组成 目标1 [目标2...]: [依赖文件列表] [/t 命令] ... 2.规则目标 规则目标分为两种:真实目标和假象目标 (1)真实目标:命令执行后确实生成了该目标 xyz: x.c y.c assemble.o object.a gcc -o xyz x.c y.c z.c assemble.o /usr/local/lib/object.a (2)假象目标:顾名思意,命令执行后确实不生成该目标 作用1:生成多个互不相关的目标 all: object1 object2 object1: ... ... object2: ... ... 作用2:执行一些不生成目标的命令 clean: rm *.o rm *.a 如果目标存在并且为最新,make将拒绝执行规则。因此,为了让假象目标总是执行,需要加上.PHONY前缀: .PHONY clean: ... 3.自动生成规则依赖行: gcc -MM filename 只包含用户头文件 gcc -M filename 包含系统头文件 用>>追加到Makefile中就可以了 4.隐含规则 当规则只有依赖行而没有命令行时,make命令将求助于隐含规则 隐含规则也称后缀转换规则,如.c.o的后缀为.o,表示将*.c文件转换为*.o文件;.s.o后缀为.o,表示将.s文件转换为.o文件;.c后缀为 空,表示将.c文件转换为可执行文件。可以自己定义隐含规则: .SUFFIXES: 清除所有隐含规则 .SUFFIXES: .s .t .l 声明两条隐含规则.s.t和.s.l,注意后缀之间用空格隔开 .s.t: ... .s.l: ... 5.Makefile中的变量 变量用$()进行引用,可以代替编译器名,选项名,文件名,目标名等 内部变量:一类是静态的,如CFLAGS,CPPFLAGS,与普通变量同样使用;一类是动态的,根据规则确定其值,有以下几种: $* 不包括文件扩展名的依赖文件名 $? 比目标文件名新的依赖文件 $@ 目标文件名 $< 当前规则中的依赖文件列表中的第一个文件名 $^ 当前规则中依赖文件列表中的所有文件 6.make命令的使用 使用格式: make [选项] [参数] 其中参数为目标名,如果不制定则默认创建/更新第一个目标 选项有以下几种: 变量赋值,如:make CC=gcc。make命令按如下顺序对变量赋值:内部变量定义,环境变量定义,Makefile文件中的变量定义,make命令行中的定义。以最后赋值 为准。 -e 将上述变量赋值顺序的2、3两项互换 -f 制定输入文件的文件名,默认为Makefile或makefile -r 禁止隐含规则 -n 输出用于创建/更新目标的命令序列,但不真正执行 -I 忽略出错信息 -P 指示make以并行方式一次创建多个目标。可用.MUTEX关键字指示要求串行创建的目标 7.make命令工作方式 读入输入文件,找到要创建/更新的目标规则 检查目标与依赖文件列表的时间戳信息,如果目标文件比依赖文件列表旧,则需要更新。此时继续查找生成依赖文件列表中的文件的目标规则,同样比较时 间戳,依此类推。然后从底层开始更新,最终完成目标的创建/更新。 (责任编辑:IT) |