Note: This question sorted itself out while I was writing it. I had trouble finding information on this problem, so I feel it would be useful to post it anyway. Advice welcome.
Hello everyone. I've recently installed GCC 4.9.1 on my Linux Mint, have been compiling some projects of mine, and everything has gone smoothly.
Now I want to get working on one such project again, beginning with some source files sorting. So I created a new folder and moved a couple .h and .tpp files inside. The structure looks like this :
.
├── clip
│ ├── Clip.h
│ ├── ClipImpl.tpp
│ └── Mask.h
:
├── main.cpp
:
├── vect.cpp
├── vect.h
:
main.cpp
is just #include "clip/Clip.h"
, and will later contain some template instantiations for testing purposes. clip/Clip.h
includes clip/Mask.h
, which needs vect.h
.
Note that the latter include is not satisfied, so the compiler rightly complains. Now, I would like all my #include
s to be relative to the project's root, and not the file they are made from. Alright, I edit my Makefile :
# Retrieve the root directory
WD = $(shell pwd)
...
# Add it to the include search paths
%.o: %.cpp # vvvvvvv
$(CXX) $(CXXFLAGS) -I$(WD) -c $<
And then... Boom ??
g++ -std=c++1y `sdl2-config --cflags` -Wall -Wextra -Winline -fno-rtti -I/home/quentin/NetBeansProjects/glk -c AutoDisplayed.cpp
In file included from /home/quentin/NetBeansProjects/glk/time.h:4:0,
from /usr/include/sched.h:33,
from /usr/include/pthread.h:23,
from /opt/gcc-4.9.1/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/gthr-default.h:35,
from /opt/gcc-4.9.1/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/gthr.h:148,
from /opt/gcc-4.9.1/include/c++/4.9.1/ext/atomicity.h:35,
from /opt/gcc-4.9.1/include/c++/4.9.1/bits/basic_string.h:39,
from /opt/gcc-4.9.1/include/c++/4.9.1/string:52,
from /opt/gcc-4.9.1/include/c++/4.9.1/stdexcept:39,
from /opt/gcc-4.9.1/include/c++/4.9.1/array:38,
from /opt/gcc-4.9.1/include/c++/4.9.1/tuple:39,
from /opt/gcc-4.9.1/include/c++/4.9.1/bits/stl_map.h:63,
from /opt/gcc-4.9.1/include/c++/4.9.1/map:61,
from AutoDisplayed.h:5,
from AutoDisplayed.cpp:1:
/opt/gcc-4.9.1/include/c++/4.9.1/functional: In member function ‘_Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...)’:
/opt/gcc-4.9.1/include/c++/4.9.1/functional:1322:8: error: ‘forward_as_tuple’ is not a member of ‘std’
std::forward_as_tuple(std::forward<_Args>(__args)...),
^
I've searched for a good bit, and actually found out what was going on while writing this very sentence.
I actually had a time.h
file in my project's root. While it didn't cause any problem so far, It started getting included in place of the standard header <time.h>
. Short of renaming the file, I dug into the GCC documentation and found the cause of the problem (emphasis mine) :
-I
dir
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, [...] the directories are scanned in left-to-right order; the standard system directories come after.
So, the -I option overrides system headers by plonking your directory in front of the list. No good, I wanted to have it at the back... But just below is the solution :
-iquote
dir
Add the directory dir to the head of the list of directories to be searched for header files only for the case of ‘#include "file"
’; they are not searched for ‘#include <file>
’, otherwise just like -I.
Oh. That's just what I needed. It's a shame I never heard of that option before, and have been using -I for the wrong purpose all along. Oh well. Case solved !