59

I have a project (a library) that is subdivided into a few directories with code in them. I'd like to to have g++ search for header files in the project's root directory, so I can avoid different include paths for same header files across multiple source files.

Mainly, the root/ directory has sub-directories A/, B/ and C/, all of which have .hpp and .cpp files inside. If some source file in A wanted to include file.hpp, which was in B, it would have to do it like this: #include "../B/file.hpp". Same for another source file that was in C. But, if A itself had sub-directories with files that needed file.hpp, then, it would be inconsistent and would cause errors if I decided to move files (because the include path would be "../../B/file.hpp").

Also, this would need to work from other projects as well, which reside outside of root/. I already know that there is an option to manually copy all my header files into a default-search directory, but I'd like to do this the way I described.

Edit: all programs using the library must compile only with g++ prog.cpp lib.a -o prog. That means permanently setting the include path for g++!

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
corazza
  • 31,222
  • 37
  • 115
  • 186
  • Note the discussion in [What are the benefits of a relative path such as `#include "../include/header.h"` for a header?](https://stackoverflow.com/questions/597318/what-are-the-benefits-of-a-relative-path-such-as-include-header-h-for-a-hea) – Jonathan Leffler Nov 09 '19 at 00:20

4 Answers4

69

A/code.cpp

#include <B/file.hpp>

A/a/code2.cpp

#include <B/file.hpp>

Compile using:

g++ -I /your/source/root /your/source/root/A/code.cpp
g++ -I /your/source/root /your/source/root/A/a/code2.cpp

Edit:

You can use environment variables to change the path g++ looks for header files. From man page:

Some additional environments variables affect the behavior of the preprocessor.

   CPATH
   C_INCLUDE_PATH
   CPLUS_INCLUDE_PATH
   OBJC_INCLUDE_PATH

Each variable's value is a list of directories separated by a special character, much like PATH, in which to look for header files. The special character, "PATH_SEPARATOR", is target-dependent and determined at GCC build time. For Microsoft Windows-based targets it is a semicolon, and for almost all other targets it is a colon.

CPATH specifies a list of directories to be searched as if specified with -I, but after any paths given with -I options on the command line. This environment variable is used regardless of which language is being preprocessed.

The remaining environment variables apply only when preprocessing the particular language indicated. Each specifies a list of directories to be searched as if specified with -isystem, but after any paths given with -isystem options on the command line.

In all these variables, an empty element instructs the compiler to search its current working directory. Empty elements can appear at the beginning or end of a path. For instance, if the value of CPATH is ":/special/include", that has the same effect as -I. -I/special/include.

There are many ways you can change an environment variable. On bash prompt you can do this:

$ export CPATH=/your/source/root
$ g++ /your/source/root/A/code.cpp
$ g++ /your/source/root/A/a/code2.cpp

You can of course add this in your Makefile etc.

Vikas
  • 8,790
  • 4
  • 38
  • 48
  • Hey, I've stated the question without one important detail, please see the edit, thanks! – corazza Sep 29 '12 at 15:38
  • @Bane, that changes everything :-). I edited my answer to include more options that can be used. – Vikas Sep 29 '12 at 15:46
  • 1
    That seems to be what I am looking for. How exactly can I edit those? (With a CLI instruction, that is, which I need to add to my library's makefile's install rule.) – corazza Sep 29 '12 at 15:48
  • @Bane, updated with instruction. Exact way of setting environment variable will depend on your environment. But you mentioned you are using `Makefile`. In that case, why can't you add `-I /path` flag in your `Makefile`? Why do you want compiler to be executed without any options? – Vikas Sep 29 '12 at 16:01
  • Because some other projects might need the library, and I only want to move the `lib.a` file, not the header files. I could include `-I /path` into *their* makefiles, but I'd rather not. – corazza Sep 29 '12 at 16:03
36
gcc -I/path -L/path
  • -I /path path to include, gcc will find .h files in this path

  • -L /path contains library files, .a, .so

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
Yueyoum
  • 2,823
  • 5
  • 23
  • 26
1

it's simple, use the "-B" option to add .h files' dir to search path.

E.g. g++ -B /header_file.h your.cpp -o bin/your_command

Zhile Zou
  • 1,949
  • 2
  • 14
  • 12
0

Headers included with #include <> will be searched in all default directories , but you can also add your own location in the search path with -I command line arg.

I saw your edit you could install your headers in default locations usually

 /usr/local/include
 libdir/gcc/target/version/include
 /usr/target/include
 /usr/include

Confirm with compiler docs though.

NiladriBose
  • 1,849
  • 2
  • 16
  • 31