gcc - how to find path of header include file - c++

Do we have any option in gcc to find from where a particular file header is included.
I have the following scenario :
file_1.h :
declare type of type_1
file_2.h :
type_1 var;
I want to check where was file_1.h included in the library that i am creating.

gcc has an option -M:
-M 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.
If you do, gcc -M filename.c, it'll list out all headers. Same with g++.

If you look at the preprocessed output it will show the headers that were included, in the order they were included, so you can see where file_1.h appears and work backwards to see which file included it, and which file included that etc.
The -E option tells GCC to only perform the preprocessing step and to stop before compilation.

Related

Using clang or g++/gcc to print preprocessed code without including files from system paths

currently I'd like to debug my includes. To do this I want to get the preprocessed code, but without any system header files - just my own code.
I tried it with flag "-E" and "-nostdinc". But then I get errors that for example <string> is missing. How to disable such preprocessing errors?
How to disable such preprocessing errors?
You could create a set of headers files with names matching the standard library headers. Put those headers in the include directory. Let the files be empty.
Using clang or g++/gcc to print preprocessed code without including files from system paths
I can see two other approaches besides the empty header approach:
Instead of using the full pre-processor of the compiler, write your own pre-processor that only does the subset of processing that you want.
Or, write a post-pre-processor that removes the standard header content from the pre-processed result.
(It's not really an answer - just a "hack")
To solve this I created a text file with all system headers by:
rem my GCC STL-PATH
cd Z:\usr\include\c++\10
dir /b > F:\DummySTL\files.txt
Then I executed the following line of code:
for /f "delims=" %F in (files.txt) do copy nul "%F"
This creates an empty text file for every line in the file.
Now I can call gcc or clang just with:
-isystem"F:\DummySTL"
Using clang or g++/gcc to print preprocessed code without including files from system paths
This is not easily possible with GCC. Read about how to invoke GCC.
But you could get all the preprocessed code using g++ -C -E and use some script (perhaps with GNU gawk) to remove the useless parts.
currently I'd like to debug my includes.
I have the habit of generating all the preprocessed code and then use GNU less to look inside it. Disk space is cheap.
Alternatively, consider writing your own GCC plugin doing what you need.

What is the correct way to include a proto file in C++?

I'm trying to learn C++ but I'm failing at some basic steps, like this one. I have a .proto file that needs to be included from a .cc file.
I added the line:
#include "path/to/my/protofile.pb.h"
I edited the matching BUILD file, by adding:
proto_library(
name = "protofile_proto",
srcs = ["//path/to/my:protofile.proto"],
visibility = [
"//visibility:public",
],
)
When I try to compile it, I get the following error:
path/to/my/ccfile.cc
fatal error: 'path/to/my/protofile.pb.h' file not found
Any idea on how to get the compiler to find the proto file at build time? Thanks in advance.
When you use double-quotes " in #include, the path is relative from the source file itself. And if it's not found then the compiler will search through its list of standard (and non-standard) directories to find the header file.
So there are two alternative solutions for you:
Make sure to give the correct relative path from the source file; Or
Add a suitable directory to the compilers list, usually using an -I (upper-case i) option (note that for this you might as well use <> instead of double-quotes)
Depending on build-system you need to add path/to/my/protofile.pb.h as a dependency for the source file, to make sure it's generated before the source file itself will be passed to the compiler.

How to list .hpp header files as they are being built with CMake

I have a number of C++ header files that don't have an implementation file and are self-contained. Each of these files end with .hpp, in standing with one of my conventions.
When I compile my project now it only lists(via stdout) the the .cpp that are being built, but not any of the .hpp files. So how can I list the .hpp files as they are being built? I am using CMake 3.13, if that helps.
Linux answer:
Remember Cmake does not compile, although you can do cmake --build . , this works just as as calling make in the folder where you ran the cmake ../.. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=DEBUG. So Cmake is just a build generator but not an actual builder.
The make command also doesn't build, it just reads some script/text files (let's call them this for simplicity) and in them it has the rules to invoke the desired compiler (GCC, CLANG, etc). So the headers are shown at the precompilation phase by the compiler. That is handled by the compiler. So if you want to see all the headers included you need to tell the compiler to show them to you
Try and add -M as a compiler flag (i assumed that you are compiling with GCC)
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.
A smaller output flag would be -H
-H Print the name of each header file used, in addition to other normal activities. Each name is indented to show how deep in the
‘#include’ stack it is. Precompiled header files are also printed,
even if they are found to be invalid; an invalid precompiled header
file is printed with ‘...x’ and a valid one with ‘...!’ .

Creating several precompiled header files using GNU make

I use gcc (running as g++) and GNU make.
I use gcc to precompile a header file precompiled.h, creating precompiled.h.gch; the following line in a Makefile does it:
# MYCCFLAGS is a list of command-line parameters, e.g. -g -O2 -DNDEBUG
precompiled.h.gch: precompiled.h
g++ $(MYCCFLAGS) -c $< -o $#
All was well until i had to run g++ with different command-line parameters.
In this case, even though precompiled.h.gch exists, it cannot be used, and the compilation will be much slower.
In the gcc documentation i have read that to handle this situation,
i have to make a directory called precompiled.h.gch and put
the precompiled header files there,
one file for each set of g++ command-line parameters.
So now i wonder how i should change my Makefile to tell g++ to create
the gch-files this way.
Maybe i can run g++ just to test whether it can use any existing file
in the precompiled.h.gch directory,
and if not, generate a new precompiled header with a unique file name.
Does gcc have support for doing such a test?
Maybe i can implement what i want in another way?
It seems weird to answer my own question; anyway, here goes.
To detect whether a suitable precompiled header file exists, i add a deliberate error to my header file:
// precompiled.h
#include <iostream>
#include <vector>
...
#error Precompiled header file not found
This works because if gcc finds a precompiled header, it will not read the .h file, and will not encounter the error.
To "compile" such a file, i remove the error first, placing the result in a temporary file:
grep -v '#error' precompiled.h > precompiled.h.h
g++ -c -x c++ $(MYCCFLAGS) precompiled.h.h -o MORE_HACKERY
Here MORE_HACKERY is not just a plain file name, but contains some code to make a file with unique name (mktemp). It was omitted for clarity.
There is a simpler way than introducing an #error in precompiled.h: never create this file at all. Neither G++ nor Visual C++ (at least up to 2005) expect the "real" file to be there, if a precompiled version is around (and if they get the necessary compilation flags).
Let's say the list of #includes that we want to precompile is called "to_be_precompiled.cpp". The filename extension doesn't matter much, but I don't like to call this a .h file, since it has to be used in a way different from genuine header files, and it's easier in Visual C++ if this is a .cpp. Then pick a different name to refer to it throughout the code, let's say "precompiled_stuff". Again, I I don't like to call this a .h file, because it's not a file at all, it's a name to refer to precompiled data.
Then in all other source files, the statement #include "precompiled_stuff" is not a genuine include, but simply loads precompiled data. It's up to you to prepare the precompiled data.
For g++, you need a build rule to create "precompiled_stuff.gch" from a source file whose name doesn't matter to the compiler (but would be "to_be_precompiled.cpp" here).
In Visual C++, the string "precompiled_stuff" equals the value of the /Yu flag and the precompiled data loaded comes from a .pch file with an unrelated name, that you also created from an unrelated source file (again "to_be_precompiled.cpp" here).
Only when building with a compiler without precompiled header support, a build rule needs to generate an actual file called "precompiled_stuff", preferably in the build directory away from the real source files. "precompiled_stuff" is either a copy of "to_be_precompiled.cpp", a hard or symbolic link, or a small file containing #include "to_be_precompiled.cpp".
In other words, you take the viewpoint that every compiler supports precompilation, but it's just a dumb copy for some compilers.

Which directories does include statement search in C/C++?

test.c:
#include "file.h"
In the above statement, which directories will be searched ?
I suppose the directory where test.c locates will be searched, right?
But is that all?
BTW, what's the benefit to use a header file? Java doesn't require a header file...
#include <header_name>: Standard include file: look in standard paths (system include paths setup for the compiler) first
#include "header_name": Look in current path first, then in include path (project specific lookup paths)
The benefit of using a header file is to provide others with the interface of your library, without the implementation. Java does not require it because java bytecode or jar is able to describe itself (reflexion). C code cannot (yet) do it.
In Java you would only need the jar and have the correct use statement. In C you will (mostly) need a header and a lib file (or header and dll).
The other reason is the way c code is compiled. The compiler compiles translation units (a c/cpp file with all included headers) and the linker in a second step links the whole stuff. Declarations must not be compiled, and this saves time and avoid code to be useless generated for each compilation unit which the linker would have to cleanup.
This is just a general idea, I am not a compiler specialist but should help a bit.
It's controlled by your compiler. For example, gcc has a -I option to specify the include path.
C and C++ prototypes are required so the compiler (distinguished from the linker) can make sure functions are being called with the correct arguments. Java is different in that the compiler uses the binary .class files (which unlike C are in a standard bytecode format with all type information preserved) to check that calls are valid.
Using quotes after the #include instructs the preprocessor to look for include files in the same directory of the file that contains the #include statement, and then in the directories of any files that include (#include) that file. The preprocessor then searches along the path specified by the /I compiler option, then along paths specified by the INCLUDE environment variable.
If you use the angle bracket form, it instructs the preprocessor to search for include files first along the path specified by the /I compiler option, then, when compiling from the command line, along the path specified by the INCLUDE environment variable.
The C++ Standard doesn't really say which directories should be searched. This is how the C++ Standard describes what happens when #include "somefile.h" is encountered:
A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that
directive by the entire contents of
the source file identified by the
specified sequence between the "
delimiters. The named source file is
searched for in an
implementation-defined manner. If this
search is not supported, or if the
search fails, the directive is
reprocessed as if it read
# include <h-char-sequence> new-line
with the identical contained sequence
(including > characters, if any) from
the original directive.
So exactly what directories are searched are at the mercy of your specific C++ implementation.
strace, or truss, etc., may be helpful. For example, create a file foo.c with the single line #include "foo.h". Then on CYGWIN, the command:
strace /usr/bin/gcc-4.exe foo.c | grep 'src_path.*foo.h,' | sed 's/.*src_path //;s/foo.h.*//'
produces:
foo.c:1:22: error: foo.h: No such file or directory
/home/Joe/src/utilities/
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include-fixed/
/usr/include/
/usr/include/w32api/
I was actually surprised this list was so short: the last time I did this exercise, on SunOS 4 fifteen years ago, the search path had over a dozen directories.
The first directory, obviously, is where foo.c lives. See aslo http://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html for the environment variables CPATH and C_INCLUDE_PATH. But these are not set on my machine. (And I am unclear whether CYGWIN uses them, anyway.)
Edit: The simplest solution is to use cpp -v (not gcc -v). It gives:
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=i686'
/usr/lib/gcc/i686-pc-cygwin/4.3.4/cc1.exe -E -quiet -v -D__CYGWIN32__ -D__CYGWIN__
-Dunix -D__unix__ -D__unix -idirafter /usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../..
/include/w32api -idirafter
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/lib/../../include/w32api -
-mtune=generic -march=i686
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/include"
ignoring duplicate directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/lib/../../include/w32api"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include-fixed
/usr/include
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../include/w32api
End of search list.