142

How can I tell where g++ was able to find an include file? Basically if I

#include <foo.h> 

g++ will scan the search path, using any include options to add or alter the path. But, at the end of days, is there a way I can tell the absolute path of foo.h that g++ chose to compile? Especially relevant if there is more than one foo.h in the myriad of search paths.

Short of a way of accomplishing that... is there a way to get g++ to tell me what its final search path is after including defaults and all include options?

1
  • 2
    Related: is there any way to tell which parent include file(s) a child include file was included from? I.e. to show the included-from graph (Hint: gcc -E isn't quite there... might be processed to yield it.) Commented Jan 8, 2013 at 22:53

6 Answers 6

167
g++ -H ... 

will also print the full path of include files in a format which shows which header includes which

Sign up to request clarification or add additional context in comments.

6 Comments

This seems to be more helpful than -M in my experience. I like the hierarchical display of what includes what.
This is the best answer. You can add it to your build process without changing anything else.
This really answers the question more than the accepted answer. Only unfortunate problem is that I couldn't get it to stop Clang from trying to compile the file normally, so I ended up using clang++ -MM -H (which is a slightly useful combination).
@rookie1024 Use clang++ -H -fsyntax-only ... if you would like to avoid generating output files (works for gcc too).
This looks like the counterpart of /showIncludes in MSVC.
|
97

This will give make dependencies which list absolute paths of include files:

gcc -M showtime.c 

If you don't want the system includes (i.e. #include <something.h>) then use:

gcc -MM showtime.c 

2 Comments

It should be noted that if you use in conjunction with "-o myObj.o", the output, not the compiled binary, goes into "myObj.o". -M has an implicit -E, so the compilation is not peformed. I found -MD is a very useful option instead, it performs the compile and puts the output in myObj.d instead. Making a suitable param for just prepending to your compile line without strange effects like *.o now contains the output instead of the binary. Thanks for your help.
All related gcc options are described here.
13

Sure use

g++ -E -dI ... (whatever the original command arguments were) 

2 Comments

There are several benefits to this solution: 1. You can discover multiple inclusions of a single header file (-H and -M print each included file only once) 2. You can see where it is included (name and line number of the original include instruction). 3. Thereby you can reliably(!) distinguish whether a header is included directly or indirectly or both (This is important for cleanups.)
@hagello Unfortunately with -E -dI, GCC only gives you the raw source line of the include if the header was already included - not the annotation with the resolved full path. For manual analysis this may be enough. But for automated analysis it makes things awkward.
9

If you use -MM or one of the related options (-M, etc), you get just the list of headers that are included without having all the other preprocessor output (which you seem to get with the suggested g++ -E -dI solution).

You can also use the -H option. It prints the headers as they are included with one dot . as a prefix for each level of nesting in the headers. What you include directly is prefixed by a dot and a space; files that those files include are prefixed with two dots and a space, and so on. This can be helpful. The output appears on stderr rather than stdout. (See also the answer, which suggests -H but doesn't include information about the format of the output.)

2 Comments

g++ -MM t.cc shows no inclusion at all, just t.o: t.cc. Does it need something else?
Nice - for completeness, you can get similar with MSVC using the /showIncludes option. MSVC will even indent to show you the nesting of headers (I dont see that with -M on GCC).
8

If your build process is very complicated...

constexpr static auto iWillBreak = #include "where/the/heck/is/this/file.h" 

This will (almost certainly) cause a compilation error near the top of the file in question. That should show you a compiler error with the path the compiler sees.

Obviously this is worse than the other answers, but sometimes this kind of hack is useful.

3 Comments

I find this very useful, especially as it works across different compilers and is directed towards the file I want.
Why not just use #error instead?
if you write #error in a file, then the compiler will print out that file's path in the error message. the silly hack in the answer above will (probably) show the path of the file included in the next line
2

For MSVC you can use the /showIncludes option, which will display the files that are included.


(This was stated in a comment of Michael Burr on this answer but I wanted to make it more visible and therefore added it as a separate answer.)


Usability note: The compiler will emit this information to the standard error output which seems to be suppressed by default when using the windows command prompt. Use 2>&1 to redirect stderr to stdout to see it nonetheless.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.