重温编译
例如我有一个简单的程序
代码语言:javascript复制/*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;
}
代码语言:javascript复制/*头文件*/
#pragma once
struct TreeNode {
int value;
TreeNode *next;
TreeNode(int x) :value(x){};
};
预处理
这个流程主要是处理头文件(#include)和宏定义(#define)
使用gcc的-E只预处理,生成.ii文件
代码语言:javascript复制gcc -E main.cpp -o main.ii
生成的.ii文件有10000多行,其实是把库函数所有声明和结构合并在一起
编译
这个过程是将上一步生成的文件编译成汇编能够识别的文件
使用gcc的-S参数只编译,生成.s文件,下面是部分代码
代码语言:javascript复制gcc -S main.ii -o main.s
代码语言:javascript复制.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), �x
20 movl �x, (%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参数
代码语言:javascript复制gcc -c main.s -o main.o
代码语言:javascript复制^?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 标准库
代码语言:javascript复制gcc -xc -lstdc -shared-libgcc main.cpp -o main2
或者使用g ,g 的好处就是能够自动链接
代码语言:javascript复制g main.cpp -o main3
再或者就是使用make或者cmake工具指定库地址来完成整个编译过程