假设我使用了一些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选项?但它的输出对我来说很困惑,它需要进一步的文本处理,我不明白信息是如何分层的。 还是一种更简单的方式?
相关问题:
答案 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)
任何ctags
(对于vi)或etags
(对于emacs)程序都将提取该信息(在哪个文件中定义/声明了哪个标识符)。作为奖励,您可以使用编辑直接理解的形式,允许您将光标放在标识符上,然后跳转到其声明/定义。
使用工具箱中的工具,使用Unix理念,让一个工具做好一件事。