gcc命令行

GCC 的意思也只是 GNU C Compiler 而已。

经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言;它现在还支持 Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL语言,以及支持函数式编程和逻辑编程的 Mercury 语言,等等。而 GCC 也不再单只是 GNU C 语言编译器的意思了,而是变成了 GNU Compiler Collection 也即是 GNU 编译器家族的意思了。

另一方面,说到 GCC 对于操作系统平台及硬件平台支持,概括起来就是一句话:无所不在。

简单编译

```c\r\n//test.c\r\n#include <stdio.h>\r\nint main(void)\r\n{\r\n    printf(\"Hello World!\\n\"); // 注释\r\n    return 0;\r\n}\r\n```\r\n\r\n编译输出\r\n\r\n```shell\r\ngcc test.c -o test\r\n```\r\n\r\n> 实质上,上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编 (Assembly)和连接(Linking)。\r\n\r\n### 编译过程\r\n\r\n#### 预处理\r\n\r\n> 在C里预处理只是简单的头文件替换、宏替换 和 删除注释\r\n\r\n```shell\r\n  gcc -E test.c -o test.i\r\n#或\r\n  gcc -E test.c\r\n```\r\n\r\n结果如下:\r\n\r\n```c\r\n# 1 \"main.c\"\r\n# 1 \"<built-in>\"\r\n# 1 \"<command-line>\"\r\n# 1 \"main.c\"\r\n\r\n# 省略接近 800 行代码\r\n\r\n  __attribute__ ((__dllimport__)) size_t __attribute__((__cdecl__)) _fread_nolock_s(void *_DstBuf,size_t _DstSize,size_t _ElementSize,size_t _Count,FILE *_File);\r\n# 992 \"C:/Strawberry/c/i686-w64-mingw32/include/stdio.h\" 2 3\r\n\r\n# 1 \"C:/Strawberry/c/i686-w64-mingw32/include/_mingw_print_pop.h\" 1 3\r\n# 994 \"C:/Strawberry/c/i686-w64-mingw32/include/stdio.h\" 2 3\r\n# 3 \"main.c\" 2\r\nint main(void)\r\n{\r\n    printf(\"Hello World!\\n\");\r\n    return 0;\r\n}\r\n```\r\n\r\n#### 编译为汇编代码\r\n\r\n> 预处理之后,可直接对生成的test.i文件编译,生成汇编代码\r\n\r\n```c\r\ngcc -S test.i -o test.s\r\n```\r\n\r\n结果如下\r\n\r\n```c\r\n.file\"main.c\"\r\n.def___main;.scl2;.type32;.endef\r\n.section .rdata,\"dr\"\r\nLC0:\r\n.ascii \"Hello World!\\0\"\r\n.text\r\n.globl_main\r\n.def_main;.scl2;.type32;.endef\r\n_main:\r\npushl%ebp\r\nmovl%esp, %ebp\r\nandl$-16, %esp\r\nsubl$16, %esp\r\ncall___main\r\nmovl$LC0, (%esp)\r\ncall_puts\r\nmovl$0, %eax\r\nleave\r\nret\r\n.ident\"GCC: (i686-posix-sjlj, built by strawberryperl.com project) 4.9.2\"\r\n.def_puts;.scl2;.type32;.endef\r\n```\r\n\r\n#### 汇编\r\n\r\n> 对于生成的汇编代码文件test.s,gas汇编器负责将其编译为目标文件,如下:\r\n\r\n```c\r\ngcc -c test.s -o test.o\r\n```\r\n\r\n#### 连接\r\n\r\n> gcc连接器是gas提供的,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。附加的目标文件包括静态连接库和动态连接库。\r\n对于之前生成的test.o,将其与C标准输入输出库进行连接,最终生成程序test\r\n\r\n### gcc 命令行\r\n\r\n|参数|说明|\r\n|:--|:--|\r\n|-E|预处理|\r\n|-S|编译|\r\n|-c|汇编|\r\n|-o|指定输出文件名|\r\n|-g|产生gdb调试的必要信息(后加1、2、3控制调试信息量)|\r\n|-g1|不包含局部变量和与行号有关的调试信息,只能够用于回溯跟踪和堆栈转储|\r\n|-g2|产生的调试信息包括:扩展的符号表、行号、局部或外部变量信息(默认g2)|\r\n|-g3|包含级别2中的所有调试信息以及源代码中定义的宏|\r\n|-O|对程序进行优化编译、链接,编译过程慢|\r\n|-O2|比-O更好的优化编译、链接。速度更慢|\r\n|-p|会将剖析(Profiling)信息加入到最终生成的二进制代码中,利于优化性能|\r\n|-v|输出gcc工作的详细过程|\r\n|-pedantic|帮助程序员发现一些不符合 ANSI/ISO C标准的代码|\r\n|-Wall|能够使GCC产生尽可能多的警告信息|\r\n|-Werror|GCC会在所有产生警告的地方停止编译|\r\n|–I|指定头文件路径|\r\n|–L|指定库文件路径|\r\n|–l|指定编译时依赖的库文件|\r\n|-static|强制编译时使用静态链接库(默认gcc优先使用动态库)|\r\n|-shared|生成一个共享的目标文件,能与其他目标一起链接生成可执行文件|\r\n\r\n### 静态库链接时搜索路径顺序:\r\n\r\n1. ld会去找GCC命令中的参数-L\r\n2. 再找gcc的环境变量LIBRARY_PATH\r\n3. 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的\r\n\r\n动态链接时、执行时搜索路径顺序:\r\n\r\n1. 编译目标代码时指定的动态库搜索路径\r\n2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径\r\n3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径\r\n4. 默认的动态库搜索路径/lib\r\n5. 默认的动态库搜索路径/usr/lib\r\n\r\n### GCC 环境变量\r\n\r\n- LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径\r\n- LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径\r\n


评论列表: (共0条评论)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。