# How to include library header files in subdirectory

• ### Question

• Hi, I have a Visual Studio 2015 C++ project organized like this:

myapp

|

-- subdir/something.cpp

-- libdir/blabla.h

And I have add path\to\myapp\libdir to the "Include directories", "library directories" as well as "Additional include directories" in project property.

However, when I include blabla.h in something.cpp:

#include <blabla.h>

I still get the "cannot open source file blabla.h" error.

Files right under the root directory do not have such problem.

I know "#include "../libdir/blabla.h"" may bypass this issue, but it's not very beautiful.

Can't VC project be organized into hierarchical directories, like Linux does?

Thank you!

• Edited by Sunday, August 12, 2018 6:32 AM
Sunday, August 12, 2018 6:29 AM

### All replies

Sunday, August 12, 2018 9:25 AM
• You mean the way that the way the STL has the experimental sub directory?

#include <experimental/coroutine>

It is just a matter of how you set up the project paths.

The documentation for #include states how each form works. The quoted form searches in the order of:

1) Same directory as the file (source or header) that includes the file

2) In the same directory as any currently opened include statements, in reverse order of opening.

3) The paths in the /I statements

4) The paths in the INCLUDE environment.

The angle bracket form of include searches in the order of:

1) The paths in the /I statements

2) The paths in the INCLUDE environment.

So the issue is how you have placed the files in your project structure.

If for example you placed your header files in a separate include directory:

and they were in a subdirectory of this:

and this contains the files:

If you then went to your project properties and added the outer include directory, either to the Additional Include Directories option or the Include Directories in the project properties:

($(SolutionDir) is a macro that expands to the path that the currently opened .sln file is in, if you want to have the headers inside the same directory as the project itself, you can use$(ProjectDir) which will expand to the path that the .vcxproj is in)

using this, you can just include using the <pathto/header> format.

#include <coro/yield.h>

Just be aware that you should either use one or the other. This works because Additional Include Directories adds it using the /I option (which is step 1 of the angled bracket order), and Include Directories adds it to the INCLUDE environment variable. Obviously /I will have priority over INCLUDE.

This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

• Edited by Sunday, August 12, 2018 1:07 PM
Sunday, August 12, 2018 1:01 PM
• Thank you for the thoughtful answers from all you guys!

I just figured out the reason, that is the include directories should not only be provisioned for platform x64, but also for platform Win32, although building is only under x64.

Also I really suspect it is a bug here. In the .vcxproj file, provision for Win32 appears before x64, and the compiler only reads the first provision it meets, so it decides ......

Monday, August 13, 2018 2:52 AM
• No, this is entirely untrue.

To give an example, I created a very simple project that only one header file, and it is only available to the x64 settings.

Notice the path includes incx64? This is the directory for include files for x64 only. The x86 version of that directory is empty.

Now, Visual Studio is set to include the headers from the corresponding platform's include directory.

The $(SolutionDir) macro expands to the path where the solution directory is, and this is where the incx64 and incx86 directories are. the$(PlatformTarget) expands to x64 when the platform in the configuration is set to x64, and to x86 when the platform in the configuration is x86/Win32. So this makes the intellisense and compiler look in two different locations depending on configuration.

So Visual Studio would then have to get the presence of these headers depending on configuration. So if you set Visual Studio to the x64 configuration, it detects that it exists properly.

But if you set it to the x86 configuration, it will report that this header doesn't exist.

Now you should see that the platform in the main Visual Studio window controls this.

But notice how I never once mentioned the project file and solution explorer?

This file was never even added to the project.

The thing you will learn is that adding a header to the project doesn't do anything for the intellisense or build. It is only really there to make opening those files easier when they do logically belong to that project. The compiler and intellisense compiler will only use the INCLUDE environment variable and /I command line option, as well as the current directory for the quoted form of #include, to detect headers, nothing added to your project will make any difference.

Now, there is one more thing that could have gotten you confused. The Visual Studio configuration may not be set to the same as the project settings configuration.

You didn't accidentally go and make all of your changes to the Win32 configuration assuming that it would automatically match the x64 configuration from Visual Studio itself did you?

This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

• Edited by Monday, August 13, 2018 10:02 AM
Monday, August 13, 2018 10:00 AM