请教一个问题:在GCC中如何看包含文件的关系?
记得VC6.0通过一个选择是可以在输出中显示的。不知道GCC有没有类似的功能?
目前用一个交叉编译器编译nmap,结果编译到C++的文件全部出错,最后我确认是这个编译器自己的实现需要最终包含其config.h文件,但我写一个单个的文件就OK,不明白为啥nmap就不行了,手工强制在main.cc中加上那个文件的include就OK了,但这个显然不是解决方案。我所能想到的是如果能显示出头文件的包含关系,我就可以利用单个文件编译来进行分析了。为个编译器并不是用GCC实现的,但手册说是完全兼容GCC编译选项的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
GCC -M
是这个选项?
好像不是。不过问题倒找到原因了,configure会生成nmap_config.h,但生成的文件中防止重复包含的宏叫CONFIG_H,而我所用编译器的C++实现中会包含到它自己的一个config.h,也是这个宏。由于这个编译器自带的文件后包含,导致其内容并没有引用进来。
定位的手段算是最老土但也很有效的:二分法。先在不同位置插入这个文件的硬包含,最终一层一层找到冲突的头文件。
哦,绛紫啊。
这手段简单有效,跟你学了一手
啥叫“绛紫”?逐步分解的办法以前在定位问题时经常用(不限于编译问题),编译时的头文件冲突很烦人的,因为出来的错误很不直观,以前遇到过VC6.0编译时出现Compiler Internal Error,当时那哥们傻眼了,最好也是用类似的办法一步步定位到是他们测试工具的头文件包含在编译器头文件的前面了,而且基本的宏和编译器头文件有冲突。
我印象中GCC至少有一个选项是可以只预处理的(就象只编译不链接一样),里面会标注哪些内容是从哪个文件include进来的,但实在没心思在成堆的选项说明中找了。至于和VC一样的,以前没用过,不知道有没有。
[ 本帖最后由 Cyberman.Wu 于 2009-3-16 20:03 编辑 ]
gcc -E 是只进行预处理。
我有时编译个东西看见 GCC 的 Internal Compiler Error 简称 ICE(不是硬件的那个 ICE)也是很郁闷啊,不过还好在 buglist 上总能找到我的问题。
你们那是测试工具生成的代码和编译器使用的代码名字冲突了。不过这种一步一步找问题的手段倒是非常有效和实用的。如果测试套件是自己公司写的,就打个招呼,以后生成文件的时候把文件名起的“个性”一点,带个前缀什么的,如果测试套件是买的...
如果真的编译器本身的问题,还得把 AST 、 GIMPLE 和 RTL 打印出来和 ASM 对比,打印出来这些 IR 是为了看 GCC 在处理哪一级 IR 的时候出现了问题,然后去找相应的 bug ,我只是知道这么找,也没找过。
绛紫、酱紫是“这样子”的意思,大家都用,我也跟着用了
[ 本帖最后由 prolj 于 2009-3-17 01:12 编辑 ]
谢了,刚试了一下,以前用过的应该就是这个。另外-v在没其它编译时显示版本信息等,而编译时则显示编译过程的一些细节信息,但没有预处理部分。
原来公司对于文件名称、宏定义名称等有严格的要求,这个还是很有道理的,因为这些东西一旦引起冲突问题会让人有抓狂的感觉。以前我遇到过好几次有人编译的是另一个同名的文件,还总说我怎么修改了编译出来的结果就是不对呢,是不是编译器错了(虽然以前也遇到几次编译器的缺陷,但相对来说还是我们自己的问题多多了)。
BTW:我在学校时专业和计算机无关,而且十几年前条件也没现在这么好,纯粹是做为业余受好玩了几年,学得东西乱七八糟的,编译原理没学过,所以你的名词AST啥的不知道,呵呵。如果说对编译器的了解的话,纯粹因为工作中老是需要反汇编分析和指令级调试;而YACC也是为了写一个反汇编VxWorks的bin程序(模拟VxWorks串口的一些函数;说出这个来原来公司小圈子的人看到就知道我是谁了,不过他们应该没人在这里),但不想自己写解释命令而玩了一段时间。
你已经那么厉害了,把一个 OS 吃透了,对 Arch 还那么熟悉。
VxWorks的.bin已经没任何结构了,就是内存映射,所有的文件头符号表啥的全部删除了。前面是代码段的内容,然后是数据段,BSS也直接填写一堆0放进去,基本上不用对OS和Arch有太多了解。它的所谓符号表实际上是编译过程中先链接一个文件,把所有符号导出来生成一个symtbl.c,里面有一个数据结构把所有符号表放进去,然后再编译链接到系统中。
我的办法就是从文件后面反向搜索,因为这个表的数据结构是有一定特征,可以定位出来。办法虽然简单,但却挺有效的,所以有时候笨办法最可行。这个表中地址最低的那个符号的地址一般就是.bin文件在内存的加载位置。
ELF映射的直接支持也曾想过,但后来工作忙没动力完成它了。
哈哈,就是你这种犀利的风格,正是我要学习的。还有你那么丰富的经验,和积累的功力。我对 OS 要求不高,代码都熟悉一下就好。