gcc编译原理和顺序
2023-02-18 16:41:14 时间
重温编译
例如我有一个简单的程序
/*cpp文件*/
#include <cstdio>
#include <iostream>
#include "data.h"
int main()
{
printf("hello from epoll!\n");
TreeNode *root = new TreeNode(1);
std::cout<<(root->value);
return 0;
}
/*头文件*/
#pragma once
struct TreeNode {
int value;
TreeNode *next;
TreeNode(int x) :value(x){};
};
预处理
这个流程主要是处理头文件(#include)和宏定义(#define)
使用gcc的-E只预处理,生成.ii文件
gcc -E main.cpp -o main.ii
生成的.ii文件有10000多行,其实是把库函数所有声明和结构合并在一起
编译
这个过程是将上一步生成的文件编译成汇编能够识别的文件
使用gcc的-S参数只编译,生成.s文件,下面是部分代码
gcc -S main.ii -o main.s
.file "main.cpp"
2 .local _ZStL8__ioinit
3 .comm _ZStL8__ioinit,1,1
4 .section .text._ZN8TreeNodeC2Ei,"axG",@progbits,_ZN8TreeNodeC5Ei,comdat
5 .align 2
6 .weak _ZN8TreeNodeC2Ei
7 .type _ZN8TreeNodeC2Ei, @function
8 _ZN8TreeNodeC2Ei:
9 .LFB972:
10 .cfi_startproc
11 pushq %rbp
12 .cfi_def_cfa_offset 16
13 .cfi_offset 6, -16
14 movq %rsp, %rbp
15 .cfi_def_cfa_register 6
16 movq %rdi, -8(%rbp)
17 movl %esi, -12(%rbp)
18 movq -8(%rbp), %rax
19 movl -12(%rbp), %edx
20 movl %edx, (%rax)
21 popq %rbp
22 .cfi_def_cfa 7, 8
23 ret
24 .cfi_endproc
25 .LFE972:
26 .size _ZN8TreeNodeC2Ei, .-_ZN8TreeNodeC2Ei
27 .weak _ZN8TreeNodeC1Ei
28 .set _ZN8TreeNodeC1Ei,_ZN8TreeNodeC2Ei
汇编
这个步骤主要是把.s文件翻译成二进制机器指令文件.o
gcc使用-c参数
gcc -c main.s -o main.o
^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^A^@>^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^G^@^@^@^@^@^@^@^@^@^@@^@^@^@^@^ @@^@^Q^@^P^@^A^@^@^@^F^@^@^@UH<89>åSH<83>ì^X¿^@^@^@^@è^@^@^@^@¿^P^@^@^@è^@^@^@^@H<89>þ^A^@^@^@H<89>ßè^@^@^@^ @H<89>]èH<8b>Eè<8b>^@<89>Æ¿^@^@^@^@è^@^@^@^@¸^@^@^@^@H<83>Ä^X[]ÃUH<89>åH<83>ì^P<89>}ü<89>uø<83>}ü^Au'<81>}øÿÿ ^@^@u^^¿^@^@^@^@è^@^@^@^@º^@^@^@^@¾^@^@^@^@¿^@^@^@^@è^@^@^@^@ÉÃUH<89>å¾ÿÿ^@^@¿^A^@^@^@è°ÿÿÿ]Ã^@UH<89>åH<89>}ø <89>uôH<8b>Eø<8b>Uô<89>^P]Ãhello from epoll!^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@GCC: (GNU) 4.8.5 20150623 (Red Ha t 4.8.5-44)^@^@^@^T^@^@^@^@^@^@^@^AzR^@^Ax^P^A^[^L^G^H<90>^A^@^@^\^@^@^@^\^@^@^@^@^@^@^@^V^@^@^@^@A^N^P<86>^B C^M^FQ^L^G^H^@^@^@ ^@^@^@<^@^@^@^@^@^@^@O^@^@^@^@A^N^P<86>^BC^M^FE<83>^C^BE^L^G^H^@^@^@^\^@^@^@`^@^@^@^@^@^@^ @=^@^@^@^@A^N^P<86>^BC^M^Fx^L^G^H^@^@^@ ^@^@^@<80>^@^@^@^@^@^@^@^U^@^@^@^@A^N^P<86>^BC^M^FP^L^G^H^@^@^@^@^@^@ ^@^@^@^@^@^@
链接
这个步骤主要是把相关的静态库.a文件和动态库.so文件拼起来
对于使用gcc的,可以用-L参数声明库文件地址,也可以使用一下参数
gcc -xc++ -lstdc++ -shared-libgcc 这里会声明使用c++标准库
gcc -xc++ -lstdc++ -shared-libgcc main.cpp -o main2
或者使用g++,g++的好处就是能够自动链接
g++ main.cpp -o main3
再或者就是使用make或者cmake工具指定库地址来完成整个编译过程
相关文章
- [javaEE] HTTP协议总结
- [javaEE] web应用的目录结构&配置虚拟主机
- [javaEE] Tomcat的安装与配置
- 「万字图文」史上最姨母级Java继承详解
- 带你深入理解Java的IO到底是个啥
- 不藏了,这些Java反射用法总结都告诉你们
- java算法易筋经:常见java-API使用技巧
- 论文/代码速递2022.10.19!
- 论文/代码速递2022.10.20!
- 【AI绘画】如何优雅的在本地配置 nounovelai ?
- 英伟达最新成果!基于NeRF的并行优化方法,可用于6D姿态估计!论文/代码速递2022.10.21!
- 论文/代码速递2022.10.24!
- 低分辨率人脸识别!注意力相似性知识提取方法!论文/代码速递2022.10.25!
- 论文/代码速递2022.10.26!
- ECCV 2022 | 开放集半监督目标检测!论文/代码速递2022.10.27!
- 论文/代码速递2022.10.28!
- SCI语料库!学术写作神器——Academic Phrasebank
- 查找表实现高效的图像超分辨率!论文/代码速递2022.10.31!
- 论文/代码速递2022.11.1!
- ECCV2022 | 通过网格实现辐射场的自由变形! 已开源!论文/代码速递2022.11.2!