生成标头中定义的所有预处理器符号的列表

时间:2013-01-11 14:43:33

标签: gcc macros c-preprocessor

假设我使用了一些C或C ++库,它们是由标题和一些源文件组成的,它们被编译成我可以链接的静态或共享库。

在库的标题中(数十个......或数百个文件),定义了一些宏/符号。

现在我想在项目中使用这个库,它还定义了一些宏和符号。当然,我想避免名字冲突, 因为有时会报道,特别是对于windows.h。但更一般地说,我希望控制从该标题中真正导出的内容。

我可以使用gcc预处理器选项生成已定义符号的列表:

gcc -E -dM include/great_lib.h | sort -V >symbols.txt

这将在文件symbols.txt中输出包含此标题时用户文件中包含的所有已定义符号的排序列表。

但是,它只提供符号而不是文件的定义

我觉得这可能是一个有用的信息。例如,检查是否在“great_lib.h”或其优先级中重新定义了某个系统宏。 不幸的是,在检查gcc preprocessor options之后,我看不到使用gcc的方法。

例如,而不仅仅是给我:

#define M_PI 3.14159265358979323846

它会产生

#define M_PI 3.14159265358979323846; /usr/include/math.h

也许使用-dN选项?但它的输出对我来说很困惑,它需要进一步的文本处理,我不明白信息是如何分层的。 还是一种更简单的方式?

相关问题:

3 个答案:

答案 0 :(得分:2)

-dD选项输出预处理的源以及宏。这包括指示当前源文件的行,例如

# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.5.2/../../../../include/_mingw.h" 1 3

你可以写一个小程序,(i)通过解析这些行来跟踪当前的源文件; (ii)输出以#define(和\t# define等)开头的所有行,然后输出当前的源文件名; (iii)丢弃所有其他行(源代码,声明等)。

答案 1 :(得分:1)

快速的unix方法:

find "$PATH_TO_LIB" -name "*.h" | xargs grep "^[ \t]*#[ \t]*define"

然后,您可以使用sed和sort来清理格式。

另外,根据gcc手册,gcc会警告你这类事情。

http://gcc.gnu.org/onlinedocs/cpp/Undefining-and-Redefining-Macros.html

  

如果使用与旧的定义实际上不同的定义重新定义宏,则预处理器会发出警告并更改宏以使用新定义。如果新定义实际上是相同的,则会默默忽略重新定义。例如,这允许两个不同的头部定义公共宏。只有定义不匹配时,预处理器才会抱怨。

答案 2 :(得分:1)

不要笨拙地重新发明轮子。所有gcc -dM东西都给你一个方轮: - )

任何ctags(对于vi)或etags(对于emacs)程序都将提取该信息(在哪个文件中定义/声明了哪个标识符)。作为奖励,您可以使用编辑直接理解的形式,允许您将光标放在标识符上,然后跳转到其声明/定义。

使用工具箱中的工具,使用Unix理念,让一个工具做好一件事。