一、查看gcc的参数
gcc 在编译程序时可以有很多可选参数。在终端中输入下面的命令,可以查看gcc 的这些可选参数。
gcc --help
在终端中显示的gcc 的可选参数如下所示。进行程序编译时,可以设置下面的这些参数。
用法:gcc [选项] 文件... 选项: -pass-exit-codes:在某一阶段退出时返回最高的错误码 --help:显示此帮助说明 --target-help:显示目标机器特定的命令行选项 -dumpspecs:显示所有内建 spec 字符串 -dumpversion:显示编译器的版本号 -dumpmachine:显示编译器的目标处理器 -print-search-dirs:显示编译器的搜索路径 -print-libgcc-file-name:显示编译器伴随库的名称 -print-file-name=<库>:显示 <库> 的完整路径 -print-prog-name=<程序>:显示编译器组件 <程序> 的完整路径 -print-multi-directory:显示不同版本 libgcc 的根目录 -print-multi-lib:显示命令行选项和多个版本库搜索路径间的映射 -print-multi-os-directory:显示操作系统库的相对路径 -Wa,<选项>: 将逗号分隔的 <选项> 传递给汇编器 -Wp,<选项>:将逗号分隔的 <选项> 传递给预处理器 -Wl,<选项>:将逗号分隔的 <选项> 传递给链接器 -Xassembler <参数>:将 <参数> 传递给汇编器 -Xpreprocessor <参数>:将 <参数> 传递给预处理器 -Xlinker <参数>:将 <参数> 传递给链接器 -combine:将多个源文件一次性传递给汇编器 -save-temps:不删除中间文件 -pipe:使用管道代替临时文件 -time:为每个子进程计时 -specs=<文件>: 用 <文件> 的内容覆盖内建的 specs 文件 -std=<标准>:指定输入源文件遵循的标准 --sysroot=<目录>:将 <目录> 作为头文件和库文件的根目录 -B <目录>:将 <目录> 添加到编译器的搜索路径中 -b <机器>:为 gcc 指定目标机器(如果有安装) -V <版本>:运行指定版本的 gcc(如果有安装) -v:显示编译器调用的程序 -###:与 -v 类似,但选项被引号括住,并且不执行命令 -E:仅作预处理,不进行编译、汇编和链接 -S:编译到汇编语言,不进行汇编和链接 -c:编译、汇编到目标代码,不进行链接 -o <文件>:输出到 <文件> -x <语言>:指定其后输入文件的语言。允许的语言包括c、c++、assembler 等。 以 -g、-f、-m、-O、-W 或 --param 开头的选项将由 gcc 自动传递给其调用的不同子进程。若要 向这些进程传递其他选项,必须使用 -W<字母> 选项。
二、查看编译过程
参数-v 可以查看程序的编译过程和显示已经调用的库。输入下面的命令,在编译程序时输出编译过程。
gcc -v a.c
显示的结果如下所示。
使用内建 specs。 目标:i386-redhat-linux 配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --host=i386-redhat-linux 线程模型:posix gcc 版本 4.1.2 20070925 (Red Hat 4.1.2-33) /usr/libexec/gcc/i386-redhat-linux/4.1.2/cc1 -quiet -v a.c -quiet -dumpbase a.c -mtune=generic -auxbase a -version -o /tmp/cc8P7rzb.s 忽略不存在的目录“ /usr/lib/gcc/i386-redhat-linux/4.1.2/http://www.cnblogs.com/http://www.cnblogs.com/i386- redhat-linux/include” #include "..." 搜索从这里开始: #include <...> 搜索从这里开始: /usr/local/include /usr/lib/gcc/i386-redhat-linux/4.1.2/include /usr/include 搜索列表结束。 GNU C 版本 4.1.2 20070925 (Red Hat 4.1.2-33) (i386-redhat-linux) 由 GNU C 版本 4.1.2 20070925 (Red Hat 4.1.2-33) 编译。 GGC 准则:--param ggc-min-expand=64 --param ggc-min-heapsize=64394 Compiler executable checksum: ab322ce5b87a7c6c23d60970ec7b7b31 a.c: In function ‘main’: a.c:16: 警告:‘main’ 的返回类型不是 ‘int’ as -V -Qy -o /tmp/ccEFPrYh.o /tmp/cc8P7rzb.s GNU assembler version 2.17.50.0.18 (i386-redhat-linux) using BFD version version 2.17.50.0.18-1 20070731 /usr/libexec/gcc/i386-redhat-linux/4.1.2/collect2 --eh-frame-hdr --build-id -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i386-redhat-linux/4.1.2/http://www.cnblogs.com/../crt1.o
从显示的编译过程可知,gcc 自动加载了系统的默认配置,调用系统的库函数完成了程序的编译过程。
三、编译过程的控制
编译过程指的是gcc 对一个程序进行编译时完成的内部处理和步骤。编译程序时会自动完成预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)和链接(Linking)4 个步骤。本节将讲解如何对这4 个步骤进行控制。
3.1编译过程简介
gcc 把一个程序的源文件,编译成一个可执行文件,中间包括很多复杂的过程。可以用图1-1 来表示编译中4 个步骤的作用和关系。
在4 个过程中,每一个操作都完成了不同的功能。编译过程的功能如下所示。
1、预处理:在预处理阶段,主要完成对源代码中的预编译语句(如宏定义define 等)和文件包含进行处理。需要完成的工作是对预编译指令进行替换,把包含文件放置到需要编译的文件中。完成这些工作后,会生成一个非常完整的C 程序源文件。
2、编译:gcc 对预处理以后的文件进行编译,生成以.s 为后缀的汇编语言文件。该汇编语言文件是编译源代码得到的汇编语言代码,接下来交给汇编过程进行处理。汇编语言是一种比C 语言更低级的语言,直接面对硬盘进行操作。程序需要编译成汇编指令以后再编译成机器代码。
3、汇编:汇编过程是处理汇编语言的阶段,主要调用汇编处理程序完成将汇编语言汇编成二进制机器代码的过程。通常来说,汇编过程是将.s 的汇编语言代码文件汇编为.o的目标文件的过程。所生成的目标文件作为下一步链接过程的输入文件。
4、链接:链接过程就是将多个汇编生成的目标文件以及引用的库文件进行模块链接生成一个完整的可执行文件。在链接阶段,所有的目标文件被安排在可执行程序中的适当的位置。同时,该程序所调用到的库函数也从各自所在的函数库中链接到程序中。经过了这个过程以后,生成的文件就是可执行的程序