How can I print headers hierarchy? [duplicate] - c

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?

g++ -H ...
will also print the full path of include files in a format which shows which header includes which

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

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

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.

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).

For MSVC you can use the /showInclude 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.

Related

Is my understanding of C header files/gcc options related to these correct?

I am currently taking a class on C and I am baffled by gcc options a lot of the time, because the videos/documentation on the options are sparse and those that eixst are hard to understand(for idiots/non-technical majors like myself). Please consider the following scenario:
Lets say I have a header file, myHeader.h and main.c which would like to include myHeader.h. Assume they are in the same directory.
In main.c, I could write #include "myHeader.h". However, according to my professor the "" is permitted because gcc will check in the current directory for anything in the "". However, where I am lost is when it comes to how I could add myHeader.h to the gcc header file search path such that #include <myHeader.h> would work. I am wondering what gcc commands would work, and why they work in specific. I would love any references(that aren't super nerdy) to better understand this.
So far, I researched on stackoverflow and on google, and it said something about -Idir gcc command, where dir is the directory you would like to add to the header file search path, but I am confused as to why this works or how to actually implement it. Since the "path" to myHeader.h is CStuff/workspace/myHeader.h I attempted to do gcc -I/CStuff/workspace/myHeader.h but this didn't really work out. I really thought it would take that directory and add it to the header file search path, but it just gave me an error.
I am a very confused business major so please take it easy on me! I really would love a dumbed-down explanation or a reference to a source that is more "basic" and has more than 1-2 sentences of explanation(if possible).
However, where I am lost is when it comes to how I could add myHeader.h to the gcc header file search path such that #include <myHeader.h> would work.
If you want to add search path directory for system headers, there is -isystem <path>. For ordinary headers — which your header very likely is — there is -I <path>. This supports relative and absolute path formats.
To see which search paths GCC is using, add -v to the options:
> gcc main.c -v ...
...
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
There are more special options, see Directory-Options in the GCC documentation, if it comes to search order, for instance.
To see the outcome of including, i.e. the C-preprosessed file, use -save-temps and have a look at the preprocessed file *.i for C, *.ii for C++, *.s for assembly.
To also see built-in and explicit #define's values in preprocessed code, also add -H -g3.
In main.c, I could write #include "myHeader.h". However, according to my professor the "" is permitted because gcc will check in the current directory for anything in the "". However, where I am lost is when it comes to how I could add myHeader.h to the gcc header file search path such that #include <myHeader.h> would work.
As a preliminary matter, you are already lost when you conceive the idea that you should want to use that form for the private headers associated with your program. The <header.h> form is conventionally and best reserved for use with system headers. That is, exactly those that do not accompany the code being compiled.
That does not moot the question, however. Sometimes one might want to amend the header search path to help the compiler find headers distributed with the source code and referenced via the "header.h" form, too.
I am wondering what gcc commands would work, and why they work in specific. I would love any references(that aren't super nerdy) to better understand this.
You will not earn friends or respect here by eschewing technical references, nor by casting aspersions on those who do read such references. Technical documents can be hard reading at first, but reading and understanding them is a skill that you will need to cultivate if you want to enjoy success as a programmer.
So far, I researched on stackoverflow and on google, and it said
something about -Idir gcc command, where dir is the directory you
would like to add to the header file search path,
Good start.
but I am confused as
to why this works or how to actually implement it. Since the "path" to
myHeader.h is CStuff/workspace/myHeader.h I attempted to do gcc
-I/CStuff/workspace/myHeader.h but [...] it just gave me an error.
It is important to pay attention to details. You yourself wrote:
where dir is the directory you would like to add to the header file search path
(emphasis added). If /CStuff/workspace/myHeader.h is the header you want gcc to find, then that path is not the path of a directory. The directory is /CStuff/workspace, so -I/CStuff/workspace is a viable option.
Alternatively, for gcc runs in which the working directory is also /CStuff/workspace, you can refer to it by the name . (that is, use -I.). It is a general feature of Unix and Windows paths, not specific to gcc, that the . represents the current working directory.

autoconf configure results in C std lib header related compile errors

I am attempting to build a project that comes with an automake/autoconf build system. This is a well-used project, so I'm skeptical about a problem with the configure scripts, makefiles, or code as I received them. It is likely some kind of environment, path, flag, etc problem - something on my end with simply running the right commands with the right parameters.
The configuration step seems to complete in a satisfactory way. When I run make, I'm shown a set of errors primarily of these types:
error: ‘TRUE’ undeclared here (not in a function)
error: ‘struct work’ has no member named ‘version’
error: expected ‘)’ before ‘PRIu64’
Let's focus on the last one, which I have spent time researching - and I suspect all the errors are related to missing definitions. Apparently the print-friendly extended definitions from the C standard library header file inttypes.h is not being found. However, in the configure step everything is claimed to be in order:
configure:4930: checking for inttypes.h
configure:4930: /usr/bin/x86_64-linux-gnu-gcc -c -g -O2 conftest.c >&5
configure:4930: $? = 0
configure:4930: result: yes
All the INTTYPES flags are set correctly if I look in confdefs.h, config.h, config.log Output Variables, etc:
HAVE_INTTYPES_H='1'
#define HAVE_INTTYPES_H 1
The problem is the same whether doing a native build, or cross-compiling (for arm-linux-gnueabihf, aka armhf).
The source .c file in question does have config.h included as you'd expect, which by my understanding via the m4 macros mechanic should be adding an
#include <inttypes.h>
line. Yes, as you may be inclined to ask, if I enter this line myself into the .c file it appears to work and the PRIu64 errors go away.
I'm left with wondering how to debug this type of problem - essentially, everything I am aware of tells me I've done the configure properly, but I'm left with a bogus make process. Aside from trying every ./configure tweak and trick I can find, I've started looking at the auto-generated Makefile.in itself, but nothing so far. Also looking into how I can get the C pre-processor to tell me which header files it's actually inserting.
EDIT: I've confirmed that the -DHAVE_CONFIG_H mechanic looks good through configure, config.log, Makefile, etc.
autoconf does not automatically produce #include directives. You need to do that on your own based on the HAVE_* macros. So you'll have to add something like this:
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
If these lines show up in confdefs.h, a temporary header file used by configure scripts, this does excuse your application from performing these #includes. If configure writes them to confdefs.h, this is solely for the benefit of other configure tests, and not for application use.
First, run make -n for the target that failed. This is probably some .o file; you may need some tweaking to get its path correctly.
Now you have the command used to compile your file. If you don't find the problem by meditating on this command, try to run it, adding the -E to force preprocessor output text instead of invoking the compiler.
Note that now the .o file will be text, and you must rebuild it without -E later.
You may find some preprocessor flags useful to get more details: -dM or -dD, or others.

How to stop make (in makefile) after "No such file or directory" error?

So, most of the times I'm testing if every include is correct on a given C/C++ code, I have a makefile with a gcc/g++ call with proper -I option for searching headers on specific directories (like every program) when I'm compiling sources to headers.
However, if the included directory is not correct and an undefined header appears (e.g. foo.h has #include and was not found), the gcc/g++ will just spit a bunch of errors for every include I have of that foo.h header for all other sources I'm compiling afterwards (and I'm already using -Werror -Wfatal-errors to make gcc/g++ to stop).
So, my question is simple: how can I tell makefile stop after the first error of the type "No such file or directory" it finds? It is really annoying it continue to compile sources and sources, giving me hundreds of errors just for a repeated error I already understood.
It probably continues because you told it to. See the following two options of GNU make:
-k, --keep-going Keep going when some targets can't be made.
-S, --no-keep-going, --stop
Turns off -k.
Put the header files into a variable and use that variable as a dependency. The following snippet will not build anything until the specified headers exist.
HEADERS=test.h other.h /usr/include/special.h
all: $(HEADERS) $(BINPROGS)
[... all other rules go here as usual ...]
*.h:
echo found $#
The ".h:" simply prints out each header that is found before any building even starts. The makefile itself stops if a header cannot be found (and it will stop before trying to compile anything).
I believe that that is what you wanted?
you can write a shell script to check for error conditions before running the make script.

Compiling a C prog winth unix syle header files in windows

well i have a few Cpp source and header files, and the header files have include statements in the form,
#include<include/config.h>
#include<include/controls.h>
the thing is im using gcc on windows and it says no such file or directory as the windows style paths has '/' and not '\' ,
so i changed the path to include\config.h but again, the problem is config.h has many header files included in it with the similar unix path style, and its not feasible to change the paths in all the header files cos its a library and there are 100s of such headers, is there any way to compile this using GCC (minGW) ??
Thanks :)
this may sound like a silly problem, sorry if it is!!..
I don't think the direction of the / is the problem here. Windows should convert between the two for you when calling its API precisely for the purposes of (some) unix compatibility.
I think the problem is the include path. Try compiling your program with
gcc -o output.exe -I"c:\path\to\directory\above\include" file.c
So that in the directory you specify with the include flag, there is a subdirectory "include" containing your headers. This assumes all your paths in your other headers are relative to this.
config.h and controls.h are not standard header files. Try this instead:
#include "include/config.h"
#include "include/controls.h"
Even better would be to use the command line to specify the include directory and use
#include "config.h"
#include "controls.h"
Probably mingw uses the same option as all other c compilers: (compiler name) -I(directory name)...
As others have stated, / vs. \ is a non-issue. Even Microsoft compilers and utilities accept / everywhere. The use of \ is a historical mistake, perpetrated needlessly.
A good discussion of your issue can be seen here:
How to generate a OS independent path in c++
Don't change forward slash / to back-slash \ - you are making the compiler to interpret the next character as a special character \c. GCC has no problem dealing with UNIX-style paths on Windows. The problem is probably the lack of -I directive to the compiler - something like -I. to search for files in current and sub-directories.

Including a library (lsusb) in a C program

I am still fairly new to programming with C and I am working on a program where I want to control the power to various ports on a hub I have. That is, however, not the issue I am having right now.
I found a program online that does what I want I am trying to compile it. However it uses #include<lsusb.h>. lsusb is located in a totally different folder than the file I am wanting to run (and not in a sub folder) and when I try to compile it, I, logically enough, get the error that the file lsusb.h is not found.
How can I link to this file so that it can be found?
This is more of a GCC toolchain question than a C question (although most C compilers do use the same Unixy flags).
The braces around the include file (<>) indicate you want the compiler to search its standard search path for the include file. So you can get access to that new include file either by putting it into a directory on your standard include file search path yourself, or by adding its directory to the file search path. With GCC you do the latter by giving gcc the flag -I"directoryname" where "directoryname" is the full file path to where you are keeping that new include file of yours.
Once your compiler finds it, your linker may have the exact same problem with the library file itself ("liblsusb.a"?). You fix that the same way. The flag GCC's linker will want is -L instead of -I.
See the "-I" parameter in the gcc man page. It allows you specify a directory in which to find a header file. See also -l and -L.
Or try #include "../../path_to_the_file/lsusb.h"

Resources