gcc/g++工具的使用
文章目录
一、程序执行的四个过程
1.预处理
gcc -E test.c -o test.i
- 头文件的展开
- 对define等进行替换
- 处理条件编译指令
- 删除所有注释
gcc : 使用gcc工具来编译代码
-E : 表示让代码在完成预处理后停下来,不再继续往后编译
-o : 形成临时文件的名称
通过我们之前学的命令行指令vs
可以明显的看出,完成了展开头文件、删除注释、处理条件编译等操作。
2.编译
gcc -S test.i -o test.s
- 语法分析
- 词法分析
- 语义分析
- 符号汇总
S : 从现在开始,进行程序的翻译,做完编译工作,变成汇编之后,就停下来
可以看到代码转变为了汇编语言。
3.汇编
gcc -c test.s -o test.o
-c:表示让代码在完成编译后停下来,不再继续往后编译
汇编产生的文件一般以.o为后缀
编译阶段生成汇编代码转成计算机可以识别的二进制目标代码,.o 文件被称为可重定向二进制目标文件。
命令行输入od test.o
汇编得到的二进制目标文件使用一般的文本编辑器打开时是一堆我们看不懂的符号 (与符号的编码有关 – utf-8),我们可以使用 od 指令以指定格式来打开它 (默认是以八进制打开)。
4.链接
gcc test.o
链接的过程,形成了一个可执行程序。
这几个步骤刚好和键盘上的ESC很相似,但是只有-c
选项是小写的。
三个命令顺序为ESc
。
二、链接方式和函数库
在刚刚的操作中,printf
是调用的c语言函数库中的函数,并不是我们自己实现的,而是别人写好,我们直接拿来用的。只有当链接时,我们的代码才会和库里对应的实现相关联。
c标准库的位置
ls /lib64/libc*
我们平时说的装环境就是需要安装语言的静态和动态库,这样才能正常利用库里面的函数进行代码的编译处理。
链接的本质是我们在调用库函数时如何与标准库相关联的问题
1.动态链接和静态链接
动态链接是指执行代码时,如果遇到库函数调用就跳转到动态库中对应函数的定义处,然后执行该函数,执行完毕后再跳转回原程序并继续往下执行。
优点:节省资源
缺点:库一旦丢失,所有相关程序失效
静态链接则是直接将本程序内部要使用的库函数从对应的静态库中拷贝一份过来。
优点:不依赖任何库,可以独立运行
缺点:非常浪费资源
2.动态库和静态库
- 在Linux下,我们可以使用 “file” 指令来辨识文件类型,使用 “ldd” 来打印或者查看程序运行所需的共享库。
- 动态库在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。
- 动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。
- gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件。
- 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。
- 其后缀名一般为“.a
默认生成静态链接
gcc test.c -o mytest -static
由于静态链接生成的可执行程序非常大,所以我们一般推荐使用动态链接。
Linux下一般都使用的动态链接,所以静态链接的库需要我们进行下载。
sudo yum install -y glibc-static
sudo yum install -y libstdc++-static
不难看出静态链接的可执行程序比动态链接的可执行程序大了很多倍。
三、gcc/g++的基本使用
1.安装
sudo yum install -y gcc-c++
sudo yum install -y libstdc++-static//安装C++静态库
2.使用
gcc/g++的使用和之前使用的方法相同,当然也可以直接生成可执行程序。
gcc test.c -o mytest1
g++ test.cpp -o mytest2