29

In a "working directory" I have a lot of *.cpp and *.h files that #include each other and files from subdirectories.

For example:

#include "first.h"
#include "second.h"
#include "dir1/third.h"
#include "dir2/fourth.h"

In my own directory (that is different from the "working" directory) I would like to create a new *.cpp and *.h file that includes one of the files from the "working" directory. For example:

#include "/root/workingdirectory/first.h"

However, it does not work. Because "first.h" might include "second.h" and "second.h" is not located in my directory. Is there a way to tell the compiler that it needs to search included files not in the current but in the working directory: /root/workingdirectory/?

To make it even more complex, dir1 and dir2 are not located in my working directory. They are located in /root/workingdirectory2/. So, my second question is if it is possible to resolve this problem by letting compiler know that subdirectories are located somewhere else?

I also need to add, that I do not use any environment for development and compile from the command line (using g++).

tshepang
  • 12,111
  • 21
  • 91
  • 136
Roman
  • 124,451
  • 167
  • 349
  • 456
  • 3
    Somebody voted to close as "not constructive"? In what way is "use this option, oh and have a link to the manual" not supported by facts, references, or specific expertise and likely to solicit debate, arguments, polling, or extended discussion? –  Mar 18 '13 at 13:32
  • 1
    The `-I` part of the question is definitely an RTFM, but using the `#include` directive correctly in the first place _is_ a language issue (and one OP didn't obviously know to ask about) – Useless Mar 18 '13 at 13:52
  • 2
    People read the manual, they try `-I` and it seems to work. They seem to know what `-I` does. Then much later it does something unexpected. This is why it really isn't a RTFM question. – doug65536 Nov 04 '16 at 08:22

4 Answers4

15

As you've already been told, it's useful to read the manual - specifically this chapter - and even more specifically right here.

Specifically, you want

g++ -I/root/workingdirectory -I/root/workingdirectory2

Note also the documentation on #include directive syntax, described here as:

2.1 Include Syntax

Both user and system header files are included using the preprocessing directive #include. It has two variants:

#include <file>

This variant is used for system header files. It searches for a file named file in a standard list of system directories. You can prepend directories to this list with the -I option (see Invocation).

#include "file"

This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for <file>. You can prepend directories to the list of quote directories with the -iquote option. The argument of #include, whether delimited with quote marks or angle brackets, behaves like a string constant in that comments are not recognized, and macro names are not expanded. Thus,#include <x/*y> specifies inclusion of a system header file named x/*y.

However, if backslashes occur within file, they are considered ordinary text characters, not escape characters. None of the character escape sequences appropriate to string constants in C are processed. Thus, #include "x\n\\y" specifies a filename containing three backslashes. (Some systems interpret \ as a pathname separator. All of these also interpret / the same way. It is most portable to use only /.)

It is an error if there is anything (other than comments) on the line after the file name.

So for example

#include "first.h"

will start looking in the same directory as the .cpp file containing this directive (or take a relative path as relative to this directory).

If you want to use the include path (specified by -I) you should use

#include <dir1/third.h>

Usual practice is to use the #include "local.h" form for headers inside a library/package/module (however you've chosen to organize that), and the #include <external.h> form for headers from external/3rd-party or system libraries.

Useless
  • 64,155
  • 6
  • 88
  • 132
13

Read The Fine Manual

It's there for everyone to read. You even have a choice of what to use (I'd go with the first):

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

-iquotedir

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.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • @johannes_lalala This answer points the OP and every future reader/googler (including you) to the actual source of the information, including the relevant bits here for your viewing pleasure. Everyone should have read the manual instead of asking questions about these things yes, but the manuals are less search-engine optimized, so having a good link to them (on SO) is useful all by itself. An answer just saying "RTFM" isn't productive. This one is, and attempts to point people to a wealth of other information they might be looking for in the near future. – rubenvb Jun 07 '21 at 06:56
  • yesyes, answer is good. Except for the part where you lecture about RTFM'ing-before-asking-questions in the first 2 sentences. That I find a bit rude. Sorry man, just didn't need to read that in order to get the info (which other than that is nice). The other thing is: Imagine the guy had actually read the manual, found the answer and not posted the question in the first place. Would you have liked that situation more? Would I? Would someone who upvoted? Or stackoverflow in general? – johannes_lalala Nov 28 '21 at 23:10
  • @johannes_lalala with all due respect, but this meta post is linked from the [StacxkOverflow help page](https://stackoverflow.com/help): https://meta.stackoverflow.com/questions/261592. Googling for "compiler cannot find header file" literally finds tens if not hundreds of results. This question is also missing the qttempted solutions, and means to reproduce effectively. Instead of closing it for lack of being a good fit for SO _by their own rules_, I linked to the manual and literally coipy-pasted the answer from there. Note these manuals have all been indexed by you favorite search engine. – rubenvb Nov 29 '21 at 15:40
3

For gcc it is the -I option for header includes. For the .cpp files you just need those to appear as an argument to the gcc command.

Andrew White
  • 52,720
  • 19
  • 113
  • 137
-1

Every C/C++ compiler (g++, gcc, MinGW, clang, e.t.c.) has a folder called "include" in it's root path where it automatically looks for header files. If you use MinGW, it would be in, for example: "C:\MinGW\include". Just save your header to the include folder like this: C:\MinGW\include\header1.h or C:\MinGW\include\LibGUI\Window.h

biskit
  • 11
  • 3
  • That would make the files available to the whole system, rather than just the project. – Coder-256 Aug 09 '20 at 19:11
  • It's how I do it – biskit Aug 11 '20 at 04:31
  • Anyway, making the file available to the whole system might be useful, because you may want to reuse the header file. – biskit Aug 11 '20 at 04:33
  • @biskit you are missing the point. How can you achieve working with a project in an isolated environment and still have the compiler work on the project without any problems? – Drizzle Apr 10 '23 at 04:47