Mariusz Bartosik's website

Graphics programming, demoscene and book reviews

Directory Structure for a C++ Project

Project directory

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).

Default directory layout in Visual Studio. Some files omitted for brevity.
Default directory layout in Visual Studio. Some files omitted for brevity.

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:

Custom directory layout
Custom directory layout
  • 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:
Extended objects directory
Extended objects directory

..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:
Extended projects directory
Extended projects directory

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.

Avatar

Written by Mariusz Bartosik

I’m a software engineer interested in 3D graphics programming and the demoscene. I'm also a teacher and a fan of e-learning. I like to read books. In spare time, I secretly work in my lab on the ultimate waffles with whipped cream recipe.

Comments

Comments are automatically closed on articles older than 512 days.