在使用gcc编译程序时,编译过程可以细分为4个阶段:
1.预处理(Pre-Processing)
2.编译(Compiling)
3.汇编(Assembling)
4.链接(linking)
gcc -v -o main main.c -v:vebose1.预处理(Pre-Processing)
gcc -E main.c -o main.i 命令 /usr/bin/x86_64-linux-gnu-cpp-9 main.c -o main.i 详细过程 [root@Orz 23:40 /mnt/d/linux/c]# whereis cpp cpp: /usr/bin/cpp /usr/lib/cpp /usr/share/man/man1/cpp.1.gz [root@Orz 23:40 /mnt/d/linux/c]# ll /usr/bin/cpp lrwxrwxrwx 1 root root 5 Mar 20 2020 /usr/bin/cpp -> /usr/bin/cpp-9 [root@Orz 23:40 /mnt/d/linux/c]# ll /usr/lib/cpp lrwxrwxrwx 1 root root 21 Nov 16 03:00 /usr/lib/cpp -> /etc/alternatives/cpp* [root@Orz 23:42 /mnt/d/linux/c]# ll /etc/alternatives/cpp lrwxrwxrwx 1 root root 12 Nov 16 03:00 /etc/alternatives/cpp -> /usr/bin/cpp* [root@Orz 23:43 /mnt/d/linux/c]# ll /usr/bin/cpp-9 lrwxrwxrwx 1 root root 22 Aug 8 2020 /usr/bin/cpp-9 -> x86_64-linux-gnu-cpp-9* [root@Orz 23:44 /mnt/d/linux/c]# ll /usr/bin/x86_64-linux-gnu-cpp-9 -rwxr-xr-x 1 root root 1158288 Aug 8 2020 /usr/bin/x86_64-linux-gnu-cpp-9* [root@Orz 23:49 /usr/bin]# ll /usr/bin | grep "gcc" -rwxr-xr-x 1 root root 428 May 7 2006 c89-gcc* -rwxr-xr-x 1 root root 454 Apr 11 2011 c99-gcc* lrwxrwxrwx 1 root root 5 Mar 20 2020 gcc -> gcc-9* lrwxrwxrwx 1 root root 22 Aug 8 2020 gcc-9 -> x86_64-linux-gnu-gcc-9* lrwxrwxrwx 1 root root 8 Mar 20 2020 gcc-ar -> gcc-ar-9* lrwxrwxrwx 1 root root 25 Aug 8 2020 gcc-ar-9 -> x86_64-linux-gnu-gcc-ar-9* lrwxrwxrwx 1 root root 8 Mar 20 2020 gcc-nm -> gcc-nm-9* lrwxrwxrwx 1 root root 25 Aug 8 2020 gcc-nm-9 -> x86_64-linux-gnu-gcc-nm-9* lrwxrwxrwx 1 root root 12 Mar 20 2020 gcc-ranlib -> gcc-ranlib-9* lrwxrwxrwx 1 root root 29 Aug 8 2020 gcc-ranlib-9 -> x86_64-linux-gnu-gcc-ranlib-9* lrwxrwxrwx 1 root root 5 Mar 20 2020 x86_64-linux-gnu-gcc -> gcc-9* -rwxr-xr-x 1 root root 1154192 Aug 8 2020 x86_64-linux-gnu-gcc-9* lrwxrwxrwx 1 root root 8 Mar 20 2020 x86_64-linux-gnu-gcc-ar -> gcc-ar-9* -rwxr-xr-x 1 root root 35464 Aug 8 2020 x86_64-linux-gnu-gcc-ar-9* lrwxrwxrwx 1 root root 8 Mar 20 2020 x86_64-linux-gnu-gcc-nm -> gcc-nm-9* -rwxr-xr-x 1 root root 35464 Aug 8 2020 x86_64-linux-gnu-gcc-nm-9* lrwxrwxrwx 1 root root 12 Mar 20 2020 x86_64-linux-gnu-gcc-ranlib -> gcc-ranlib-9* -rwxr-xr-x 1 root root 35464 Aug 8 2020 x86_64-linux-gnu-gcc-ranlib-9*
使用-E参数可以让gcc在预处理结束后停止编译过程,预处理器(cpp)根据以字符#开头的命令,修改原始的C程序,把宏定义进行替换。
另外可以使用gcc main.c -I 头文件的路径 -o main
2.编译(Compiling)gcc -S main.i -o main.s 命令 /usr/lib/gcc/x86_64-linux-gnu/9/cc1 -quiet -v -imultiarch x86_64-linux-gnu main.c -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase main -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o main.s 详细过程 [root@Orz 00:09 /mnt/d/linux/c]# ll /usr/lib/gcc/x86_64-linux-gnu/9/cc1 -rwxr-xr-x 1 root root 25654616 Aug 8 2020 /usr/lib/gcc/x86_64-linux-gnu/9/cc1
编译器(cc1)将文本文件main.i文件看成是预处理后的C语言源代码,再翻译成文本文件main.s,它包含一个汇编语言程序。
3.汇编(Assembling)gcc -c main.s -o main.o 命令 /usr/bin/x86_64-linux-gnu-as -v --64 -o main.o main.s 详细过程 [root@Orz 00:03 /mnt/d/linux/c]# whereis as as: /usr/bin/as /usr/share/man/man1/as.1.gz [root@Orz 00:04 /mnt/d/linux/c]# ll /usr/bin/as lrwxrwxrwx 1 root root 19 Oct 20 19:09 /usr/bin/as -> x86_64-linux-gnu-as* [root@Orz 00:05 /mnt/d/linux/c]# ll /usr/bin/x86_64-linux-gnu-as -rwxr-xr-x 1 root root 696624 Oct 20 19:09 /usr/bin/x86_64-linux-gnu-as*
汇编器(as)将main.s翻译成机器语言指令,把这些指令打包成一种可重定位目标程序的格式,并将结果保存在目标文件main.o中。main.o文件是一个二进制文件,它的字节编码是机器语言指令而不是字符,如果我们在文本文件中打开main.o文件,看到的将是一堆乱码。
4.链接(linking)gcc -v main.o -o main 可以看见详细过程 命令 /usr/lib/gcc/x86_64-linux-gnu/9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccZ7lCdk.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o main /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/9 -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/9/../../.. main.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o 1779 whereis ld 1780 ll /usr/bin/ld 1781 ll /usr/bin/x86_64-linux-gnu-ld 1782 ll /usr/bin/x86_64-linux-gnu-ld.bfd
链接器(ld)负责处理合并目标代码,生成一个可执行目标文件,可以被加载到内存中,由系统执行
GCC基本使用方法、常用指令gcc [options] [filenames] -o [outputfilename] [options] -c:通知gcc取消连接步骤,即编译源码并在最后生成目标文件 -Dmacro:定义指定的宏,使它能够通过源码中的#ifdef进行检验 -E:不经过编译预处理程序的输出而输送至标准输出 -g3:获得有关调试程序的详细信息,它不能与-o选项联合使用 -Idirectory:在包含文件搜索路径的起点处添加指定目录 -llibrary:提示连接程序在创建最终可执行文件时包含指定的库 -O、-O2、-O3:将优化状态打开,该选项不能与-g选项联合使用 -S:要求编译程序生成来自源代码的汇编程序输出 -v:启动所有警报 .h:预处理文件(标头文件) -Wall:在发生警报时取消编译操作,即将警报看作是错误 -w:禁止所有的报警
(2条消息) GCC_人生代码 ---- 公众号-CSDN博客https://blog.csdn.net/qq_36772866/article/details/91126586?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163695872216780357234289%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163695872216780357234289&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-4-91126586.first_rank_v2_pc_rank_v29&utm_term=gcc&spm=1018.2226.3001.4187



