gcc/g++介绍
概述
gcc
和g++
都是GNU
(组织)的一个编译器
区别
- 后缀为.c的文件gcc把它当做c程序,g++当做c++程序。
- 后缀为c++的两者都当做c++程序。
其他
- 对于
cpp
程序,无论gcc
或者是g++
编译阶段都是相同的- 都是用的
gcc
进行编译 - 但是在链接阶段
gcc
不能自动和c++
程序使用的库连接
如果使用的话,形如下:gcc helloworld.cpp -lstdc++ -o helloworld
- 都是用的
- 所以我们通常用
g++
来进行连接(g++
会自动连接c++
常用库),所以为了使用方便对于cpp
程序干脆编译链接统统都使用g++
- 这样就给人一种错觉,好像
cpp
只能用g++
编译
- 这样就给人一种错觉,好像
gcc/g++作用
- 将
C/C++
源代码编译成机器可识别的指令
gcc/g++编译过程
- 预处理
- 在预处理阶段,编译器处理源代码中的预处理指令(以
#
开头的指令),包括宏定义、文件包含和条件编译等 gcc -E test.c -o test.i
产生一个预处理后的文件(.i
文件 )
- 在预处理阶段,编译器处理源代码中的预处理指令(以
1 2 3 4 |
#define MAX 100 int arr[MAX]; int arr[100]; |
1 2 3 4 5 6 |
#include <iostream> //预处理后会将 <iostream> 的内容插入到该指令的位置 // 条件编译 // 处理 #ifdef、#ifndef、#if 等条件编译指令,根据条件编译或忽略某些代码段 |
-
编译
- 在编译阶段,编译器将预处理后的源代码翻译成汇编代码
- 具体如下:
- 语法分析:检查源代码的语法是否合法,构建抽象语法树(
AST
) - 语义分析:检查语义错误(例如,类型检查、作用域解析等)
- 中间代码生成:将源代码翻译成一种中间表示(如三地址码)
- 优化:对中间代码进行优化,以提高生成代码的效率
- 汇编代码生成:将中间代码翻译成目标机器的汇编代码
gcc -S test.i -o test.s
产生一个汇编程序文件(.s
文件 )
-
汇编
- 在汇编阶段,汇编器将汇编代码翻译成机器代码(二进制指令),生成目标文件
- 主要任务如下:
- 翻译汇编代码:将汇编代码中的每条指令翻译成对应的机器指令
- 符号解析:解析汇编代码中的符号,并为每个符号分配内存地址
- 生成目标文件:将机器代码和符号表打包成目标文件
gcc -c test.s -o test.o
产生一个目标文件(.o
文件)
-
链接
- 在链接阶段,链接器将多个目标文件(包括程序的目标文件和库文件)合并成一个可执行文件,解析符号引用,并处理重定位
- 主要任务如下:
- 符号解析:解析并匹配所有目标文件中的符号引用,确保每个符号都有定义
- 重定位:调整代码和数据地址,以便在可执行文件中正确运行
- 生成可执行文件:将所有目标文件和库文件合并,生成最终的可执行文件
gcc test.o -o test
产生一个可执行文件
gcc/g++编译器常用选项
-
基本选项
-c
只生成目标文件(.o
文件),不链接-E
只进行预处理,不编译,生成预处理后的(.i
)文件-S
生成汇编文件(.s
)文件-o
指定输出的可执行文件名称
-
警告选项
-Wall
给出所有有用的警告信息,有利于排查问题-Werror
在发生警告时取消编译操作,即将警报看作是错误-w
禁止警告,有时会隐藏程序中的错误-W
给出额外更详细的警告
-
优化选项
-Idirectory
向GCC
的头文件搜索路径中添加新的目录-Ldirectory
向GCC
的库文件搜索路径中添加一个行的目录-llibrary
提示连接程序在创建可执行文件时包含指定的库文件-static
强制使用静态库-shared
强制使用共享库
-
其他选项
-xlanguage
指定输入文件的编程语言-v
显示编译器的版本号-g
获得有关调试程序的详细信息-ansi
支持符合ansi
彼岸准的c
程序
静态库/动态库
- 在
linux
系统中静态库的扩展名为.a
,动态库的扩展名是.so
- 静态库是在每个程序进行链接的时候将库在目标程序中进行一次拷贝,当目标程序生成的时候,程序可以脱离库文件单独运行,换言之原来的文件即使删除程序还是会正常工作
- 共享库可以被多个应用程序共享,实在程序运行的时候进行动态的加载,因此对于每个应用程序来说,即使不再使用某个共享库,也不应该将其删除,因为其他的引用程序可能需要这个库
示例
1 2 3 4 5 6 |
#include <stdio.h> int main() { printf("hello world"); return 0; } |
- 预处理
$ gcc -E hello.c -o hello.i
- 编译
$ gcc -S hello.i -o hello.s
- 汇编
$ gcc -c hello.s -o hello.o
- 链接
$ gcc hello.o -o hello
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Linux 线程的同步与互斥03/31
- ♥ Bash Shell 命令09/04
- ♥ 51CTO:Linux C++网络编程五08/20
- ♥ Linux_ 命令大全 系统管理03/16
- ♥ Linux 高性能服务器编程:I/O复用一12/11
- ♥ 编译器扩展语法:一07/06