How to Tell Where a Header File Is Included From

How to tell where a header file is included from?

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

How to determine which header files to include?

Is there an easier/better way to ensure cross-compiler compatibility?

This is always going to be a bit of a chore if you have a huge codebase and haven't been doing this so far, but once you've gone through fixing your includes, you can stick to a simple procedure:

When you write new code that uses a standard feature, like std::stoi, plug that name into Google, go to the cppreference.com article for it, then look at the top to see which header it's defined in.

Then include that, if it's not already included. Job done!

(You could use the standard for this, but that's not as accessible.)

Do not be tempted to sack it all off in favour of cheap, unportable hacks like <bits/stdc++.h>!


tl;dr: documentation

How to check each header file includes required include files?

@StoryTeller 's answer

Conventional wisdom is to add source files to every header.

is appropriate way to achieve the goal. It requires adding many source files. It is annoying work especially I develop a header only library.

How to automate that process?

I found a way to check missing include file on cmake. The strategy is compile each header files individually and directly.

Here is CMakeLists.txt

cmake_minimum_required(VERSION 3.8.2)
project(test_checker)

add_custom_target(chkdeps)

file(GLOB HDR_ROOT "*.hpp")
FOREACH (HDR ${HDR_ROOT})
message(STATUS "${HDR}")
get_filename_component(HDR_WE ${HDR} NAME_WE)
SET(CHK_TARGET "${HDR_WE}.chk")
add_custom_target(
${CHK_TARGET}
COMMAND ${CMAKE_CXX_COMPILER} -c ${HDR}
VERBATIM
)
add_dependencies(chkdeps ${CHK_TARGET})
ENDFOREACH ()

To check missing include files, execute make chkdeps.

In order to do only compile, I use add_custom_target. The custom target name is chkdeps (check dependencies). This is the target for all header files dependency checking.

I get the list of *.hpp using file(GLOB HDR_ROOT "*.hpp"). For each got files, I add custom target for only compile using add_custom_target.

I add the extension .chk to avoid conflict. For example if the file name is a.hpp then the target name is a.chk.

I execute the COMMAND ${CMAKE_CXX_COMPILER} with -c option. The -c option is for only compile. I only tested the cmake on Linux. I know setting compile option directly is not good for cross platform development. cmake might provides compile only cross platform mechanism. But I couldn't find it, so far.

Then I add dependency to chkdeps using add_dependencies. Due to this dependency, when I execute make chkdeps, all custom targets (a.chk and b.chk) run.

When I run make chkdeps, then I got the expected error "'func_a' was not declared in this scope" as follows.

make chkdeps                                                                                                                                                    
Built target a.chk
/home/kondo/work/tmp/fly_check/b.hpp: In function 'void func_b()':
/home/kondo/work/tmp/fly_check/b.hpp:3:5: error: 'func_a' was not declared in this scope; did you mean 'func_b'?
3 | func_a();
| ^~~~~~
| func_b
make[3]: *** [CMakeFiles/b.chk.dir/build.make:57: CMakeFiles/b.chk] Error 1
make[2]: *** [CMakeFiles/Makefile2:78: CMakeFiles/b.chk.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:113: CMakeFiles/chkdeps.dir/rule] Error 2
make: *** [Makefile:131: chkdeps] Error 2

How to tell the gcc to look in the include folder for the header files?

You can use the -I option with gcc to tell the path where to look for the header files.

From online gcc manual

-Idir
Add the directory dir to the head of the list of directories to be searched for header files. This can be used to override a system header file, substituting your own version, since these directories are searched before the system header file directories. [...]

You can use this option multiple times,

[...] If you use more than one -I option, the directories are scanned in left-to-right order; the standard system directories come after.

How do I find out which header/include declared what variables in source?

Since you are already using vim, I recommend installing the ctags package, which will allow you to jump to those declarations directly within the editor.

Once installed, create a ctags file. This will parse all the source code files in the specified paths, and create a file named tags:

ctags -R /usr/include .

Note that we specify /usr/include as well as the current directory, which presumably contains the source code you're reading. If that's in a different directory, specify that one instead.

After that completes (give it a moment), open the file you're interested in. If you're still in the same directory as the new tags file, vim will have already loaded it. Otherwise you would have to :set tags=/path/to/tags.

Now just place the cursor over a symbol you don't know, and press Ctrl-]. Alternatively, if you're using the GUI version of vim, you can left-click while holding Ctrl. Either way, this will jump to the declaration of the symbol.

Press Ctrl-T to go back to where you were.

Once you get the hang of this, check out :help tags and :help tagstack. vim has extensive support for working with them.

Where does gcc look for C and C++ header files?

`gcc -print-prog-name=cc1plus` -v

This command asks gcc which C++ preprocessor it is using, and then asks that preprocessor where it looks for includes.

You will get a reliable answer for your specific setup.

Likewise, for the C preprocessor:

`gcc -print-prog-name=cpp` -v

Identify which file has included some particular header file

Someone has posted about it but I can't find this answer.
So, In VS, go to your project properties. Choose Configuration Properties / C/C++ / Advanced / Show Includes and set "yes".

then compile you cpp file. It looks like this:
cpp file:

#include <stdio.h>

int main()
{
return 0;
}

In the output window after compiling you will see:

1>------ Build started: Project: stlport_project, Configuration: Release Win32 ------
1>Compiling...
1>stlport_project.cpp
1>Note: including file: D:\src\hrs_rt_059.00\HRS\modules\src\libs\src\external\stlport\5.1.7\stdio.h
1>Note: including file: D:\src\hrs_rt_059.00\HRS\modules\src\libs\src\external\stlport\5.1.7\stl/_prolog.h
1>Note: including file: D:\src\hrs_rt_059.00\HRS\modules\src\libs\src\external\stlport\5.1.7\stl/config/features.h

and so on

EDIT: reference to the same question Displaying the #include hierarchy for a C++ file in Visual Studio

Where is the implementation of included C++/C header files?

In general, the implementation is distributed as form of pre-compiled libraries. You need to tell the compiler where they are located.

For example, for gcc, quoting the online manual

-llibrary
-l library

Search the library named library when linking. [...]

and,

-Ldir

Add directory dir to the list of directories to be searched for -l.


Note: you don't need to explicitly specify the standard libraries, they are automatically linked. Rather, if you don't want them to be linked with you binary, you need to inform the compiler by passing the -nostdlib option.

How To Get g++ to list paths to all #included files

You need to invoke g++ with the -M option.

From the manual:

Instead of outputting the result of preprocessing, output a rule
suitable for make describing the dependencies of the main source file.
The preprocessor outputs one make rule containing the object file name
for that source file, a colon, and the names of all the included
files, including those coming from -include or -imacros command line
options.

It's worth reading the manual to consider the other -M sub options (-MM and -MF in particular may be of use).



Related Topics



Leave a reply



Submit