GCC:
C语言程序转化为可执行程序的过程:
-
预处理
- 根据以字符#开头的命令,修改原始C文件,生成后缀名为.i的文件
-
编译
- 将.i文件翻译为.s文件,主要将C程序转化为汇编程序
-
汇编
- 将.s文件翻译成机器语言,生成.o后缀的文件。
-
链接
- 将调用的外部文件合并到我们的.o文件中,一般生成自主命名的可执行文件。
C语言编译过程简介:
gcc -o 介绍:
// gcc -o 输出文件名 输入文件名 (其中输如文件名也可以放在-o前,但不能放在-o 与输出文件名中间)
gcc -D介绍
gcc -DABC 1 等价于 #define ABC 1。相当于在预编译c程序之前在c程序里面添加一个宏定义
// 配合 #ifdef #endif来使用
预处理:
【gcc -E】 将#define和#include进行处理,生成.i后缀的文件。
// a.c文件
#define ABC 10
void mian(){
int a = ABC;
}
进过gcc -E -o a.i a.c 编译过后:
编译:
【gcc -S】将c语言转化为汇编语言,生成.s类型文件。
// a.c文件
#define ABC 10
void mian(){
int a = ABC;
}
进行gcc -S -o a.s a.c 编译后
汇编:
【gcc -c 】将汇编程序转化为机器能看懂的二进制程序,同过.s类型文件生成.o类型文件
对上述a.s文件进行gcc -c -o a.o a.s后:
链接:
【gcc -o】链接系统文件生成一个可执行的程序
对上述a.c进行一个gcc -o build a.c 即可生成一个可执行文件。
观察上述内容,我们可以发现,我们平常没有用-S、-E、-c这些选项,但仍然可以生成可执行文件,那是因为在-o之前系统默认帮我们执行了-S、-E、-c这些操作。
注意:#include ,#define,#ifdef #else #endif都不是c语言的关键字
静态库编译与链接:
-
编译成.o文件
gcc -c [.c] -o [自定义文件名] gcc -c [.c] [.c] ...
-
编静态库
ar -r [lib自定义库名.a] [.o] [.o] ...
-
链接成为可执行文件
gcc [.c] [.a] -o [自定义输出文件名] gcc [.c] -o [自定义输出文件名] -l[库名] -L[库所在路径]
创建静态库编译与链接:
-
编译二进制文件
gcc -c -fpic [.c/.cpp][.c/,cpp]...
-
编库
gcc -share [.o][.o]... -o [lib自定义库名.so]
-
连接动态库到可执行文件
gcc [.c/.cpp] -o [自定义可执行文件] -l[库名] -L[库路径] -Wl,-rpath=[库路径]
动态库与静态库的区别
- 静态库直接写入到执行文件里,执行文件会变大;
- 动态库是运行时候调用,执行文件小但需要运行时才能连接到库
细节:
#include<>与#include ""的区别:
- #include <头文件> : 编译器只会从系统配置的库环境中去寻找头文件,不会搜索当前文件夹。通常用于引用标准库头文件。
- #include “头文件” : 编译器会先从当前文件夹中寻找头文件,如果找不到则到系统默认库环境中去寻找。一般用于引用用户自己定义使用的头文件。