目录
Linux编译器-gcc/g++使用
No.1 背景知识
No.2 预处理(进行宏替换)
No.3 编译(生成汇编)
No.4 汇编(生成机器可识别代码)
No.5 动态链接过程
No.6 gcc选项
Linux编译器-gcc/g++使用
No.1 背景知识
-
预处理(进行宏替换)
-
编译(生成汇编)
-
汇编(生成机器可识别代码)
-
连接(生成可执行文件或库文件)
由这4中编译方式:我们测试一段代码看一下,是否可以得到我们想要的结果。
No.2 预处理(进行宏替换)
// 预处理 [ShaXiang@VM-8-14-centos ~]$ gcc -E Test.c -o Test.i // -E: 从现在开始,进行程序的编译,当你将预处理完后,就停下来。 // -o:指名形成的临时文件名称.(后缀为.i)文件
No.3 编译(生成汇编)
// 编译 - 翻译成汇编语言 [ShaXiang@VM-8-14-centos ~]$ gcc -S Test.c -o Test.s // -S:从现在开始,进行程序的翻译为汇编,做完翻译工作,就停下来,不要继续往下走了。 // -o:指名形成的临时文件名称.(后缀为.s)文件
No.4 汇编(生成机器可识别代码)
// 将汇编编程二进制目标文件 [ShaXiang@VM-8-14-centos ~]$ gcc -c Test.s -o Test.o // -c:从在在开始,程序进行翻译,昨晚汇编工作,编程可重定向目标二进制,就停下来。 // -o:指名形成的临时文件名称.(后缀为.o)文件 // 可以使用[ShaXiang@VM-8-14-centos ~]$ od Test.o 查看二进制代码 0000000 042577 043114 000402 000001 000000 000000 000000 000000 0000020 000001 000076 000001 000000 000000 000000 000000 000000 0000040 000000 000000 000000 000000 001630 000000 000000 000000 0000060 000000 000000 000100 000000 000000 000100 000015 000014 0000100 044125 162611 000277 000000 164000 000000 000000 000277
// 链接 - 将你写的代码和c标准库中的代码合起来 [ShaXiang@VM-8-14-centos ~]$ gcc Test.o // 连接为可执行程序。 [ShaXiang@VM-8-14-centos ~]$ gcc Test.o -o myTest // 可以指定为执行文件名称。
No.5 动态链接过程
// 我们可以查看可执行程序的动态链接和静态链接 // 指令一: file (可执行程序文件名) // 指令二: ldd (可执行程序文件名) // 解释: .so为动态库 .a为静态库
生成静态可执行程序
// 第一步:先安装一下静态库,如果有的话就忽略 sudo yum install -y glibc-static sudo yum install -y libstdc++-static // 安装c++的库 // 第二部生成静态库的可执行文件。 gcc Test.c -o myTest_s -static
在这里涉及到一个重要的概念:函数库
-
我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?
-
最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用
函数库一般分为静态库和动态库两种。
-
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
-
动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcchello.o –o hello
-
gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证
No.6 gcc选项
-
-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-
-S 编译到汇编语言不进行汇编和链接
-
-c 编译到目标代码
-
-o 文件输出到 文件
-
-static 此选项对生成的文件采用静态链接
-
-g 生成调试信息。GNU 调试器可利用该信息。
-
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
-
-O0
-
-O1
-
-O2
-
-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-
-w 不生成任何警告信息。
-
-Wall 生成所有警告信息。
gcc选项记忆
-
esc,iso例子