gcc预处理后可以输出C代码吗?
我正在使用一个开源库,它似乎有很多预处理指令来支持除 C 之外的许多语言。这样我就可以研究该库在做什么,我想看看预处理后我正在编译的 C 代码,更像是我写的。
gcc(或 Linux 中常用的任何其他工具)可以读取这个库,但输出经过预处理转换为任何内容并且也可供人类读取的 C 代码吗?
I'm using an open source library which seems to have lots of preprocessing directives to support many languages other than C. So that I can study what the library is doing I'd like to see the C code that I'm compiling after preprocessing, more like what I'd write.
Can gcc (or any other tool commonly available in Linux) read this library but output C code that has the preprocessing converted to whatever and is also readable by a human?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
是的。向 gcc 传递
-E
选项。这将输出预处理后的源代码。Yes. Pass gcc the
-E
option. This will output preprocessed source code.cpp
是预处理器。运行
cpp filename.c
输出预处理后的代码,或者更好的是,将其重定向到一个文件cpp 文件名.c >文件名.预处理
。cpp
is the preprocessor.Run
cpp filename.c
to output the preprocessed code, or better, redirect it to a file withcpp filename.c > filename.preprocessed
.-save-temps
与
-E
相比,此选项的优点是可以轻松地将其添加到任何构建脚本中,而不会过多干扰构建本身:main.c
现在,除了正常输出
main.o
之外,当前工作目录还包含以下文件:main.i
是所需的预设文件包含:<前><代码>#1“main.c”
#1“<内置>”
# 1 “<命令行>”
# 31 “<命令行>”
# 1 “/usr/include/stdc-predef.h” 1 3 4
# 32 “<命令行>” 2
# 1 “main.c”
int myfunc(int i) {
返回 i + 1;
}
main.s
是一个额外的好处:-)并包含生成的程序集:<前><代码> .文件“main.c”
。文本
.globl myfunc
.type myfunc,@function
我的函数:
.LFB0:
.cfi_startproc
推q%rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movl -4(%rbp), %eax
添加$1,%eax
弹出%rbp
.cfi_def_cfa 7, 8
雷特
.cfi_endproc
.LFE0:
.size myfunc, .-myfunc
.ident“GCC:(Ubuntu 8.3.0-6ubuntu1)8.3.0”
.section .note.GNU-stack,"",@progbits
文档:https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html#index-save-temps
-save-temps =obj
如果您想对大量文件执行此操作,请考虑使用:
它将中间文件保存到与
-o
对象输出相同的目录中当前工作目录的名称,从而避免潜在的基本名称冲突。例如:
导致文件的创建:
显然,苹果计划接管世界。
-save-temps -v
关于此选项的另一个很酷的事情是,如果您添加
-v
:它实际上显示正在使用的显式文件,而不是
/tmp
下的丑陋临时文件,因此很容易确切地知道发生了什么,其中包括预处理/编译/汇编步骤:在 Ubuntu 19.04 (Disco Dingo) amd64、GCC 8.3.0 中测试。
CMake 预定义目标
CMake 自动为预处理文件提供一个目标:
向我们展示我们可以做什么:
并且该目标运行:
因此可以在
CMakeFiles/main.dir/main 中看到该文件。 ci
在 cmake 3.16.1 上测试。
-save-temps
The advantage of this option over
-E
is that it is easy to add it to any build script, without interfering much in the build itself:main.c
and now, besides the normal output
main.o
, the current working directory also contains the following files:main.i
is the desired prepossessed file containing:main.s
is a bonus :-) and contains the generated assembly:Docs: https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html#index-save-temps
-save-temps=obj
If you want to do it for a large number of files, consider using instead:
which saves the intermediate files to the same directory as the
-o
object output instead of the current working directory, thus avoiding potential basename conflicts.For example:
leads to the creation of files:
Clearly an Apple plot to take over the world.
-save-temps -v
Another cool thing about this option is if you add
-v
:it actually shows the explicit files being used instead of ugly temporaries under
/tmp
, so it is easy to know exactly what is going on, which includes the preprocessing / compilation / assembly steps:Tested in Ubuntu 19.04 (Disco Dingo) amd64, GCC 8.3.0.
CMake predefined targets
CMake automatically provides a targets for the preprocessed file:
shows us that we can do:
and that target runs:
so the file can be seen at
CMakeFiles/main.dir/main.c.i
Tested on cmake 3.16.1.
我使用 gcc 作为预处理器(用于 html 文件)。它正是您想要的。它扩展“#--”指令,然后输出一个可读文件。 (我尝试过的其他 C/HTML 预处理器都没有这样做 - 它们连接行,阻塞特殊字符等。)假设您安装了 gcc,命令行是:
gcc -E -xc -P -C -traditional -cpp code_before.cpp > > code_after.cpp
(不一定是“cpp”。)http://www.cs.tut.fi/~jkorpela/html/cpre.html。
“-traditional-cpp”保留空格和空格。选项卡。
I'm using gcc as a preprocessor (for html files.) It does just what you want. It expands "#--" directives, then outputs a readable file. (NONE of the other C/HTML preprocessors I've tried do this- they concatenate lines, choke on special characters, etc.) Asuming you have gcc installed, the command line is:
gcc -E -x c -P -C -traditional-cpp code_before.cpp > code_after.cpp
(Doesn't have to be 'cpp'.) There's an excellent description of this usage at http://www.cs.tut.fi/~jkorpela/html/cpre.html.
The "-traditional-cpp" preserves whitespace & tabs.
运行:
或
Run:
or
假设我们有一个文件 Message.cpp 或一个 .c 文件
步骤 1: 预处理(参数
-E
)生成的 P1 文件已扩展宏,头文件内容和注释为脱光了。
第 2 步: 将预处理文件转换为程序集(参数
-S
)。这个任务是由编译器完成的,生成一个汇编程序(ASM)(Message.s)。它有所有的汇编代码。
第 3 步:将汇编代码转换为对象代码。注意:Message.s是在Step2中生成的。
生成一个名为 Message.o 的对象文件。它是二进制形式。
第 4 步:链接目标文件。这个任务是由链接器完成的,
这里生成了一个exe文件MessageApp.exe。
Suppose we have a file as Message.cpp or a .c file
Steps 1: Preprocessing (Argument
-E
)P1 file generated has expanded macros and header file contents and comments are stripped off.
Step 2: Translate Preprocessed file to assembly (Argument
-S
). This task is done by compilerAn assembler (ASM) is generated (Message.s). It has all the assembly code.
Step 3: Translate assembly code to Object code. Note: Message.s was generated in Step2.
An Object file with the name Message.o is generated. It is the binary form.
Step 4: Linking the object file. This task is done by linker
An exe file MessageApp.exe is generated here.