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
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.
Reading the fine print of the -I switch in GCC, I'm rather shocked to find that using it on the command line overrides system includes. From the preprocessor docs
"You can use -I to override a system header file, substituting your own version, since these directories are searched before the standard system header file directories."
They don't seem to be lying. On two different Ubuntu systems with GCC 7, if I create a file endian.h:
#error "This endian.h shouldn't be included"
...and then in the same directory create a main.cpp (or main.c, same difference):
#include <stdlib.h>
int main() {}
Then compiling with g++ main.cpp -I. -o main (or clang, same difference) gives me:
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:194:0,
from /usr/include/stdlib.h:394,
from /usr/include/c++/7/cstdlib:75,
from /usr/include/c++/7/stdlib.h:36,
from main.cpp:1:
./endian.h:1:2: error: #error "This endian.h shouldn't be included"
So stdlib.h includes this types.h file, which on line 194 just says #include <endian.h>. My apparent misconception (and perhaps that of others) was that the angle brackets would have prevented this, but -I is stronger than I'd thought.
Though not strong enough, because you can't even fix it by sticking /usr/include in on the command line first, because:
"If a standard system include directory, or a directory specified with -isystem, is also specified with -I, the -I option is ignored. The directory is still searched but as a system directory at its normal position in the system include chain."
Indeed, the verbose output for g++ -v main.cpp -I/usr/include -I. -o main leaves /usr/include at the bottom of the list:
#include "..." search starts here:
#include <...> search starts here:
.
/usr/include/c++/7
/usr/include/x86_64-linux-gnu/c++/7
/usr/include/c++/7/backward
/usr/lib/gcc/x86_64-linux-gnu/7/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
Color me surprised. I guess to make this a question:
What legitimate reason is there for most projects to use -I considering this extremely serious issue? You can override arbitrary headers on systems based on incidental name collisions. Shouldn't pretty much everyone be using -iquote instead?
What legitimate reasons are there for -I over -iquote? -I is standardized (at least by POSIX) while -iquote isn't. (Practically, I'm using -I because tinycc (one of the compilers I want my project to compile with) doesn't support -iquote.)
How do projects manage with -I given the dangers? You'd have the includes wrapped in a directory and use -I to add the directory containing that directory.
filesystem: includes/mylib/endian.h
command line: -Iincludes
C/C++ file: #include "mylib/endian.h" //or <mylib/endian.h>
With that, as long as you don't clash on the mylib name, you don't clash (at least as far header names are concerned).
Looking back at the GCC manuals it looks like -iquote and other options were only added in GCC 4: https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Directory-Options.html#Directory%20Options
So the use of "-I" is probably some combination of: habit, lazyness, backwards compatibility, ignorance of the new options, compatibility with other compilers.
The solution is to "namespace" your header files by putting them in sub directories. For example put your endian header in "include/mylib/endian.h" then add "-Iinclude" to the command line and you can #include "mylib/endian.h" which shouldn't conflict with other libraries or system libraries.
I this your premise that it's -I that's dangerous is false. The language leaves the search for header files with either form of #include sufficiently implementation-defined that it's unsafe to use header files that conflict with the names of the standard header files at all. Simply refrain from doing this.
An obvious case is cross-compilation. GCC suffers a bit from a historical UNIX assumption that you're always compiling for your local system, or at least something that's very close. That's why the compiler's header files are in the system root. The clean interface is missing.
In comparison, Windows assumes no compiler, and Windows compilers do not assume you're targeting the local system. That's why you can have a set of compilers and a set of SDK's installed.
Now in cross-compilation, GCC behaves much more like a compiler for Windows. It no longer assumes that you intend to use the local system headers, but lets you specify exactly which headers you want. And obviously, the same then goes for the libraries you link in.
Now note that when you do this, the set of replacement headers is designed to go on top of the base system. You can leave out headers in the replacement set if their implementation would be identical. E.g. chances are that <complex.h> is the same. There's not that much variation in complex number implementations. However, you can't randomly replace internal implementation bits like <endian.h>.
TL,DR : this option if for people who know what they're doing. "Being unsafe" is not an argument for the target audience.
Let us assume that in first.h we have #include "aaa/second.h" and in the aaa/second.h we have #include "bbb/third.h". I think that in the "default settings" the compiler will complain if "third.h" is not located in "aaa/bbb".
Is it possible to change this behavior in such a way that the directory, in which the first.cpp is located is used to construct the full names in all includes?
For example, if "first.h" is located in '/home/bucky/' then #include "bbb/third.h" (from "aaa/second.h") should be interpreted as /home/bucky/bbb/third.h and not as /home/bucky/aaa/bbb/third.h.
EDITS
I cannot change the whole source code. In the code quotation marks are used instead of angle brackets.
I compile using g++ -std=c++0x name.cpp -o name in the command line. I do it in two different terminals. It looks like in the first terminal the working directory is used to construct the full names and in the second terminal it is not the case. I am almost sure that it happens because of the environment variables but I do not know which ones. So, my question is, to larger extent, what environment variables can force the compiler to construct full names using the working directory.
EDIT 2
In my test.cpp file I include "first.h". This inclusion does not cause any problem (complier sees "first.h"). The "first.h" file includes "ppp/second.h". It also causes no problems. But "ppp/second.h" includes "ppp/third.h" and this is the place where the problem appears. I think that the reason of the problem is that "second.h" tries to find "third.h" in the "ppp" subdirectory of the directory where second.h is located. In other words, second.h tries to find the third.h in the "ppp/ppp" subdirectory (because second.h is located in the ppp subdirectory).
In another terminal, the same compilation command, in the same directory does not cause any problem. The reason, is obviously in the values of the environment varibales.
Yes. The exact mechanics depend on the compiler but the short and the long of it is that you need to configure your compiler to include the project path in the search path. For GCC and clang that’s done via the -I command line flag (-I path/of/first.cpp). This configuration would usually be done in the project settings (if you’re working with an IDE), a Makefile or similar.
Since you’re talking about environment variables: the flags that are passed to the g++ and c++ compiler are controlled by the CXXFLAGS and CFLAGS variables.
You should set up include paths for your project globally. In your example, you would pass some option like -I /home/bucky to your compiler (if it is GCC or Clang). MSVC has analogous options.
(All #includes are searched relative to the include paths. The difference between <...> and "..." is that the latter also searches the current directory.)
It's been a while since I've dealt with C/C++, so forgive me if this is a ridiculously easy to answer question - I just don't quite know how to "Google" it.
I have a file, "MyFile.h" that includes file "includedFile.h". However, the compiler cannot find the file. Please see below picture:
What I'm doing is moving the project from an old Solaris box to a Linux box. The weird thing is that it worked on the Solaris box as-is but Linux is a little confused.
The makefile that I use for the project hasn't changed either which makes me think that it may be a compiler option...
So how do I tell the compiler on Linux where that include file is, or how do I specify it in "MyFile.h?"
With gcc and clang, you specify the include path using -I:
g++ -o myprogram main.cc extra.cc -I/usr/include/boost -I/my/extra/include/files
You can specify full paths in your files, as in #include "/path/to/my/includedfile.h", but I strongly discourage this as it forces everyone who wants to compile your code to comply with that directory layout.
Also relevant: Read the following link for the difference between #include <file> and #include "file" in gcc: http://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html
Assuming you are using g++, you pass a path with the -I flag.
g++ ..... -I<a path to your includes> -I<another path to includes>
My code is linking against several other libraries that are also developed at my company, one of these libraries is redefining several values from errno.h, I would like to be able to fix this, however I am having trouble finding the exact file that is redefining these values, I am want to know if there is a way to make the compiler tell me when a file has defined a particular value.
You can probably do it by adding -include errno.h to the command line that builds the library in question. Here's a quick example. I have a C program called "file.c":
#define ESRCH 8
That's it - then I compile with:
cc -c -include errno.h file.c
And presto, a compiler warning:
file.c:1:1: warning: "ESRCH" redefined
In file included from /usr/include/errno.h:23,
from <command-line>:0:
/usr/include/sys/errno.h:84:1: warning: this is the location of the previous definition
That will tell you where your bad definitions are.
Have you tried searching with grep?
If you don't want to search through all your headers for the particular #define, you could use
#undef YOUR_MANIFEST_CONSTANT
after each #include in your source module and then start removing them from the bottom up and see where your definitions come from.
Also, your compiler may tell you that a #define has been redefined. Turn all your warnings on.
With GCC I did something similar with:
g++ input.cc -dD -E > cpp.out
-dD tells cpp to print all defines where they were defined. And in the cpp output there are also markers for the include file names and the line numbers.
It is possible that some environments, I'm thinking IDE's here, have configuration options tied into the "project settings" rather than using a configuration header. If you work with a lot of other developers in a place where this behavior is NOT frowned on then you might also check your tool settings.
Most compilers will tell you where the problem is, you have to look and think about what the diagnostic notification is telling you.
Short of that, grep/findstr on *nix/Windows is your friend.
If that yields nothing then check for tool settings in your build system.
Some IDE's will jump to the correct location if you right click on the usage and select 'go to definition'.
Another option if you're really stuck is a command line option on the compiler. Most compilers have an option to output the assembler they generate when compiling C++ code.
You can view this assembler (which has comments letting you know the relative line number in the C++ source file). You don't have to understand the assembler but you can see what value was used and what files and definitions were included when the compiler ran. Check your compiler's documentation for the exact option to use