gcc编译中间文件查看

本文介绍了GCC编译流程,包括预处理、编译、汇编和链接四个阶段,以及每个阶段产生的中间文件类型:.i(预处理)、.s(汇编)和.o(对象文件)。通过一个简单的C程序示例,详细展示了预处理后的main.i和汇编后的main.s文件的内容,帮助理解编译过程。

gcc编译流程有:预处理、编译、汇编、链接

每个过程分别产生相应的中间文件。

预处理:.i

编译:.s

汇编:.o

连接:.exe

 

下面以一个例子说明,仅main.h和main.c两个文件。
main.h 内容
char str[] = "hello";

 

main.c 内容

#include<stdio.h>
#include"main.h"
int main()

{

      printf("Hello! /n");
      printf("%s/n",str);
      getchar();
      return 0;

}

 

 

 

命令:gcc -E main.c

查看预处理结果,-E选项将把预处理的结果,写入stdout。
也可以将与处理结果输出到文件中:gcc -E main.c -o output.txt

 

命令:gcc -E main.c -O main.i
输出预处理结果main.i

 

命令:gcc -save-temps -S main.c
1个中间文件: main.i(预处理结果)
1个输出文件:main.s(汇编代码)

注意:使用-save-temps保留中间文件

其中预处理结果main.i为:

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "main.c"
# 1 "C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/stdio.h" 1 3
# 19 "C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/stdio.h" 3
# 1 "C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/_mingw.h" 1 3
# 31 "C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/_mingw.h" 3
      
# 32 "C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/_mingw.h" 3
# 20 "C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/stdio.h" 2 3

.....省略部分

 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetwchar (void);
 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputwchar (wint_t);
 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getw (FILE*);
 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putw (int, FILE*);
# 2 "main.c" 2
# 1 "main.h" 1
char str[] = "hello";
# 3 "main.c" 2
int main()

{

      printf("Hello! This is our embedded world!/n");
      printf("%s/n",str);
      getchar();
      return 0;

}

 

 

 

编译结果main.s为:

 .file "main.c"
.globl _str
 .data
_str:
 .ascii "hello/0"
 .def ___main; .scl 2; .type 32; .endef
 .section .rdata,"dr"
 .align 4
LC0:
 .ascii "Hello! This is our embedded world!/12/0"
LC1:
 .ascii "%s/12/0"
 .text
.globl _main
 .def _main; .scl 2; .type 32; .endef
_main:
 pushl %ebp
 movl %esp, %ebp
 subl $24, %esp
 andl $-16, %esp
 movl $0, %eax
 addl $15, %eax
 addl $15, %eax
 shrl $4, %eax
 sall $4, %eax
 movl %eax, -4(%ebp)
 movl -4(%ebp), %eax
 call __alloca
 call ___main
 movl $LC0, (%esp)
 call _printf
 movl $_str, 4(%esp)
 movl $LC1, (%esp)
 call _printf
 call _getchar
 movl $0, %eax
 leave
 ret
 .def _getchar; .scl 2; .type 32; .endef
 .def _printf; .scl 2; .type 32; .endef

 

在 Linux 环境下使用 GCC 编译 C++ 文件,主要通过 `g++` 命令完成。`g++` 是 GCC(GNU Compiler Collection)的一部分,专门用于编译 C++ 程序。用户只需在终端中输入适当的命令,即可完成从源代码到可执行文件编译过程。 ### 编译单个 C++ 文件 对于一个简单的 C++ 源文件(例如 `main.cpp`),可以直接使用以下命令进行编译: ```bash g++ main.cpp -o main ``` 该命令将 `main.cpp` 编译为名为 `main` 的可执行文件。若未指定 `-o` 参数,编译器将默认生成名为 `a.out` 的可执行文件,如以下命令所示: ```bash g++ main.cpp ``` 生成的 `a.out` 文件可以直接运行,执行方式如下: ```bash ./a.out ``` 这种方式适用于仅包含一个源文件的小型程序[^1]。 ### 编译多个 C++ 文件并链接 当程序由多个源文件组成时(例如 `main.cpp`、`func1.cpp`、`func2.cpp`),需要将这些文件一起编译,并在编译过程中进行链接操作。以下命令可完成该过程: ```bash g++ main.cpp func1.cpp func2.cpp -o program ``` 此命令会将所有 `.cpp` 文件编译并链接为一个名为 `program` 的可执行文件。若源文件较多,也可以使用通配符简化命令: ```bash g++ *.cpp -o program ``` 这种方式适用于多个源文件组成的项目,确保所有函数和类定义都能被正确解析和链接[^3]。 ### 分步编译与链接 有时为了调试或模块化构建,用户可能希望将编译和链接过程分开进行。可以先将每个源文件单独编译为目标文件(`.o` 文件),再将这些目标文件链接为可执行文件。具体步骤如下: #### 1. 编译生成目标文件 ```bash g++ -c main.cpp -o main.o g++ -c func1.cpp -o func1.o g++ -c func2.cpp -o func2.o ``` 上述命令使用 `-c` 参数仅执行编译阶段,不会进行链接操作,生成的 `.o` 文件中间目标文件。 #### 2. 链接目标文件生成可执行文件 ```bash g++ main.o func1.o func2.o -o program ``` 这种分步方式有助于大型项目的构建管理,也便于增量编译和调试。 ### 使用静态库进行链接 如果程序依赖于静态库(例如 `libmath.a`),可以在编译时将库文件与源文件一起链接。例如: ```bash g++ main.cpp libmath.a -o program ``` 此命令将 `main.cpp` 编译并与 `libmath.a` 静态库链接,生成可执行文件 `program`。若库文件不在当前目录,需指定完整路径或使用 `-L` 参数指定库路径[^2]。 ### 注意事项 - 编译 C++ 程序时必须使用 `g++` 而非 `gcc`,因为 `gcc` 默认按 C 语言处理源文件,可能导致链接错误。 - 使用 `-Wall` 参数可开启所有警告信息,有助于发现潜在问题。 - 若程序使用了 C++11 或更高版本的特性,需添加 `-std=c++11` 等参数以启用相应标准。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值