1、编译系统 C源文件到可执行文件共经历了4个过程。在使用GCC编译程序时,编译过程可以被细分为四个阶段,包括预处理、编译、汇编、链接 1、预处理 在预处理阶段,编译器主要作加载头文件、宏替换、条件编译的作用。一般处理带“#”的语句。 我们可以通过gcc 的 -E 选项进行查看,如下所示: gcc -E main.c > main.i 编译器将main.c预处理结果输出 main.i 文件。 2、编译 在编译过程中,编译器主要作语法检查和词法分析。在确认所有指令都符合语法规则之后,将其翻译成等价的中间代码或者是汇编代码。 gcc -S main.i -o main.s 编译器将预处理结果文件main.i翻译成汇编代码main.s 3、汇编 汇编阶段是把编译阶段生成的”.s”文件转成二进制目标代码。 gcc -c main.s -o main.o 编译器将main.s文件转化为main.o 文件。 4、链接 在成功编译之后,就进入了链接阶段。链接就是将目标文件、启动代码、库文件链接成可执行文件的过程,这个文件可被加载或拷贝到存储器执行。 gcc main.o -o main.exe 编译器将main.o链接成最终可执行文件main.exe
gcc -c与gcc -o以及不加参数的区别:
-c 编译和汇编,但不要链接。 -o <file> 将输出放入<文件>。 '无参数' 表示恢复为基于文件扩展名猜测语言的默认行为 1、通过gcc 不加参数可以一步直接编译生成可执行文件 gcc main.c 这里生成的是可执行文件a.out,当然可以通过-o选项更改生成文件的名字,比如将生成的可执行文件命名为hello.exe gcc main.c -o main.exe //当然也可以通过-o选项更改生成的执行文件的名字 2、gcc -c 编译生成main.o gcc -c main.c #生成main.o gcc main.o #不加参数,gcc自动链接上一步生成的main.o来生成最终可执行文件a.out 2、静态链接 静态连接器以一组可重定向目标文件为输入,生成一个完全链接的可执行目标文件作为输出。链接器主要完成以下两个任务:- 符号解析:每个符号对应于一个函数、一个全局变量或一个静态变量,符号解析的目的是将每个符号引用与一个符号定义关联起来。
- 重定位:链接器通过把每个符号定义与一个内存位置关联起来,然后修改所有对这些符号的引用,使得它们指向这个内存位置。
- 可执行目标文件:可以直接在内存中执行;
- 可重定向目标文件:可与其它可重定向目标文件在链接阶段合并,创建一个可执行目标文件;
- 共享目标文件:这是一种特殊的可重定向目标文件,可以在运行时被动态加载进内存并链接;
- 当静态库更新时那么整个程序都要重新进行链接;
- 对于 printf 这种标准函数库,如果每个程序都要有代码,这会极大浪费资源。
- 在给定的文件系统中一个库只有一个文件,所有引用该库的可执行目标文件都共享这个文件,它不会被复制到引用它的可执行文件中;
- 在内存中,一个共享库的 .text 节(已编译程序的机器代码)的一个副本可以被不同的正在运行的进程共享。
//mylib.cpp #include <iostream> #include "mylib.h" int myadd(int a, int b) { return a + b; } void myprint( int s) { std::cout << s << std::endl; }
以通过下面两个命令将这两个函数编译成静态库。 gcc -c mylib.cpp -o mylib.o //产生目标文件 ar rcv libmylib.a mylib.o //将目标文件打包成静态库 使用C++编译的静态库 //main.cpp #include <iostream> #include "mylib.h" int main() { myprint(myadd(1,2)); return 0; } 通过下面的命令(任选一种)将main.cpp与静态库进行编译。 g++ -o main main.cpp -L. -lmylib g++ -o main main.cpp libmylib.a 标签:文件,gcc,--,编译,int,Linux,main,链接 From: https://www.cnblogs.com/liujiarui/p/17517989.html