如何在C++中查找构成翻译单元的所有文件?

5
我正在使用一个仅包含头文件的库,希望只包含我实际使用的部分。
如果我包括库中的一个头文件,如何找到库中包含的所有其他头文件?或者更一般地说,如何找到组成C++翻译单元的所有文件?(我在Linux上使用g++。)
编辑:使用gcc的可能方法(答案摘要)
  • gcc -H produces output of the form:

    ... /usr/include/c++/4.6/cmath
    .... /usr/include/math.h
    ..... /usr/include/x86_64-linux-gnu/bits/huge_val.h
    ..... /usr/include/x86_64-linux-gnu/bits/huge_valf.h
    

    You have to filter out the system headers manually, though.

  • gcc -E gives you the raw preprocessor output:

    # 390 "/usr/include/features.h" 2 3 4
    # 38 "/usr/include/assert.h" 2 3 4
    # 68 "/usr/include/assert.h" 3 4
    extern "C" {    
    extern void __assert_fail (__const char *__assertion, __const char *__file,
          unsigned int __line, __const char *__function)
          throw () __attribute__ ((__noreturn__));
    

    You have to parse the linemarkers manually. See: http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html

  • gcc -M produces a Make file for the given source file. The output looks as follows:

    object.o: mylibrary/object.h /usr/include/c++/4.6/map \
     /usr/include/c++/4.6/bits/stl_tree.h \
     /usr/include/c++/4.6/bits/stl_algobase.h \
     /usr/include/c++/4.6/x86_64-linux-gnu/./bits/c++config.h \
    

4个回答

4

I believe you're looking for gcc -H.


3
使用 g++ -M somefile 命令可以得到一个包含所有文件 somefile 作为 somefile.o 的依赖项的 makefile。
使用 g++ -MM somefile 命令同样可以得到与上述相同的结果,但不会列出系统头文件 (例如在 /usr/include/usr/local/include 中的任何文件)。
你需要这个命令做什么?如果是为了依赖项跟踪,上述命令已经足够。但如果你想进行一些疯狂的操作,比如“我包括这个头文件,那个头文件又包含了这个头文件,所以我不需要再次包含它”——不要。不,认真地说,不要。

那只给我直接包含的头文件。 - Bernhard Kausler
@BernhardKausler 你确定吗?再检查一下。当我尝试时,它会给我所有直接或间接包含的头文件。 - Cubic
1
@BernhardKausler -M 会列出编译器编译源文件时读取的所有文件。 - James Kanze
@Cubic和James:你们说得对。我尝试了-MM选项,它删除了所有已安装库的头文件。而-M选项确实像你们所说的那样工作。 - Bernhard Kausler

2
您可以使用GCC的-E标志获取预处理的源代码,然后用grep搜索#include。我不知道其他任何将源文件引入翻译单元的方式,因此这样做应该能够完成工作。

谢谢你的提示!不幸的是,在预处理器之后,"#include"已经消失了。但是你可以从预处理器插入的行标记中恢复这些信息。请参见:http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html - Bernhard Kausler
请您更新您的答案,这样我就可以接受它了,谢谢 :) - Bernhard Kausler

2

使用g++(以及大多数Unix编译器,我想),您可以使用-M。 对于其他编译器,您需要使用-E/E,将输出捕获到文件中,并使用您喜欢的脚本语言对文件进行后处理。(我在我的makefile中执行此操作,以构建依赖项。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接