How to logically organize source files in C++

12,991

Solution 1

I generally recommend not to use (only) the IDE or the language syntax for organizing your source code. For one, you tie yourself to the environment: well organized in the IDE, unorganized on file, and then comes the day when you might want to use a different environment...

Because of this, I usually use all three ways of organizing my source at the same time: I separate my source into functional modules, i.e. related classes. Each module gets its own namespace, physical folder, and IDE folder. (In my case, using CMake and source_group() to generate IDE project files if needed -- personally preferring the command line, Vim, and "make".)

Hence, whether I look at the project from within the IDE, from the command line, or from a compiler log, foo/some_class.hpp is foo/some_class.cpp is foo::some_class, minimizing confusion all around.

Actually, my currently preferred setup further subdivides each module directory into <project>/<module>/<class>.hpp or <project>/<module>/src/<class>.hpp depending on whether the class is used outside its own module or not, <project>/<module>/src/<class>.cpp, and <project>/<module>/test/<class>_tu.cpp. Namespace is <project>::<module>::<class>, of course.

project
|-- foo
|   |-- some_class.hpp
|   |-- src
|   |   |-- internal_class.hpp
|   |   |-- internal_class.cpp
|   |   `-- some_class.cpp
|   `-- test
|       |-- internal_class_tu.cpp
|       `-- some_class_tu.cpp
|-- bar
|   |-- ...

The idea here is that the "external" interface of each module (foo) is documented by the headers in that subfolder, with implementation details and tests "hidden" in the respective subfolders.

But in the end, it very much depends -- on your taste, on that of your co-developers, and the scope of your project.

Solution 2

This is how I roll:

PROJECT_NAME
|-- build // This is DVCS ignored but has all the built intermediates and final binaries
|   |-- release // These are the different build profiles
|   |-- debug
|   |-- profile
|   `-- coverage
|-- bin // For binary source code
|   `-- hello_world
|       |-- doc
|       |-- inc
|       |-- src
|       |-- tests
|       `-- build_script  // Builds binary into the build folder
|-- include // Public headers for the library
|   `-- these
|       `-- folders
|           `-- represent
|               `-- namespaces
|                   `-- my_awesome_class.hpp
|-- lib // library source code
|   |-- these
|   |   `-- folders
|   |       `-- represent
|   |           `-- namespaces
|   |               |-- inc // Private headers
|   |               |   `-- my_private_class.hpp // internal class
|   |               |-- src // Source code for this namespace
|   |               |   |-- posix
|   |               |   |   `-- my_awesome_class.cpp // posix specific source code
|   |               |   |-- nt
|   |               |   |   `-- my_awesome_class.cpp // nt specific source code
|   |               |   |-- my_private_class.cpp // non-visibile class
|   |               |   `-- my_awesome_class.cpp // cross platform source code
|   |               |-- tests // Unit tests
|   |               |   `-- my_awesome_class.cpp // builds a test executable for the library
|   |               `-- doc // Documentation for this namespace
|   |                   `-- namespace.dox
|   `-- build_script  // Builds binary into the build folder
|-- doc // Documentation files
|   |-- main_page.dox
|   `-- namespace.dox
`-- build_script  // Builds the source code into the build folder

This represents the these::folders::represent::namespaces::MyAwesomeClass class which has posix and NT specific source code (as well as generic source code) plus there is a private these::folders::represent::namespaces::MyPrivateClass that is used internally in the library, the headers are not public and the visibility of the class symbols are hidden.

This has scaled very well and provides easy locating of files.

Share:
12,991
arkon
Author by

arkon

Updated on June 17, 2022

Comments

  • arkon
    arkon almost 2 years

    My source file pane is quickly growing (in terms of the number of files in my project) and it is getting a bit cumbersome to quickly locate the specific source file I need to access at any given time. I'm using Embarcadero's C++Builder, but I have encountered this issue in other C++ IDEs as well.

    In Java, I often utilize packages for creating logical divisions of my source code, especially when dealing with a large number of source files in a single project. While this, of course, isn't the only purpose of Java packages, they are very handy in this regard.

    Does anyone have any ideas on how I can achieve similar functionality in C++? Should I separate my source into physical folders? Does C++Builder offer some kind of virtual folder/grouping functionality that I'm just not seeing? Any ideas are appreciated and thank you.

  • arkon
    arkon about 11 years
    I actually indicated (in my first sentence, in fact) that what I'm dealing with is a project. My problem is organizing the source files within that project. When dealing with a relatively large number of classes, giving them clear names simply isn't enough.
  • arkon
    arkon about 11 years
    This seems like it will be the all-around best solution. Especially if my projects migrate to a different IDE in the future and since it will cover me on all fronts. Thanks for your helpful answer.
  • Offirmo
    Offirmo about 11 years
    out of source build is also quite neat. I'll suggest removing the build dir and build from ../build_whatever_mode.
  • DevSolar
    DevSolar almost 6 years
    @b1nary.atr0phy: Perhaps you might be interested in JAWS (something I have set up in the meantime)...