Linux中的编译与链接
Linux中编译链接
1.安装gcc,g++
sudo apt install gcc
sudo apt install g++S
apt update 更新软件源
2.编译链接的四个步骤
1)预编译 main.c ——> main.i
语法:gcc -E main.c -o main.i
或 gcc -o main.i -E main.c
2)编译 main.i ——> main.s
语法:gcc -S main.i -o main.s
3)汇编 main.s ——> main.o
语法:gcc -c main.s -o main.o
4)链接 main.o ——> main(可执行文件)
语法:gcc main.o -o main
5)执行
./main
或者 全路径/main
(路径+可执行文件名)
3.编译链接的过程
main.c文件通过预编译生成main.i文件
main.i文件通过编译生成main.s文件
main.s文件通过汇编生成 main.o文件
链接阶段:将所有的 .o .a(静态库文件) .lib(库文件) .obj文件链接起来生成 .out 文件。
ELF格式的可执行文件 .out文件(Windows生成的是.exe文件)
4.各个阶段所做的事情
1)预编译阶段:
#pragma 用于指示编译器完成一些特定的动作
#pragma once 在头文件的最开始加入,保证头文件只能被编译一次
a)删除所有的"#define",并展开所有的宏定义;
b)处理所有的条件预编译指令,“#if”,“ifdef”,"endif"等;
c)处理"#include"预编译指令,将被包含的文件插入到该预编译指令的位置;
d)删除所有的注释;
e)添加行号和文件名标识,以便于编译器产生调试用的符号信息以及编译时产生的错误和警告时显示行号;
f)保留所有的#pragma编译器指令,因为编译器需要使用它们。
2)编译阶段:
词法分析,语法分析,语义分析,代码优化,汇总符号。
3)汇编阶段:
将汇编指令翻译成二进制格式,生成各个section,生成符号表。
4)链接阶段:
a)合并各个section,调整各个section的起始位置的端的大小,合并符号表,进行符号解析,给符号分配虚拟地址。
b)符号重定位:即在使用符号的全部地方全部替换成符号的虚拟地址。
5.关于执行
如何启动一个进程?
路径+可执行文件名
路径+可执行文件名 & (将进程放到后台去执行)
可以把可执行文件放到/user/bin目录下,就可以省略路径。
6.关于一步执行
1)可以三步合为一步,即不经过预编译,编译,汇编这三步,直接一步生成.o文件。
gcc -c main.c -o main.o
//gcc -c main.c(先编译查看是否有错误)
gcc -o main main.o
2)可以四步合为一步:
gcc -o main main.c
7.关于多个源文件???(已解决见makefile和make)
1)两步,先分步再合并
gcc -c main.c
gcc -c add.c
gcc -c max.c
gcc -o main main.o add.o max.o
2)一步完成
gcc -o main main.c add.c max.c
8.g++
gcc可以编译C、C++文件,两者均可。(一般默认只连接C库)
gcc -o mainc++ mainc++.cpp
(默认链接C库)
gcc -o mainc++ mainc++.cpp -lstdc++
(指明用C++的标准库)