C++ project source code layout - c++

One of the popular way to organize project directory is more or less like this:
MyLib
+--mylib_class_a.h
mylib_class_a.cpp
mylib_library_private_helpers.h
mylib_library_private_helpers.cpp
MyApp
+--other_class.h
other_class.cpp
app.cpp
app.cpp:
#include "other_class.h"
#include <mylib_class_a.h> // using library MyLib
All .h and .cpp files for the same library are in the same directory. To avoid name collision, file names are often prefix with company name and/or library name. MyLib will be in MyApp's header search path, etc. I'm not a fan of prefixing filenames, but I like the idea of looking at the #include and know exactly where that header file belongs. I don't hate this approach of organizing files, but I think there should be a better way.
Since I'm starting a new project, I want to solicit some directory organization ideas. Currently I like this directory structure:
ProjA
+--include
+--ProjA
+--mylib
+--class_a.h
+--app
+--other_class.h
+--src
+--mylib
+--class_a.cpp
library_private_helpers.h
library_private_helpers.cpp
+--app
+--other_class.cpp
app.cpp
util.h
app.cpp:
#include "util.h" // private util.h file
#include <ProjA/app/other_class.h> // public header file
#include <ProjA/mylib/class_a.h> // using class_a.h of mylib
#include <other3rdptylib/class_a.h> // class_a.h of other3rdptylib, no name collision
#include <class_a.h> // not ProjA/mylib/class_a.h
#include <ProjA/mylib/library_private_helpers.h> // error can't find .h
.cpp files and private (only visible to immediate library) .h files are stored under the src directory (src is sometimes called lib). Public header files are organized into a project/lib directory structure and included via <ProjectName/LibraryName/headerName.h>. File names are not prefixed with anything. If I ever needed to package up MyLib to be used by other teams, I could simply change my makefile to copy the appropriate binary files and the whole include/ProjA directory.
Once files are checked into source control and people start working on them it will be hard to change directory structure. It is better to get it right at the get-go.
Anyone with experience organizing source code like this? Anything you don't like about it? If you have a better way to do it, I would very much like to hear about it.

Well, it all depends on how big these projects are. If you've only got a few files, then whack them all in one folder.
Too many folders when you haven't got many files to manage is in my opinion overkill. It gets annoying digging in and out of folders when you've only got a few files in them.
Also, it depends on who's using this stuff. If you're writing a library and its going to be used by other programmers, then it's good to organize the headers they want to use into an include folder. If you're creating a number of libraries and publishing them all, then your structure might work. But, if they're independent libraries, and the development isn't all done together and they get versioned and released at different times, you'd be better off sticking with having all files for one project locatable within one folder.
In fact, I would say keep everything in one folder, until you get to a point where you find its unmanagable, then reorganize into a clever scheme of dividing the source up into folders like you've done. You'll probably know how it needs to be organized from the problems you run into.
KISS is usually always the solution in programming -> keep everything as simple as possible.

Why not do something like the first, only use the directory that MyLib resides in as a part of the include directive, which reduces the silly prefixing:
#include <MyLib/ClassA.h>
That tells you where they are from. As for the second choice, I personally get really annoyed when I have a header or source file open, and have to navigate around through the directory structure to find the other and open it. With your second example, if you had src/mylib/class_a.cpp open, and wanted to edit the header, in many editors you'd have to go back two levels, then into include/ProjA before finding the header. And how are we to know that the header is in the ProjA subdirectory without some other external clue? Plus, it's too easy for one file or the other to get moved into a different place that "better" represents how it is used, without the alternate file being moved. It just gives me headaches when I encounter it at my job (and we do have some parts of our codebase where people did every potential problem I've just mentioned).

I have tried both methods. Personally, I like the first better. I understand the urge to put everything in more specific directories, but it causes a lot of over-complication.
I usually use this rule: applications and in-house libraries use the first method. Public open source libraries use the second method. When you are releasing the code, it helps a lot if the include files are in a separate directory.

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

Default folder setup for a large project

As I am trying to learn C++ I have begun on a larger project where I try to use classes in order to avoid a messy main.cpp file. This means that I am creating more .cpp files which I have placed in the same folder as the main.cpp file. This has resulted in a messy directory aswell so I tried managing my files by adding folders following the two links:
Link1: https://hiltmon.com/blog/2013/07/03/a-simple-c-plus-plus-project-structure/
Link2: https://mariuszbartosik.com/directory-structure-for-a-c-project/
My questions are the following:
Does a standard for creating C++ projects exist that is used in a
workplace or is every project subjectively created?
If a standard does not exist are there any bad practises that should
be avoided when creating a folder structure?
Can I create a folder structure where I put all the header (.h)
files in one directory and all the source files (.cpp) in another
directory such as C:\headers\header.h and C:\source\main.cpp to
in my include use a #define HEADER "/path to header" and then
somehow #include HEADER "aheader.h" which would mean that I dont
need to everytime when including a header write the path to the
header directory and instead write HEADER before the include?
Example:
Instead of:
#include "c:\headers\header.h"
#include "c:\headers\anotherheader.h"
Use:
#define HEADER "c:\headers\"
#include HEADER "header.h"
#include HEADER "anotherheader.h"
I am asking this because I would like to avoid all bad practise when learning to code in C++ so I wont do mistakes later on. Since I have no work experience I dont know if the guides I found online are good ones in practise.
My current structure:
Does a standard for creating C++ projects exist that is used in a
workplace or is every project subjectively created?
No, you can find different structures across different projects.
If a standard does not exist are there any bad practices that should
be avoided when creating a folder structure?
You should:
Put your compiled files in a different folder (bin maybe).
Organize your project in different logical modules placed in different folders.
Use the root folder for not-code files (makefile, gitignore, etc...).
Use lowercase names only to avoid silly mistakes.
You should not:
Use absolute paths.
Can I create a folder structure where I put all the header (.h)
files in one directory and all the source files (.cpp) in another directory such as C:\headers\header.h and C:\source\main.cpp to in my include use a #define HEADER "/path to header" and then somehow #include HEADER "aheader.h" which would mean that I dont need to everytime when including a header write the path to the header directory and instead write HEADER before the include?
No, that's really bad.
I don't like use different folders for source/header files, but if you want to. You can work around using include paths (-l flag).
So you would use:
#include <header.h>
#include <anotherheader.h>
That works because you are including the folder on compile time:
g++ -l "../headers" enemy.cpp
Any sensible IDE will do this for you. Or you could do it on your makefile, whatever suits you.

MACRO depending on its folder location

In the following files:
app/main.cpp
app/config.hpp
app/show.hpp
app/file.hpp
lib/append.hpp
lib/clear.hpp
lib/reopen.hpp
lib/crypt.hpp
I have a problem. Imagine a few of my files use lib/crypt.hpp. For example in app/file.hpp I should write:
#include "../lib/crypt.hpp"
If I take this file to lib folder it does not work anymore. So I need a something like:
#include "LIB/crypt.hpp"
So, this LIB/ has meaning of (empty) in lib directory while it has meaning of "../lib/" in app directory.
Then I will have no worry about moving file.hpp from app to lib. I just need to fix the callers of it. But not what it calls.
Similar to concept of web programming frameworks. Is it possible in C/C++?
According to what you wrote you're searching for a way to move your sources around without worrying for hard-coded paths to your headers.
You didn't specify the compiler you're using so I'm not focusing on a specific one, anyway most C++ compilers have an option to specify one or more header search paths (on gcc you would just use something like -Ilib_parent_dir).
Once you've included your lib's parent path to the search list, you can move your sources around (as long as you don't move lib's headers) and have them include the right headers with something like #include <lib/crypt.hpp> (and keep include paths priority in mind)
This should be a cleaner and simpler way to achieve what you asked rather than using a macro.

C++ Organization on the File System

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.

Vs2008 C++: how can I make recursive include directories?

I am including a complicated project as a library in C++ using Visual Studio 2008.
I have a set of include files that are scattered throughout a very complicated directory tree structure. The root of the tree has around ten directories, and then each directory could have multiple subdirectories, subsubdirectories, etc.
I know that all the header files in that structure are necessary, and they are hopelessly interlinked; I can't just include one directory, because then dependencies in another directory will feel left out and cause the compiler to crash in their annoyance at not being invited to the party. So, everyone has to be included.
I can do this by adding the directories one at a time to the project (right click->properties->additional include directories), but that can be fraught with pain, especially when one of the dependencies has children and makes a brand new subsubsubdirectory.
Is there a way to specify an include directory in a header file itself, so that I can just include that header whenever I need to use the functions it contains? That way, I get an easier way to edit the include files, and I don't have to make sure that the debug and release versions agree with each other (since the properties right click defaults to the current build, not all builds, a feature that has led to much crashing when switching from debug to release). Even better, is there a way to point to the directory root and force everything to be recursively included?
EDIT for all those replies so far:
I cannot edit the structure of this project. I can only link to it. I don't like the way the code is organized anymore than anyone else seems to, but I have to work within this constraint. Rather than spending potentially hours in the error-prone process of finding all the interdependencies and putting them in a project file, is there a way to do this programmatically?
That's clearly not a good idea, really.
These directories are a way to organize the code in logical groups.
/web
/include
/web
/stackoverflow
/language-agnostic
/algorithm
/database
/meta
/bug
/feature-request
/src
/local/
/include
/local
/my-favorites
/src
Now if I type
#include "exception.h"
What the heck am I trying to include ? Where's that file ? How can I see its content ?
On the other hand if I type
#include "local/my-favorites/exception.h"
Then it's perfectly clear. (and I just have two includes -Iweb/include -Ilocal/include)
And this way, I can have multiple files that have the exact same name and there would be no ambiguity, nifty when you wish to integrate two different 3rd party libraries which both have such a 'exception.h'.
Also note that for clarity, the namespace nesting should reflect the directories organization. So that
file: "web/include/web/meta/bug/exception.h"
namespace web { namespace meta { namespace bug {
struct exception: std::runtime_error {};
} } } // namespace bug, namespace meta, namespace web
This way it's easy to think of what header you have to include when you want a class.
Also note that, for example if you look at boost, they put headers for 'lazy' programmers, in each directory, which include the headers of all subdirectories
file: "web/include/web/meta/bug.h"
#include "web/meta/bug/file1.h"
#include "web/meta/bug/file2.h"
#include "web/meta/bug/file3.h"
#include "web/meta/bug/file4.h"
#include "web/meta/bug/file5.h"
file: "web/include/web/meta.h"
#include "web/meta/bug.h"
#include "web/meta/feature-request.h"
These includes might also 'pull' names into a more generic namespace with a using directive:
namespace web { namespace meta {
using ::web::meta::bug::bug;
} } // namespace meta, namespace web
To make it less painful for developers.
So as you can see, the language already provide you with a very good way of organizing your code cleanly, if you go with the 'all includes' options, you'll just end up with an unmaintainable mess:
#include "exception.h"
#include "bug.h"
#include "myString.h"
#include "database_connect.h"
#include "helper.h" // really love this one...
#include "file.h" // not bad either eh ?
I've had some of these at work... think 20 unqualified includes when you depend on 25+ components... now, do you think that it would be possible to remove a dependency on component X ? ;)
EDIT: How to deal with 3rd party library ?
Sometimes a 3rd party library does not live up to your expectations, whether it is:
not self-sufficient headers (ie you need to include 3 files to use 1 object)
warnings at compilation
header organization problem
you always have the opportunity to wrap them in headers of your own.
For example, say I have:
/include
/file1.h
/file2.h
/detail
/mustInclude.h
/exception.h
And anytime you wish to include a file, you have to include 'exception.h' BEFORE and 'mustInclude.h', and of course you have the problem that it is difficult to spot that the files included come from this 3rd party library and not your own (current) project.
Well, just wrap:
/include
/3rdParty
/file1.h (same name as the one you would like to include, it's easier)
file: "/include/3rdParty/file1.h"
#pragma push
// ignore warnings caused
#include "detail/exception.h" // necessary to include it before anything
#include "file1.h"
#include "detail/mustInclude.h"
#pragma pop
And then in your code:
#include "3rdParty/file1.h"
You have just isolated the problem, and all the difficulty now lies within your wrappers files.
Note: I just realize that you may have the problem that the 3rd party headers reference each others without taking the 'relative path' into account, in this case, you can still avoid the 'multiple include' syndroms (even without edition), but that might be ill-fated.
I suppose you don't have the opportunity not to use such crap :x ?
If in any way possible you really should take the time to rework that mess. It will only get worse.
If you are including it as a library then you probably only need a subset of its functionality anyway - make it slowly accessible and usable again step by step.
edit:
And no, there is no recursive include - for good reason. It would be completely uncontrollable from a certain size on and you'd fall over file-name-collisions all the time.
You could hack around the limitation via scripting and the project files, but you really would regret it in the long run.
edit2:
Ok, emergency procedure then. Put the library in its own project and use a short script to generate a line containing the neccessary paths seperated by ; which to put in the project file into the projects .vcproj (which is just an xml-file) under:
VisualStudioProject -> Configurations -> Configuration -> Tool -> AdditionalIncludeDirectories
(at least in VS2005, might differ a bit in later versions).
If you need all the includes in your calling code, you might want to consider wrapping that part in a static library in a seperate project to avoid polluting the rest.
Q: I cannot edit the structure of this
project. I can only link to it. I
don't like the way the code is
organized anymore than anyone else
seems to, but I have to work within
this constraint. Rather than spending
potentially hours in the error-prone
process of finding all the
interdependencies and putting them in
a project file, is there a way to do
this programmatically?
This should get you started:
write a script (in your favorite "quick" language) to enumerate all the [sub-...]directories in the library directory
filter the directories (for start, remove the ones that don't contain any .h files)
output them either to header file as you described or directly to the vcproj file. The
vs2008 vcproj file is relatively simple XML. It might even be documented, but if you just view it in a text editor, you'll figure out where and how the include paths are defined
try to compile
if errors, try to figure out why, adjust directory filter (blacklist specific directories etc.) and go back to 2.
success
Anyway, don't be afraid to write code generation scripts