前篇文章写的是文本的编辑器,只提供编写代码的vim
【Linux】vim快捷键 + 配置_Rinne’s blog-CSDN博客
本篇介绍,代码的编译器,gcc/g++
一、gcc的使用
用来编译c语言程序的编译器
**翻译环境:**在这个环境中源代码被转换为可执行的机器指令
**执行环境:**它用于切实执行代码
1. 翻译环境的四个步骤
翻译阶段:
- 预处理(进行宏替换)
- 编译(生成汇编)
- 汇编(生成机器可识别的二进制代码)
- 链接(生成可执行文件或库文件)
2. 预处理
预处理:相当于根据预处理指令组装新的C/C++程序。生成
文件(.i)
经过预处理,会产生一个**
没有头文件(都已经被展开了)、宏定义(都已经替换了),没有条件编译指令(该屏蔽的都屏蔽掉了),没有特殊符号的输出文件,去注释
,这个文件的含义同原本的文件无异**,只是内容上有所不同。
gcc -E test1.c
翻译到预处理阶段停止,并把结果打印到显示器上,但不会有目标文件
-o
即生成对应的目标文件
gcc -E test1.c -o test1.i
查看后会显示编译结果
3. 编译
编译:将预处理完的文件逐一进行一系列**
词法分析、语法分析、语义分析及优化后
**,产生相应的汇编代码文件。生成汇编代码文件(.s)
编译是针对单个文件编译的,
只校验本文件的语法是否有问题
,不负责寻找实体。
gcc -S test1.i -o test1.s
从上一步执行到编译阶段结束
4. 汇编
汇编阶段:对汇编代码进行汇编操作,将汇编代码转化成二进制代码,生成符号表并且生成
目标文件(类型linux/vs .o/.obj)
也称作,生成可重定位目标文件
gcc -c test1.s -o test1.o
不认识的乱码,如果想看二进制
od test1.o
即使已经形成了二进制文件,但仍然不可执行,缺少链接的过程
5. 链接
**链接:**通过链接器将一个个目标文件(或许还会有库文件libc.a, libc,os)链接在一起生成一个完整的可执行程序。 形成
.exe
文件链接程序的主要工作就是将有关的目标文件彼此相连接,也就是将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。
**在此过程中会发现被调用的函数未被定义。**需要注意的是,链接阶段只会链接调用了的函数/全局变量,如果存在一个不存在实体的声明(函数声明、全局变量的外部声明),但没有被调用,依然是可以正常编译执行的。
gcc test1.c 这里的文件可以为前3个步骤的结束后任何一个文件
查看可执行程序所依赖的链接库
ldd a.out
linux标准库名称是libc
linux中
-
静态库 以.a结尾
静态链接:库中有关代码拷贝,进可执行程序中
-
动态库 以.so结尾
动态链接:程序发现此函数不是这个文件里,但知道另外一个库包含,去库里面找然后调用
-
得出结论:gcc默认以动态链接方式链接库
[rinne@VM-16-8-centos ~]$ file test1
test1: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=49e67c7d4761df28cc570955ff1b508caa676f08, not stripped
用静态链接试试
gcc test1.c -o test1_static -static
发现没有 -lc指令,yum自己装一个
sudo yum install glibc-static
安装完成之后继续
不难发现test1的静态库体积要很大,因为是把库里面东西拷贝进来了,虽然动态库轻便,但静态库的可移植性强
可以发现,前三个指令组合起来就是电脑键盘左上角的**ESC
**
而文件结尾的字母,组合起来就是iso,一般很多镜像文件的文件结尾比如
二、g++的使用
g++用来编译c++
因为c++兼容c,必然,g++也能编译gcc
基本的使用方法和gcc相同