How to specify location of angle-bracket headers in gcc/g++? - c++

Is there a way to tell gcc/g++/clang where to look for headers that are included via angle brackets ("<", ">")?
I don't use the angle bracket convention for non-system files, but the problem is that when I try using the headers from some packages I download, I get errors for all of the included files.
For example, say I want to include headers from a module called Foo that I download:
/foo-v1.0/include/DependencyA.hpp:
#ifndef DEP_A_HPP
#define DEP_A_HPP
class DependencyA
{
...
};
#endif
/foo-v1.0/include/Api.hpp:
#ifndef FOO_HPP
#define FOO_HPP
#include <Foo/DependencyA.hpp>
void doSomething(DependencyA* da);
#endif
Then, in my own code:
/mycode.cpp:
#include "/foo-v1.0/include/Api.hpp"
DependencyA* da = new DependencyA();
doSomething(da);
I get a compile error:
fatal error: 'Foo/DependencyA.hpp' file not found
I've tried building with:
clang -c mycode.cpp -isystem./foo-v1.0/include -o mycode.o
clang -c mycode.cpp -isystem./foo-v1.0/include/ -o mycode.o
clang -c mycode.cpp -I./foo-v1.0/include -o mycode.o
clang -c mycode.cpp -I./foo-v1.0/include/ -o mycode.o
and so on, to no avail.
How do I tell the compiler to resolve <Foo/**/*> to a particular root directory for every included file?

The answer is already in the comments.
To check include dirs one can use the method described here: What are the GCC default include directories? , preferably with - replaced with /dev/null:
clang -xc -E -v /dev/null
On my machine for clang it gives
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/clang/11.0.0/include
/usr/include
End of search list.
To discover how to manipulate this list, it suffices to read the gcc (or clang) manual (man clang or find it in the Internet, for example, https://man7.org/linux/man-pages/man1/gcc.1.html ). For gcc this reads:
Options for Directory Search
These options specify directories to search for header files, for
libraries and for parts of the compiler:
-I dir
-iquote dir
-isystem dir
-idirafter dir
Add the directory dir to the list of directories to be searched
for header files during preprocessing. If dir begins with = or
$SYSROOT, then the = or $SYSROOT is replaced by the sysroot
prefix; see --sysroot and -isysroot.
Directories specified with -iquote apply only to the quote form
of the directive, "#include "file"". Directories specified with
-I, -isystem, or -idirafter apply to lookup for both the
"#include "file"" and "#include <file>" directives.
This description is followed by a detailed description of the order in which header files are searched and by some recommendations as to which option to use for which purpose. You'll find it in the manual. Search for "Options for Directory Search".
What I really don't like in your code is this line:
#include "/foo-v1.0/include/Api.hpp"
It seems to contain the absolute path to the header and I've never seen anything like this. I would change it to
#include "Api.hpp"
with /foo-v1.0/include being added to the search list via the usual compiler -I command-line option.

Related

C++ compiler "no such file or directory" even with include flag set

I have never used a package manager for C++ packages until today. I finally got one to semi work, called cget. I'm trying to use a package called nlohmann/json and from their documentation I just need to run cget install nlohmann/json. The issue is that this puts the include header files in the directory /cget/include/nlohmann which (I assume) the g++ compiler doesn't look in for headers. So I manually moved the nlohmann directory into the /usr/include directory. When I compile with g++ test.cpp -o test it fails with the error "No such file of directory". I clearly see the file in the include path, so what am I missing?
// test.cpp
#include <nlohmann/json.hpp>
I've tried using the Include flag g++ -I /usr/include test.cpp -o test and it still fails.
The path to the json.hpp file is /usr/include/nlohmann/json.hpp
When I run `g++ -print-prog-name=cc1plus` -v it gives:
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/9
/usr/include/x86_64-linux-gnu/c++/9
/usr/include/c++/9/backward
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include
End of search list.
What is causing this error to persist?

Instruct compiler to ignore header prefix found in a #include

[As Cornstalks explained below, I'm trying to strip a header prefix that's used in an #include. So it appears this question is not a duplicate of How to make g++ search for header files in a specific directory?]
I'm making some changes to a library. I have the library locally, so its not installed in its customary system location.
I have a test source file and its sided-by-side with the library. The test file has a bunch of includes like:
#include <foo/libfoo.h>
And it also has a bunch of customary includes, like:
#include <iostream>
I'm trying to compile the test file using:
$ g++ ecies-test.c++ -I. -o ecies-test.exe ./libcryptopp.a
And (the space between -iquote . does not appear to make a difference):
$ g++ ecies-test.c++ -I. -iquote . -o ecies-test.exe ./libcryptopp.a
The problem I am having is I don't know how to tell g++ that <foo/libfoo.h> means "./libfoo.h". Effectively, I'm trying to strip the prefix used to include the header. I've looked in the manual under 2.3 Search Path, but it does not really discuss this scenario.
I have about 60 extra test files I use for the library. And each has 10 or 20 includes like this. So I can't go through and change #include <foo/libfoo.h> to #include "./libfoo.h" in 500 or 600 places.
I tried #rici's work around by creating the fictitious directory structure, but it broke GDB debugging. GDB cannot find symbols for class members, so I can't set breakpoints to debug the code I am attempting to modify.
How do I tell the compiler to look in PWD for system includes?
Below is a typical error. ECIES_FIPS is in my local copy of the library.
$ g++ -DNDEBUG=1 -g3 -Os -Wall -Wextra -I. -iquote . ecies-test.c++ -o ecies-test.exe ./libcryptopp.a
ecies-test.c++:29:17: error: no member named 'ECIES_FIPS' in namespace
'CryptoPP'
using CryptoPP::ECIES_FIPS;
~~~~~~~~~~^
ecies-test.c++:44:5: error: use of undeclared identifier 'ECIES_FIPS'
ECIES_FIPS<ECP>::Decryptor decryptor(prng, ASN1::secp256r1());
^
ecies-test.c++:44:16: error: 'ECP' does not refer to a value
ECIES_FIPS<ECP>::Decryptor decryptor(prng, ASN1::secp256r1());
^
/usr/local/include/cryptopp/ecp.h:30:20: note: declared here
class CRYPTOPP_DLL ECP : public AbstractGroup<ECPPoint>
...
In case it matters:
$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin12.6.0
Thread model: posix
There is no option which tells gcc to ignore directory prefixes in include paths. If your program contains #include <foo/header.h>, there must be some path_prefix in the include list such that path_prefix/foo/header.h resolves to the desired file.
While you cannot configure gcc to ignore the foo, you can certainly modify the filesystem as you please. All you need is that there be somewhere a directory foo which maps onto the directory where the header files are stored. Then you can add the parent of that directory to the search path.
For example:
mkdir /tmp/fake
ln -s /path/to/directory/containing/header /tmp/fake/foo
gcc -I /tmp/fake ... # Ta-daa!
Using the -I option to add the current folder as an include directory, you could create a folder called "foo" in the current directory and put your libfoo.h file inside.
Obviously, this doesn't strip the "foo" prefix in your #include, but it is a workaround.
I have about 60 extra test files I use for the library. And each has 10 or 20 includes like this. So I can't go through and change #include to #include "./libfoo.h" in 500 or 600 places.
If the above criteria is just a matter of convenience, then a tool like sed can be used to do all the work. Something like
$ sed -i 's/\(^\s*#include\s*[<"]\)foo\/\([^>"]*[>"]\s*$\)/\1\2\t\/\/ This line was replaced/' *
will replace all the occurrences of #include <foo/file.h> with #include <file.h> (you might have to adjust it slightly, I'm on a Windows machine at the moment and can't test it). This will work if all the files are in the PWD. If there is a more complex file structure, then it can be used in conjunction with grep and xargs.
NOTE: Make sure that the svn directories are ignored when using.

Where is the -I (captial i) path relative to in g++?

I am in the App folder of my project. I run the following command to compile character.cpp
g++ -Wall -std=c++11 -I../App -c Character/character.cpp -o Obj/character.o
which is in App/Character directory. character.cpp has the following include
#include "Inventory/inventory.hpp"
where the folder of inventory.cpp is App/Inventory.
I thought because I am running the g++ command from App, the default include path would start from App and therefore I wouldn't need to have the -I../App part of the command. To me this seems to be saying "move one level higher than App then move into App and include from there" which seems redundant but without that line it doesn't work.
Can anyone explain why?
EDIT
Looking at it again and some more documentation, I believe that if no -I path is specified, g++ will look in its default directories and then all other includes (like the one I have causing problems) are relative to the file that includes them. So I have to add the -I part to say "look in the App directory too" and since it doesn't like just -I, I have to use ../App because that is equivalent to not moving at all. Can anyone confirm if this is at all accurate?
You can use -I. for searching headers from the current directory, instead of -I../App.
This include preprocessor directive
#include "Inventory/inventory.hpp"
forces gcc (g++ or cpp) to search the header not from the current path (App/), but from directory of your source file (App/Character):
/root/App# strace -f g++ -c -H ./Character/character.cpp 2>&1 |grep Inven
[pid 31316] read(3, "#include \"Inventory/inventory.hp"..., 35) = 35
[pid 31316] stat64("./Character/Inventory/inventory.hpp.gch", 0xbfffe6a4) = -1 ENOENT (No such file or directory)
[pid 31316] open("./Character/Inventory/inventory.hpp", O_RDONLY|O_NOCTTY) = -1 ENOENT (No such file or directory)
..then try system directories
This is documented here: https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
GCC looks for headers requested with #include "file" first in the directory containing the current file
This behavior can be not fixed in the Language standard (ISO C), and is implementation-defined (as commented by Richard Corden and answered by piCookie in What is the difference between #include <filename> and #include "filename"?):
specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner.
But this is the way the C compiler should work under Unix, according to Posix, aka The Open Group Base Specifications Issue 7:
Thus, headers whose names are enclosed in double-quotes ( "" ) shall be searched for first in the directory of the file with the #include line, then in directories named in -I options, and last in the usual places. For headers whose names are enclosed in angle brackets ( "<>" ), the header shall be searched for only in directories named in -I options and then in the usual places. Directories named in -I options shall be searched in the order specified.
It is useful when your current directory is far from the source directory (this is the recommended way in autotools/autoconf: do mkdir build_dir5;cd build_dir5; /path/to/original/source_dir/configure --options; then make - this will not change source dir and will not generate lot of file in it; you can do several build with single copy of source).
When you start g++ from the App directory with -I. (or with -I../App or -I/full_path/to/App), gcc (g++) will find the Inventory. I added warning to the header to see when it will be included; and -H option of gcc/g++ prints all included headers with pathes:
/root/App# cat Inventory/inventory.hpp
#warning "Inventory/inventory.h included"
/root/App# cat Character/character.cpp
#include "Inventory/inventory.hpp"
/root/App# g++ -I. ./Character/character.cpp -H -c
. ./Inventory/inventory.hpp
In file included from ./Character/character.cpp:1:
./Inventory/inventory.hpp:1:2: warning: #warning "Inventory/inventory.h included"

g++ compiler option using `pkg-config...` results in -I(directory) What does the -I mean?

I am familiar with very simple g++ commands that compile and link programs, however when working with GTK+ I found the tutorial indicate that I should use pkg-config --cflags gtk+-2.0
Now when I type in pkg-config --cflags gtk+-2.0 to the terminal I get a list of libraries and files like this...
-pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/harfbuzz
So my question is, what does the -I mean in front of a directory? For example -I/usr/include/libpng12
The -I flag is used to add directories to the list of directories to search for finding files in #include <> statements.
In your case, when a file is included by using #include, /usr/include/libpng12 will be one of the directories in which the pre-processor will search for the file.
Please read the manual. All command line options are present there :-)
-I set the search path for libraries.
https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
-I is simply adding to the paths to be searched for header files. Note that these are searched before system paths.
You can find pretty much all the options for gcc/g++ here. In this case, you want the Directory Search options specifically; see here. From that page:
-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. However, you
should not use this option to add directories that contain
vendor-supplied system header files (use -isystem for that).
If you use more than one -I option, the directories are scanned in
left-to-right order; the standard system directories come after. 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. This is to ensure that GCC's
procedure to fix buggy system headers and the ordering for the
include_next directive are not inadvertently changed. If you really
need to change the search order for system directories, use the
-nostdinc and/or -isystem options.
As the answers from #R Sahu #Klaus and #Yuushi explain, the -I dir tells the compiler where to look for the #include header.h file.
When the program is compiled, it will be linked. You will probably also need to tell the linker where to find the programs that support the functions in the #included headers. This is done with the -llibrary flag. That is a lower case l not a one (1).
The pkg-config command references a set of files and will supply the compiler flags --cflags and link flags --ldflags if you supply the package name.
Put the returned -Includes before the source name(s) and the -l's after in your compile command request.
For other than casual, one-off programs, you should use make. The cflag and ldflag info can be put in variables in the Makefile and referenced throughout your make script.
You can get a complete list of packages configured to pkg-config on your Ubuntu system with locate *.pc

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

On a Unix system, where does gcc look for header files?
I spent a little time this morning looking for some system header files, so I thought this would be good information to have here.
`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
In addition, gcc will look in the directories specified after the -I option.
You can create a file that attempts to include a bogus system header.
If you run gcc in verbose mode on such a source, it will list all the system include locations as it looks for the bogus header.
$ echo "#include <bogus.h>" > t.c; gcc -v t.c; rm t.c
[..]
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc/i686-apple-darwin9/4.0.1/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
[..]
t.c:1:32: error: bogus.h: No such file or directory
The CPP Section of the GCC Manual indicates that header files may be located in the following directories. From the Search Path page:
GCC looks in several different places for headers. On a normal Unix system, if you do not instruct it otherwise, it will look for headers requested with #include in:
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
For C++ programs, it will also look in /usr/include/g++-v3, first.
To get GCC to print out the complete set of directories where it will look for system headers, invoke it like this:
$ LC_ALL=C gcc -v -E -xc - < /dev/null 2>&1 |
LC_ALL=C sed -ne '/starts here/,/End of/p'
which will produce output of the form
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
If you have -I-family options on the command line they will affect what is printed out.
(The sed command is to get rid of all the other junk this invocation prints, and the LC_ALL=C is to ensure that the sed command works -- the "starts here" and "End of search list" phrases are translated IIRC.)
g++ -print-search-dirs
gcc -print-search-dirs
The set of paths where the compiler looks for the header files can be checked by the command:-
cpp -v
If you declare #include "" , the compiler first searches in current directory of source file and if not found, continues to search in the above retrieved directories.
If you declare #include <> , the compiler searches directly in those directories obtained from the above command.
Source:- http://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art026
One could view the (additional) include path for a C program from bash by checking out the following:
echo $C_INCLUDE_PATH
If this is empty, it could be modified to add default include locations, by:
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include
These are the directories that gcc looks in by default for the specified header files ( given that the header files are included in chevrons <>);
1. /usr/local/include/ --used for 3rd party header files.
2. /usr/include/ -- used for system header files.
If in case you decide to put your custom header file in a place other than the above mentioned directories, you can include them as follows:
1. using quotes ("./custom_header_files/foo.h") with files path, instead of chevrons in the include statement.
2. using the -I switch when compiling the code.
gcc -I /home/user/custom_headers/ -c foo.c -p foo.o
Basically the -I switch tells the compiler to first look in the directory specified with the -I switch ( before it checks the standard directories).When using the -I switch the header files may be included using chevrons.
My system has gcc9 by default and I have built a gcc12 from source and I think the accepted answer is not correct, that is gcc -print-prog-name=cc1plus -v doesn't give the real include search path.
My build configuration is
Configured with: /home/tian/playground/gcc_build_play/objdir/../gcc-12.1.0/configure --prefix=/home/tian/GCC-12.1.0 --disable-multilib
And no matter where I mv the gcc12 directoy in my machine. It can always include its own c++ header files correctly.
If I type ./gcc -print-prog-name=cc1plus -v, in the original installed directory, it gives:
tian#tian-B250M-Wind:~/GCC-12.1.0/bin$ `./gcc -print-prog-name=cc1plus` -v
ignoring nonexistent directory "/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include
/usr/local/include
/home/tian/GCC-12.1.0/include
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed
/usr/include
End of search list.
mv my gcc12 to ~/Desktop/, run again, gives:
tian#tian-B250M-Wind:~/Desktop/GCC-12.1.0/bin$ `./gcc -print-prog-name=cc1plus` -v
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include/c++/12.1.0"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include/c++/12.1.0/x86_64-pc-linux-gnu"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include/c++/12.1.0/backward"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/include
End of search list.
If that's true, then I compile a program with ./g++, it should use c++ header files in /usr/include or /usr/local/include. But it's not.
Experiment is omitted here. You can try using mv to rename any header file of gcc12 your test program use or add some garbage code to the header file. Then you will see the gcc12 ./g++ is complaining about the gcc12 c++ header file, not my system gcc9's c++ header files in /usr/include or /usr/local/include.
So in both places ./g++ can find its gcc12 c++ headers files correctly.
So I guess gcc and g++ are finding headers in relative directory, relative to /path_to_gcc12/bin/gcc.
Try./g++ -g -Wall --verbose -o test test.cpp gives the real include path:
tian#tian-B250M-Wind:~/Desktop/GCC-12.1.0/bin$ ./g++ -g -Wall --verbose -o test test.cpp
Using built-in specs.
COLLECT_GCC=./g++
COLLECT_LTO_WRAPPER=/home/tian/Desktop/GCC-12.1.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /home/tian/playground/gcc_build_play/objdir/../gcc-12.1.0/configure --prefix=/home/tian/GCC-12.1.0 --disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 12.1.0 (GCC)
COLLECT_GCC_OPTIONS='-g' '-Wall' '-v' '-o' 'test' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/home/tian/Desktop/GCC-12.1.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/12.1.0/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -iprefix /home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/ -D_GNU_SOURCE test.cpp -quiet -dumpbase test.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -g -Wall -version -o /tmp/ccrg0qhG.s
GNU C++17 (GCC) version 12.1.0 (x86_64-pc-linux-gnu)
compiled by GNU C version 12.1.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed"
ignoring nonexistent directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed
/usr/local/include
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
So I think my guess is correct.