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

0 投票
6 回答
2540 浏览
提问于 2025-04-20 19:39

我尝试用Python来解析文件,使用了#include。我还试着用sed命令来匹配模式。但这两种方法得到的数据都很乱。例如,如果在某个注释里有/* #include "header.h" */,我也会把这些行提取出来。请问怎么才能避免这种情况呢?

6 个回答

-1

我使用的是re模块,其中有Match和Search这两个函数。Search可以在字符串的任何位置找到文本,而Match则是从字符串的开头开始查找。

0

如果你的编译器支持 -E(或者类似的选项),那么像下面这样的做法可能会对你有帮助:

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

-E 这个选项的意思是只运行预处理阶段,并显示结果。

这种方法的一个好处是,你可以像正常编译那样,包含任何重要的 -I-D 命令行选项,这样就能捕捉到这些选项可能带来的行为变化。

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.hgamma.hdelta.hepsilon.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,解析预处理器的输出也会比自己逐个查看源文件简单得多。

7

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
$
0

你有没有想过用像 pycparser 这样的工具来解析C语言文件?虽然这可能对你的问题来说有点复杂,但它确实提供了更多高级的解析选项。

撰写回答