工欲善其事,必先利其器。要在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命令工作方式
    读入输入文件,找到要创建/更新的目标规则
    检查目标与依赖文件列表的时间戳信息,如果目标文件比依赖文件列表旧,则需要更新。此时继续查找生成依赖文件列表中的文件的目标规则,同样比较时间戳,依此类推。然后从底层开始更新,最终完成目标的创建/更新。