一、gcc和g++的简介
GCC(GNU Compiler Collection)是一个开源的编译器集合,支持多种编程语言,其中 gcc 和 g++ 是最常用的两种编译器。
gcc:用于编译 C 语言程序。它是编译 C 代码的主要工具,也能处理一些其他语言(如 Objective-C、Fortran 等),但默认用于 C。
gcc source.c -o output
//这将编译 source.c 并生成可执行文件 output。
g++:用于编译 C++ 程序。它不仅能编译 C++ 代码,还会自动链接 C++ 标准库(如 libstdc++)。
g++ source.cpp -o output
//这将编译 source.cpp 并生成可执行文件 output。
编译语言:gcc 用于 C 语言,g++ 用于 C++ 语言。默认链接库:g++ 自动链接 C++ 标准库,gcc 需要手动处理。选择编译器时,通常根据文件扩展名来决定:.c 文件用 gcc,.cpp 文件用 g++,或者根据需要明确指定编译器。
二、编译和链接
在我们聊gcc和g++具体操作之前,先聊一聊编程语言变为二进制代码的编译与链接的过程。
预处理
首先是预处理阶段,在这个阶段会展开所有宏定义、文件包含、条件编译、删除所有注释等操作。预处理的本质就是修改编辑我们的文本代码。
gcc -E code.c -o code.i
//选项“-E”,该选项的作⽤是让 gcc 在预处理结束后停⽌编译过程。
//选项“-o”是指⽬标⽂件,“.i”⽂件为已经过预处理的C原始程序。
编译
生成汇编代码
gcc -S code.i -o code.s
//⽤⼾可以使⽤“-S”选项来进⾏查看,该选项只进⾏编译⽽不进⾏汇编,⽣成汇编代码。
汇编
生成机器可以识别的二进制代码。
gcc -c code.s -o code.o
//读者在此可使⽤选项“-c”就可看到汇编代码已转化为“.o”的⼆进制⽬标代码了
链接
生成可执行文件或者库文件。
之前的一篇文章:详细讲过这一过程。
三、动静态库和动静态链接
上边的编译和链接过程,从预处理到编译到汇编再到链接,前三步都好理解。可以简单理解为把我们写的代码变为二进制机器语言让计算机能够执行。但是理解第四步链接之前就要先理解一下动态链接和静态链接。
库是一套方法或者数据集,为我们的开发提供最基本的接口,加速我们的二次开发。动态链接静态链接与动静态库密切相关。我们自己的程序会使用库中的方法。举个例子,当我们的程序有一个函数,这个函数的方法是库提供给我们的,这方法并不用让我们自己进行实现,我们的程序能在库中找到这个方法然后链接起来,进而形成可执行程序。
在进行链接的时候,分为动态链接和静态链接。如果这个方法是动态库提供的就会进行动态链接,反之如果方法是静态库提供的就会进行静态链接。
gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件。
四、常用选项
- E 只激活预处理,这个不生成文件,你需要把它重定向到⼀个输出文件里面
- -S 编译到汇编语言不进行汇编和链接
- -c 编译到目标代码
- -o 文件输出到文件
- -static 此选项对生成的文件采用静态链接
- -g 生成调试信息。GNU 调试器可以利于该信息。
- -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
- -O0 -O1 -O2 -O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
- -w 不生成任何警告信息。
- -Wall 生成所有警告信息。
五 、调试器 gdb/cgdb使用
程序的发布方式有两种, debug 模式和 release 模式, Linux gcc/g++ 出来的二进制程序,默认是 release 模式。
要使用gdb调试,必须在源代码生成⼆进制程序的时候, 加上 -g 选项,如果没有添加,程序无法被编译
$ gcc mycmd.c -o mycmd # 默认模式,不⽀持调试
$ file mycmd
mycmd: ELF -bit LSB shared object, x86-, version 1 (SYSV), dynamically
linked, interpreter /lib/ld-linux-x86-.so.2,
BuildID[sha1]=82f5cbaada10a9987d9f325384861a88d278b160, for GNU/Linux
3.2.0, not stripped
$ gcc mycmd.c -o mycmd -g # debug模式
$ file mycmd
mycmd: ELF -bit LSB shared object, x86-, version 1 (SYSV), dynamically
linked, interpreter /lib/ld-linux-x86-.so.2,
BuildID[sha1]=3d5a2317809ef86c7827e9199cfefa622e3c187f, for GNU/Linux
3.2.0, with debug_info, not stripped
上⾯的基本调试还是麻烦,虽然是黑屏,但是还是想看到代码调试
• 推荐安装cgdb:
• Ubuntu: sudo apt-get install -y cgdb
• Centos: sudo yum install -y cgdb
常用使用
开始: cgdb 可执行文件
退出: ctrl + d 或 quit 调试命令