13

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

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

现在我想在一个项目中使用这个库,它还定义了一些宏和符号。当然,我想避免名称冲突,因为有时会出现这种情况,尤其是 windows.h。但更一般地说,我想控制从该标题中真正导出的内容。

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

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

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

但是,它只给出符号,而不是定义它的文件

我觉得这可能是一个有用的信息。例如,检查某些系统宏是否在“great_lib.h”或其上级中被重新定义。不幸的是,在检查gcc 预处理器选项后,我看不到使用 gcc 的方法。

例如,而不是只给我:

#define M_PI 3.14159265358979323846

它会产生

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

也许与 -dN 选项有关?但是它的输出让我感到困惑,它需要进一步的文本处理,而且我不明白信息是如何分层的。还是更简单的方法?

相关问题:

4

3 回答 3

2

-dD 选项与宏一起输出预处理的源代码。这包括指示当前源文件的行,例如

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

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

于 2013-01-11T18:58:38.000 回答
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

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

于 2013-01-11T14:48:10.243 回答
1

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

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

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

于 2016-04-23T20:18:23.780 回答