我正在浏览 GCC 手册页,我发现了以下行:
file.i
C source code that should not be preprocessed.
我知道运行
gcc -E foo.c
会在预处理后停止编译器;
但创建 .i
文件的实际应用是什么?
还有一种方法可以生成除
.i
之外的 gcc foo.c -E > foo.i
文件吗?
.i
文件也称为“纯C文件”。在预处理阶段
将包含头文件。
宏将被替换。
评论已被删除。
用于条件编译。 如果您查看
.i
文件,您可以看到这些内容。生成
.i
文件的命令是-
gcc -E foo.c -o foo.i
一个
file.i
文件是:
不应预处理的 C 源代码。
来源:
man gcc
然后按/键搜索,搜索“\.i
”。man gcc
,然后按/键进行搜索,然后输入\.i
,然后按Enter键,然后反复按n键直至找到。
这意味着
.i
文件是预处理过的源代码,因此它已经被预处理过。因此,它已经包含:
...正如 @Sathish 在他的回答中所述。
您还会注意到 gcc 添加的大量特殊“注释”现在以#
字符开头,例如:
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
# 44 "main.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 374 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
我不知道它们是什么,也不知道它们是做什么的。有知道的请告诉我。请注意,像这样的简单程序:
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
用这个编译:
gcc -Wall -std=c99 -O0 -save-temps=obj main.c -o ./bin/main
将生成一个大约 682 行长的 main.i
文件,上面显示的
main()
函数就在最后。如何生成所有中间文件,包括
.i
文件:
.i
文件夹中一次性生成 所有
中间文件(
.o
、
.s
、
.i
,而不是仅使用
-E
生成
bin
文件)通过使用
gcc
-save-temps=obj
选项,如下所示:
mkdir bin
gcc -save-temps=obj foo.c -o ./bin/foo
现在“foo/bin”目录中有以下文件:
foo # compiled binary program (AKA: combined "object file",
# "executable", "binary", "program", or "machine code")
foo.i # intermediate, preprocessed C file
foo.o # individual object file
foo.s # assembly file
当然运行程序:
./bin/foo
关于“目标文件”和“可执行文件”的注释foo
可执行文件,称为“编译的二进制程序”,“程序”,(组合)“目标文件”,“可执行文件”,“二进制” ”,或者只是“机器代码”,或者“个和零”(10101010)。它是一个采用 对象文件格式 的 对象文件,单个
*.o
对象文件 也由 链接器 组合成一个来创建它。链接器将所有
*.o
目标文件合并为一个,以便生成最终的
foo
可执行文件,或组合的目标文件。 GNU 链接器 (
ld
) 手册的说明如下。请参阅“3.1 基本链接描述文件概念”部分:https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html#Basic-Script-Concepts(添加了强调,以及方括号中的内容
[]
):
如何在编译时知道STM32的闪存和动态存储器(SRAM)已使用了多少? 如何查看 C 预处理器输出?3.1 基本链接描述文件概念
我们需要定义一些基本概念和词汇来描述链接描述语言。链接器将输入文件[各个
*.o
目标文件]组合成一个单个输出文件。输出文件和每个输入文件都采用特殊的数据格式,称为目标文件格式。每个文件称为目标文件。输出文件通常称为“可执行文件”,但出于我们的目的,我们也将其称为目标文件。除其他外,每个目标文件都有一个sections列表。我们有时将输入文件中的某个部分称为“输入部分”;类似地,输出文件中的部分是输出部分。 了解更多信息。关于目标文件,您还可以在这里看到我的其他两个答案: