When you work on some bigger project, it is important to properly organize its directory structure. Most of the time, you have to prepare project directory structure yourself, as an IDE will create only a basic solution for you.
For example, Visual Studio will create folders named “Debug” and “Release” (just like the current active configuration) with the output executable file in the solution directory, and a similar pair inside sources directory for .obj files. This is a very simple approach, and putting object files inside a folder containing sources is not really version-control-system-friendly. Each time you want to commit some changes in the source files directory, new .obj files in “Debug” or “Release” subfolders are also detected, so you have to ignore these messages or create permanent .gitignore rule for them (if you use Git).
Projects often consists of additional data files, documentation and so on. Putting it all together into one directory would create a real mess. Keeping them outside a project directory, in a different place on a hard disk, can be problematic too, especially when you want to easily distribute the project to other users. No one likes to get error messages such as File K:\!data\gfx\shaders\post\fast-blur.cgfx not found!
. Ideally, the project should be self-contained, and easy to build.
There are no official C/C++ project directory layout directives, so here’s just one possible solution:
- bin – Output executables (“targets”). The suffix “_d” indicates debug version.
- data – Files used by the main executable.
- doc – Project’s documentation, possibly auto-generated.
- deps – Subdirectories with external dependencies like libraries.
- obj – Binary objects created during compilation.
- src – Source files of the project with subdirectories if needed.
- test – Source files of tests.
- .gitignore – Prevents adding binary and temporary files to the git repository.
- LICENSE – Describes how this project can be used and distributed.
- README.md – General information about the project in Markdown format.
- project.sln – Visual Studio solution.
- project.vcxproj – Visual Studio project.
Additional notes
- Sometimes the project is developed for both x86 and x64 architectures. In this case, “obj” structure should reflect this as:
..and created executables can be named as:
project.exe
project_d.exe
project_x64.exe
project_x64_d.exe
- If there are many source files and they can be grouped logically, the “src” directory should represent this as well.
- If there are more than one project files (for different IDE’s or versions), and you don’t want to clutter the root folder, you can move them to a separate directory like:
The downside of this is that the project will refer to source files like ../../src/main.cpp
. Paths that go up and down through folder structure are not the most readable ones, but this is still much better solution than using absolute paths.
- Example .gitignore file:
# skip binary, temporary and user-specific files [Bb]in/ [Oo]bj/ *.suo *.sdf *.user *.opendb
Also, check out a collection of useful .gitignore files for different languages and technologies.
Summary
Keeping things organized is important, but there is no one-size-fits-all solution. For other types of projects, a different directory layout may be more suitable. For example, in case of a library project, the “bin” folder should be renamed to “lib”, and a separate “include” directory will allow an easy deployment of the package to the end user.
Also, remember to not over-engineer your project’s structure. You probably don’t need too many levels of subdirectories and do not want to spend a day devising “the perfect structure” suitable for all types of projects. Keep it simple and functional.