Default folder setup for a large project - c++

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.

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

How to make header files can be include via Library name?

I'm trying to make a cross-platforms crypto library in C++ at https://github.com/haithngn/cryptor something like https://github.com/MailCore/mailcore2
The Structure is:
Can I make any header files can be include in the statements like this:
#include <Cryptor/MD5Encryptor.h>
I can include these header directly from absolutely file path
../core/CryptorCore.h
But these format will make the source code cannot build succeed in an XCode Project.
I tried to simulate the MailCore2 but that's very difficult.
Hope you can suggest me any solution or do a favor PR on my Repository.
Thanks,
You need to have a proper hierarchy. First, no, you can't have
#include <Cryptor/MD5Encryptor.h>
with your current setup, not while building the library, and not without flattening the hierarchy when installing your files (which CMake can do).
What you can do is:
#include <Cryptor/core/abstract/MD5Encryptor.h>
if you add your project inside a Cryptor folder instead of being at the root of your project.
I would advise you to create a Cryptor.cmake file that would allow people to pick up your library once installed, so that they don't have to know where the library includes are or what the libraries name is.
It should not be necessary to point to every single header file. Just add all directories containing these header files with include_directories(PATH_TO_HEADERS).
For the include of the header file src/core/CryptorCore.h with
#include "CryptorCore.h"
you have to point to
include_directories(${PROJECT_DIR}/core/)

Visual Studio C++ able to compile with compile errors (red underlines)

I am having a problem of getting compile errors (red underlines) like:
Error: cannot open source file "stdafx.h"
Here an edited screenshot of the environment:
On the LEFT is my Visual Studio Solution Directory list with the "Show All Files" off.
I am working on a school project, and each Folder are the source files of different parts of the project with different people who are in-charge of them.
For example, Student A and B are incharge of AST and PARSER folders (we will call them sub-projects).
We have an API for each sub-project so other sub-projects know what to call.
At the TOP-CENTER, we have my Source File for a class QueryProcessor. (just the first few lines)
Below it, is the Output for the Build Success.
The red lines are all over all the classes, mainly cause the #include "stdafx.h" cannot be opened by the environment.
On the RIGHT, that is the stdafx.h where we include all the different sub-projects so we save the trouble of each project having a different stdafx.h
However, I am able to build the project. I am pretty sure I am doing this directory/linking wrongly.
This should work
Right click on the solution file
Click Open in Windows Explorer
Find file stdfx.h in explorer and copy the path of the folder
In visual studio solution explorer, Right click on the project file
Click properties-> C/C++ -> General
In the Additional Include Directories paste the path
Combining folders and virtual folders in VC is from my point of view messy because the virtual folders indicate that all files are in one directory and the folders created on the harddrive obviously indicate that all files are in different directories. You can combine it if you know what's going on but in your case I would not recommend it.
I assume you missunderstand the purpose of stdafx.h The purpose of this header file is NOT to put all header filles into it and then just include it to all other files. Here is a SO question about this Purpose of stdafx.h
After cleaning up your stdafx.h file include as many header files into your .cpp files and only put these includes in your header files if they are required in the header file
Turn on show all files, now you will work with actual folders and you can be sure that if you adress a folder like "PKB" that this folder really exists since you can see it in the left solution explorer.
If you use using namespace std; for example make sure you also include the required header files. You might think "hey I already included e.g. iostream in another header file which I now include in this header file so I don't need it" That will really destroy you when you work with bigger projects.
Oh and regarding the stdafx.h include problem as soon as you switch to show all files I assume you will realise that stdafx is in a different file than the file where you use the include. Maybe something like #include "..\stdafx.h" is required (depending on your structure).
I think it's obivious but if you include a header file the include is allway relative to the file which is including the other header file.
stdafx.h is commonly used for creating a precompiled-header, which essentially is a compile-time optimisation such that the compiler will not continually compile these headers for every compilation unit.
If any of these headers changes, you will need to do a full system rebuild.
In reality it is preferable only to use it to include standard headers plus third-party headers (like boost libraries and similar) that you are not ever going to change.
You may decide that some of your own libraries are "set in stone" and can also be included.
Every project, i.e. every part of the project that is built into a separate unit (DLL or .exe) should have its own precompiled header and its own version of stdafx.h
Projects should only ever include their own .stdafx and not those of other projects, therefore this header file can also be used to define your dllexport macro.
When arranging your project headers you should be aware of:
1. Which headers are included externally
2. Which headers are only included internally, and are not even included indirectly externally.
The latter sort should include your stdafx.h file and should ideally not be in the same directory as those headers included from outside your project.

Project files' tree

Are there any articles or recommendations how to organize file hierarchy in your project? I am interested in how to name folders, to separate sources and headers or not.
I have project written in C++, a library and project using it. Library has many components, they are separated from each other but some of them use common files. Should I create directories for them?
I will be glad to hear all recommendations.
Do not split headers and source files into separate folders. It does nothing more than add an extra folder level.
At best it is completely useless; if you're looking for "widget.h" you can trivially find it even if there's a "widget.cpp" right next to it. At worst it's rather counter-productive - e.g. when you're editing "widget.h" and find that you also need to update "widget.cpp".
It's good to keep your namespaces in separate folders. Nest namespaces in the same manner as they are nested within your project. For instance, if you have:
namespace Foo{ namespace Bar{ } }
then you'd want any objects in the Bar namespace to be found in
{Foo's parent folder}\Foo\Bar\{how you're organizing code at this level}
We use an include folder for headers, a source for .cpp, a test folder for unit tests, and an object folder for compiled code bits. The reason we separate them is that it makes it easier to package the code in our scripts. You're always going to pass around the headers, you won't be passing around the source. (Here is another SO thread discussing separating header/source files. It's a preference thing.)
Here is a link to Google's style guidelines, if that helps.
I don't separate headers from source : it's a pain to browse
I usually have the subdirectories match my namespaces
+ Project root
+ <project_name> // namespace project
- sub_dir_1 // namespace project::sub_dir_1
- sub_dir_2 // namespace project::sub_dir_2
I only add "Project root" as an additional include path, so includes have the form :
#include "project/sub_dir_1/a.h"
#include "project/sub_dir_2/b.h"
Because source and header are usually named according to the class they contain, the whole qualified named can be deduced from the include path :
project::sub_dir_1::a is found in project/sub_dir_1/a.h
a.c trivially includes a.h (relative path provided)
If I must include a.h from b.h, I use absolute path (starting from the project/ root)

C++ project source code layout

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.