GCC, the GNU Compiler Collection
一: 基础知识
编程语言可以分为 编译型语言 和 解释型语言。编译型语言常见的有 C、C++ ,而解释型语言 如 PHP、Python。Java半编译半解释,Java源码先是编译成 字节码 ,字节码再放到 Java 虚拟机啊中运行。
- 1.1 编译型语言
处理器只认识 0/1 组成的机器码指令,不同平台(ARM、x86_64)的指令集不同。关于指令集有 RISC(精简指令集)、CISC(复杂指令集) 的概念。物理上的处理器芯片可以称为 指令集 的实现。如同 C/C++中 .C 文件中的函数定义是 h头文件中函数原型的 实现。芯片处理指令的过程,可以从FPGA设计RS232控制器窥探一二。 C/C++编译的最终结果是机器码,不同平台的指令集不同,相同的 C/C++ 源码可以运行在不同的平台上,这其中靠的是 对应不同平台的 编译器 。发散来说,C++有 C++11、C++17、C++20 各个标准,编译器支持这些标准你才能 顺利编译 符合标准规范的代码,不然就编译出错了。 C/C++ 编译过程可以分为 4大阶段,分别是 预处理阶段( Preprocess )、编译阶段( Compile )、汇编阶段( Assemble )、链接阶段( Link )。
- 1.2 解释型语言
解释型语言编写完 源码 后不需要编译成机器码,直接依靠解释器来执行。 执行速度没有编译型语言快。
二:工作环境
- 2.1 当前工作目录:
<<huaecase@Huaecase ~ >>$ pwd /home/huaecase
<<huaecase@Huaecase ~ >>$ ls
#返回为空,当前目录下无文件(夹)
三:完整流程:
- 3.1 Ctrl+Alt+t 打开终端编辑一个 huae.c
<<huaecase@Huaecase ~ >>$ sudo vim huae.c
#sudo 表示以管理员身份编辑,或者chmod 命令更改huae.c 的读写权限,不然普通可能无法保存更改。
- 3.2 huae.c 中输入以下内容:
#include <stdio.h> int main() { printf("Hello C "); return 0; }
目录下有文件:
<<huaecase@Huaecase ~ >>$ ls huae.c
- 3.3 简单编译:
<<huaecase@Huaecase ~ >>$ gcc huae.c
新增了 a.out 文件:
<<huaecase@Huaecase ~ >>$ ls a.out huae.c
- 3.4 执行: ( 要加 . / 前缀 )
<<huaecase@Huaecase ~ >>$ ./a.out Hello C
四:过程详解
- 4.1 文件类别:
计算机内部的数据 是 由 0 / 1 组成的 ,即每个比特位 要么是 1 要么是 0 。 计算机中的文件可以分为两大类,一类是 "二进制文件",另一类是“文本文件”,本质上文本文件也是 由 0/1组成 ,只不过文本文件 的 一个 字节 (1 byte = 8bit ) 对应一个ASCII码 (那些UTF-8、Unicode等文件未验证,应该差不了)。 文件 huae. c 属于文本文件,内部字节对应的ASCII与下图相似:[ 图片 截取 自《深入理解计算机系统》]
- 4.2 gcc 选项(节选):
<<huaecase@Huaecase ~ >>$ gcc --help Usage: gcc [options] file... Options: -E Preprocess only; do not compile, assemble or link. 仅仅预处理 -S Compile only; do not assemble or link. 仅仅编译、不进行 汇编 -c Compile and assemble, but do not link. 只到汇编、没有 链接
-o <file> Place the output into <file>. 指定输出文件名 -shared Create a shared library. -x <language> Specify the language of the following input files.
4.2.1 GCC到预处理:输出文件后缀应为 i
<<huaecase@Huaecase ~ >>$ gcc -E -o huae.i huae.c
-E 是gcc 预处理选项,huae.c 中 #include <stdio.h> 就是一个预处理语句,预处理过程相当于文本替换,就是把语句“#include <stdio.h>”替换成库文件 stdio.h 的内容。- o 选项指定输出文件,后接参数 ‘huae.i’ ,输出到该文件。include后面的尖括号 < > 表示优先在 库文件中查找,双引号 “ ” 的话,表示优先查找用户自定义的文件,对于用户指定的文件,要么在源码中写明路径,要么在 gcc 编译时 指明。包含自定义头文件 编译过程实验:
/home 下新建一个 huae. h
<<huaecase@Huaecase ~ >>$ sudo vim /home/huae.h
huae.h 内容:
#ifndef _HUAE_H #define _HUAE_H void apple() { printf("这是 /home/huae.h 中定义的函数 apple( ) "); } #endif
源码指明路径》修改huae.c 内容为:
#include <stdio.h> #include "/home/huae.h" // 指明huae.h 路径 int main() { apple(); printf("Hello C "); return 0; }
编译:
<<huaecase@Huaecase ~ >>$ gcc huae.c -o huae
执行:
<<huaecase@Huaecase ~ >>$ ./huae 这是 /home/huae.h 中定义的函数 apple( ) Hello C
编译时指明路径》 修改huae.c 内容为:
#include <stdio.h> #include " huae.h" // 没有 指明huae.h 路径 int main() { apple(); printf("Hello C "); return 0; }
编译:
<<huaecase@Huaecase ~ >>$ gcc -I /home huae.c #指明路径
4.2.2 GCC到编译:
未完待续
4.2.3 GCC到汇编:
4.2.4 GCC到链接:
五:高级应用
- 5.1 动态链接库:
- 5.2 静态链接库: