C++ Organization on the File System - c++

I come from a Java/AS3/Javascript background where all of my classes are organized into packages that help denote their functionality.
In starting a C++ project I sought to mimic this file system structure in mostly the same way but I've been running into issues with the includes.
Currently I have an src directory with the main.cpp file inside it. Then I have some root directories and with other files inside. Here's an example:
src
->main.cpp
->window
---->Window.h
---->Window.cpp
main.cpp includes Window.h with the statement #include "Window.h" and everything builds just fine. But if i restart Visual Studio, it complains that it can't find "Window.h".
In looking a open source projects, I've seen some that just have all the source files in one directory with no nesting for easy includes I suppose. Some have the headers and cpp files separated.
What is the correct way (or at least a way that will cause less headaches) to organize a large-ish C++ project on the file system?
Thanks!

Breaking it out like you've tried to do is reasonable and easy enough to accomplish.
You just need to set your project's include paths. From Visual Studio, right click on the project name and click "Properties". From there, in the tree control on the left hand side, expand "C/C++", and then select "General" in the tree. The first option on the right hand side should then be "Additional Include Directories".
There you have several options:
You can specify specific include directories (separated by semicolons). For instance, if you had folders "Window" and "Printing" you could put in:
..\Window;..\Printing
Which would allow you to include the files from window and printing easily, like this:
#include <Window.h> // from src/window
#include <Printing.h> // from src/printing
The above approach has some drawbacks, as you can easily collide with names from other libraries you may be using, making the include ORDER very important.
A better approach (in my opinion) is to add the following as an include path:
..\
This will make it search the parent directory when looking for includes. This allows you to be more verbose in your include paths, like this:
#include <Window/Window.h> // it's more clear where these are coming from
#include <Printing/Printing.h> // and much less likely to collide with other library
// header files

It makes sense to follow the Java example and arrange source files by C++ namespace. Create sub-folders under your /src directory that correspond to the namespaces.

Related

Including a header file in VS 2017 for "portable" projects (C++)

I decided to make a header file(s) that includes all the relatively simple methods I frequently use,to simply include said file into any project I'm working on instead of having to copy methods from one project to the other every-time I need them,I'm also going to be updating this file(s) as I go,now,I know there are multiple ways to go about including said file,either by adding it's file path to the #include directive itself,something like:
#include"C:\\Projects\\MyProgram\\Files\\MyHeader.h"
Or by adding the folder containing the header file(s) to the Additional Include Directories in the project's properties,which is what I'm currently doing,and it's working just fine.
However,I'm a bit worried about the fact the header file is not included INSIDE the project folder,so in the event I had to switch computers or wipe my hard drive,I'd have to make sure that this header file(s) is placed in the same exact file path,otherwise all of the projects that include it will simply fall apart...
And it goes without saying,I'm not making a copy of the header file to place in each project folder,for obvious reasons.
So I'd like to know if there anyway around this?
How about the ability to set an Additional Include Directory for ALL of my projects,so in the event of a wipe,a new PC or simply the old directory becoming inconvenient,all I have to do is set a new directory and all of my projects will start referring to that one?
If not,is my only choice is to build the header file(s) into a custom library? Because I know absolutely nothing about that,and I'd appreciate if someone would direct me to where I can learn to do that.
Thanks in advance.
You must use relative path. Do this:
1- Create a new subfolder in your solution. Let's call it include:
2- Put your shared headers in this subfolder. Example : myCommonFunctions.h
First solution: Use relative include path (see ../ at begining)
#include "../include/myCommonFunctions.h"
Second solution: Use relative path in Addtional include directories (see ../ at begining)
Now, you can write :
#include "myCommonFunctions.h"
By doing this, you don't depend from an absolute path C:\\Projects\\MyProgram\\... and You will no longer need to copy files manually if you change computers

Moved files in project and now I can't find namespaces

I previously had all of my source files in the same folder just scattered about, but I was getting tired of the disorder, so I created a folder hierarchy and organized my headers and .cpp files in those folders, and changed the ClInclude tags in the projects .vcxproj file accordingly. I then changed all the #include rows in the source headers to match the new location of the headers.
Now when I compile I get a heap of errors saying that the namespace "math" can't be found. The namespace could be found before the file organizing, so the problem should be something with that, but that #includes works fine.
If I write
using namespace
the autocomplete finds the namespace just fine, and no red wiggly lines show up in the text interface.
I'm using VS17 Community.
There are actually two ways to resolve your issue. You've already noted the first, that you can always use relative paths (relative to the source file).
#include "..\Math\math.h"
This will work just fine. You can also modify your C++ Project Properties to add a list of include directories. This will be very useful for you when you begin working on projects that use a lot of libraries To add include directories you need to:
right-click on your project in the solution explorer and select Properties.
In the left pane, click on the C/C++ > General tab.
On the property that says Additional Include Directories, click the drop down arrow (you may need to click inside the text first) and select Edit...
From here, you can add a list of include directories that you will be using with your project. You can use:
Absolute Paths
C:\Path\to\Math
Relative Paths (relative to your .vcxproj file)
..\..\relative\path\to\Math
Macros (Visual Studio will list your available macros)
($SolutionDir)..\path\to\Math
You'll see the use of the macros a lot when it comes to C++ and other Visual Studio projects not just for include directories, but for build events as well.
Once you've added a list of include directories, you can go back to including your headers in the source code as normal:
#include "math.h"
In the event you need to use a relative path from one of your included folders, you can do that as well.
// some directory inside of Math
#include "MoreMath\moremath.h"
// some directory above Math
#include "..\AboveMath\abovemath.h"
Hope this helps!
I solved it...
Remove this question if necessary. The problem was that I didn't backtrack the filepath in my #include "math.h". They should instead have said #include "..\Math\math.h".

Using (relative) paths to shortcut in include statements in C++

I started coding in C++ few days ago. I am using windows as my OS for writing code. I have been keeping all of my "well-written" codes in a single location. Now, I am working on a project that requires the use of those codes. So, I planned to include those files that I require as header files in my project. However, to make my project "self-contained", I created shortcuts of those folders that I require and kept them in the source folder of my new project and decided to use relative paths to the shortcuts in the "include" statements in my project.
However, I am getting an error. Is there any way to use relative (or, in general, absolute) paths to shortcuts in the include statements of C++ in windows?
Thanks.
It really depends on how you include the header files.
If you include with double-quotes, like e.g.
#include "some_header_file.h"
Then the relative path is from the current files location.
If you include using angle-brackets, like e.g.
#include <some_header_file.h>
Then the relative path is based on the system include paths.
You can always add a path to the system include path. How to do it depend on your environment and compiler. If you're using Visual Studio you go into the project properties dialog, and in the "C/C++" / "General" tab there is a field called "Additional Include Directories" where you can add directories. (This is for VS 2015, might be a little different on other versions.)
Regarding double quotes inclusion. Lets say your project hierarchy looks like this (on disk!):
Project
|-- Include
|-- Source
| `-- MoreSource
`-- Other
In Project/Source you have your source files, and if one of them want to include a header file from Project/Include, then it will look something like
#include "../Include/header.h"
Now if you have a source file in Project/Source/MoreSource that want to include the same header file it will be
#include "../../Include/header.h"
It could be useful to add the Project/Include directory to the system header search path. You can still use double-quotes to include the files, since if they are not found then the preprocessor will search the system paths as well, but you don't need the "full" relative path. If you add Project/Include to the system header path, you could write just
#include "header.h"
Or
#include <header.h>
Be careful though, if you have a header file with the same name as an actual system header file you might have some trouble.
From https://superuser.com/questions/253935/what-is-the-difference-between-symbolic-link-and-shortcut
You can't include folder shortcut since it's a file, not a folder.
You can read the guide to create symbolic link on windows.

How can I include directories with project relative paths in CMake?

I am developing a product with a team using CMake. We have several Visual Studio projects (libraries and executables) inside of our CMake project which reference other project headers (via target_include_directories()). In a source file these header includes look like:
#include "some_header.h" // from project_x
#include "another_header.h" // from project_y
I'd like to be able to include these headers with paths that reference the project they are pulled from, e.g.:
#include "project_x/some_header.h"
#include "project_y/another_header.h"
What is the most acceptable way to do this? I have thought of a couple solutions:
Add the directory which contains the project as an include path. This has the undesirable side-effect of including everything and seems like a bad solution.
Include a subfolder of the project called 'include' which contains a folder named with the same as the project, which creates a slightly redundant path: /<project_name>/include/<project_name>/<...>
There is a third solution, to use a shared include directory with a subfolder for each project, but it will not work for our project because we group our build projects by category in the file system and Visual Studio solution and it will cause the folder structure inside of /include/ to diverge from the rest of source tree which is undesirable.
Are there any better (or more canonical/idiomatic) ways to accomplish this?
If you have a project structure like this:
project_x/some_header.h
project_y/another_header.h
and you want to keep all of your CMakeLists the same, then I would introduce another folder in each project:
project_x/project_x/some_header.h
project_y/project_y/another_header.h
Of course, this requires changing the includes in each project to reflect this new structure, including the project where the header is defined proper.
There's some precedence to this, as this is how curl and googletest do it.
Edit: I understand this is very similar to the second approach you outlined. If your directory structure already employs include directories, then my suggestion is exactly the same as your second one. At the very least, this should confirm your intuition that this isn't an entirely absurd thing to do, even if it creates some redundancy.

C++ Header style

What's the preferred policy of header files in C++ projects: <test.h> or "test.h"?
In my experience I use:
#include <test_lib.h> to include C/C++ headers, third-part libraries (boost and etc.) which path specified in project settings.
#include "my_test.h" - it's used for headers files existing in project.
Any other practices can be applied here?
Is it ok to include header files with relative paths: like #include "../new_test.h"? Or is it better to move relative paths to project settings?
Angle brackets are use to include system headers. Theoretically, IIRC, they're not even necessarily files. In practice, <> means do not search current directory, only the include path, whereas "" means look in current directory and then search the include path.
As for relative paths, it probably depends on your environment, I'd suggest path relative to your project include path (as specified by -I).
This MSDN article explains how preprocessor searches for headers depending on the #include syntax form. Your style is good as Visual C++, Windows Framework, Boost and headers of other frameworks/packages are (usually) outside your project's directory.
Regarding your second question, my advice is to avoid relative paths. If you move around that header, you'll need to adjust that relative path by changing your code which is a bad idea. I'd rather put it within angle brackets and add path to it to /I option. E.g. you want to include C:\frameworks\frameworkA\include\a.h in your project, you can use #include <a.h> and \I "C:\frameworks\frameworkA\include"
It is maybe more descriptive if you add path to the framework root to /I and then put partial path to its header within angle brackets. E.g. #include <frameworkA\include\a.h> and /I "C:\frameworks". Now it's clear in the code that a.h belongs to frameworkA.
Use relative paths only for headers that are within your project's directory (e.g. if you organise code into modules which are in subdirectories of your project and which are not intended to be moved around).
You can use either. The <test.h> can be used by using the -I <directory containing test.h> option when compiling. In general, and this is a practice I follow, I tend to use <test.h> for all header files, irrespective of whether they are third-party header files or ones that I have written.
It might be a good idea to refrain from using relative paths "../test.h". From personal experience, this way of writing #include statements forces you to cement your directory structure. If you decided to move test.h tomorrow to a different directory, you would have to go into each one of the header files and change the relative path for test.h to the new path - a time consuming exercise. Better to shift this to the makefile (via -I) and then deal with it from there.