如何获取C源文件中包含的所有头文件的列表?

时间:2014-09-10 05:52:52

标签: python c parsing

我尝试过使用#include解析文件。我试图使用sed命令匹配模式。这两种方式我都得到垃圾数据。例如,如果在某些评论中我有/* #include "header.h" */,我也会得到这些行。怎么避免这个?

6 个答案:

答案 0 :(得分:5)

GCC支持-H选项。考虑源文件hw.c

#include <stdio.h>
int main(void) { puts("Hello world"); return 0; }

在Mac OS X 10.9.4上使用GCC 4.8.1:

$ gcc -H -c hw.c
. /usr/include/stdio.h
.. /usr/include/sys/cdefs.h
... /usr/include/sys/_symbol_aliasing.h
... /usr/include/sys/_posix_availability.h
.. /usr/include/Availability.h
... /usr/include/AvailabilityInternal.h
.. /usr/include/_types.h
... /usr/include/sys/_types.h
.... /usr/include/machine/_types.h
..... /usr/include/i386/_types.h
.. /usr/include/sys/_types/_va_list.h
.. /usr/include/sys/_types/_size_t.h
.. /usr/include/sys/_types/_null.h
.. /usr/include/sys/_types/_off_t.h
.. /usr/include/sys/_types/_ssize_t.h
.. /usr/include/secure/_stdio.h
... /usr/include/secure/_common.h
Multiple include guards may be useful for:
/usr/include/secure/_stdio.h
/usr/include/sys/_posix_availability.h
/usr/include/sys/_symbol_aliasing.h
$

答案 1 :(得分:3)

一旦你开始考虑像

这样的非平凡案例
/* #include <header.h> */

您很快就会达到编写自己的依赖提取器不再切实可行的程度。

例如考虑这些:

#define PLUGIN "my_extension.h"
#include PLUGIN

#ifdef WITH_CURSES
#  include <curses.h>
#endif

您可以无限期地继续列表。如果你想正确处理所有这些,你最终将实现一个完整的预处理器。

我不知道你想对生成的苍蝇列表做什么,但常见的情况是确定编译单元依赖哪些文件,例如生成makefile。大多数编译器都为此提供了特殊支持。在GCC中,它是-M选项。

<强>的main.c

#include <alpha.h>

/* #include <beta.h> */

#ifdef PLUGIN
#include PLUGIN
#endif

#if WITH_DELTA
#include <delta.h>
#endif

<强> alpha.h

#include <epsilon.h>

beta.h gamma.h delta.h epsilon.h 为空(或者,至少不是#include任何东西。

$ gcc -I. -M main.c
main.o: main.c /usr/include/stdc-predef.h alpha.h epsilon.h

$ gcc -I. -DPLUGIN='<gamma.h>' -M main.c
main.o: main.c /usr/include/stdc-predef.h alpha.h epsilon.h gamma.h

$ gcc -I. -DWITH_DELTA=1 -M main.c
main.o: main.c /usr/include/stdc-predef.h alpha.h epsilon.h delta.h

即使你最终没有尝试生成一个makefile,解析预处理器的输出也会比通过源文件走自己的方式更容易

答案 2 :(得分:0)

如果你的编译器支持-E(或类似)选项,那么这样的东西可能会有用:

cc -E myprogram.c | grep '^# 1 '

-E选项表示只需运行预处理阶段并显示结果。

此方法的一个优点是,您可以包含任何重要的-I-D命令行选项,就像正常编译一样,从而捕获可能产生的任何行为更改。

答案 3 :(得分:0)

您是否考虑使用pycparser之类的解析C文件的内容?对于您的问题可能有点过分,但它确实允许更高级的解析选项。

答案 4 :(得分:-1)

您可以使用grep实用程序(Linux,MacOS X):

grep '/^\s*#/' my_file.c

或(用于多文件搜索)

grep '/^\s*#/' *.c

答案 5 :(得分:-1)

我使用带有匹配和搜索功能的re模块。当匹配从字符串的开头

开始时,搜索将在字符串中找到任意文本