GCC编译器查看C语言编译过程 编译过程预处理预处理器将对源文件中的宏进行展开。编译编译器gcc将c文件编译成汇编文件。汇编汇编器as将汇编文件编译成机器码。链接将目标文件和外部符号进行连接得到一个可执行二进制文件。以一个很简单的01_test.c来探讨这个过程。#include stdio.h #define NUMBER (1 2) int main(void) { int x NUMBER; printf(x:%d\n,x); return 0; }预处理[csylocal compile_test]$ gcc -E -o 01_test.i 01_test.c用cat查看01_test.i的内容如下int main(void) { int x (1 2); printf(x:%d\n,x); return 0; }可以看到文件中宏定义NUMBER出现的位置被(12)替换掉了其它的内容保持不变。2. 编译成汇编代码gcc -S -o 01_test.s 01_test.i通过cat test.s查看01_test.s的内容为汇编代码。[csylocal compile_test]$ cat 01_test.s .file 01_test.c .section .rodata .LC0: .string x:%d\n .text .globl main .type main, function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $32, %esp movl $3, 28(%esp) movl $.LC0, %eax movl 28(%esp), %edx movl %edx, 4(%esp) movl %eax, (%esp) call printf movl $0, %eax leave ret .size main, .-main .ident GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4) .section .note.GNU-stack,,progbits使用汇编器编译成机器码[csylocal compile_test]$ gcc -c -o 01_test.o 01_test.s生成的机器码ELF ? 4 ( U夊冧饍?荄$ ? 婽$塗$?$椟? 擅 x:%d GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4) .symtab .strtab .shstrtab .rel.text .data .bss .rodata .comment .note.GNU-stack 4 - X % d d 0 d 8 0 j - A ? ? Q ? ? ? - 01_test.c main printf 使用链接器把目标文件链接成可执行文件将所有的 .o文件链接起来生成可执行程序。[rootzhifachen test]# gcc -o 01_test.exe 01_test.o运行[csylocal compile_test]$ ./01_test.exe x:3编译过程小结预处理阶段对包含的头文件#include和宏定义#define、#ifdef等进行处理gcc -E-o 01_test.c 01_test.i//-o表示输出为指定文件类型 -E将源文件.c转换为.i编译阶段检查代码规范性、语法错误等在检查无误后把代码翻译成汇编语言gcc -S -o 01_test.i 01_test.s//-S将已预处理的C原始程序.i转换为.s汇编阶段gcc -c -o 01_test.o 01_test.s//将汇编代码编译成机器码链接阶段将目标文件整合起来链接为可执行程序gcc -o 01_test.exe 01_test.o//将机器码(.o)和一些库函数整合成.exegcc常用选项快速编译示例预编译生成已预编译过的C原始程序*.igcc -E gcc_test.c -o gcc_test.i编译生成汇编语言原始程序*.sgcc -S gcc_test.i -o gcc_test.s编译生成目标文件*.ogcc -c -o 01_test.o 01_test.s链接生成可执行程序gcc -o 01_test.exe 01_test.o方法二编译gcc -c gcc_test.c -o gcc_test.o链接gcc -o gcc_test.exe gcc_test.o运行测试程序./gcc_test.exe方法三编译并链接gcc -o gcc_test.exe gcc_test.c运行测试程序[csylocal compile_gcc]# ./gcc_test.exe MAX100 max(3,4)4编译时候传递全局宏定义示例在代码中可以直接使用#define 来定义一个宏然后在代码中引用有时候我们希望通过编译时候决定编译宏内容以及宏是否定义这时候可以通过编译时候 -D 选项来指定。hello.c源码#include stdio.h int main(void) { #ifdef CSY//表示如果定义了CSY即命令行参数传了CSY就执行下面的输出 printf(CSY is defined!\n); #else printf(CSY is not defined!\n); #endif printf(main exit\n); return 0; }条件编译用-D传递如果没有传CSY则执行#else[csylocal compile_gcc]# gcc -o hello hello.c -DCSY [csylocal compile_gcc]# ./hello.exe CSY is defined! main exit

本月热点