views:

2223

answers:

3

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.

+1  A: 

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.

Zifre
+4  A: 

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.

Scott Langham
I agree that it will be overkill at the beginning. My concern is when the project gets going, and growth to a decent size, no one will want to spend the time to reorganize all the files and change all the include paths.
Shing Yip
Well, that might be true. But, you seem keen on keeping everything in order, so you could do it! I work in a company with about 60 developers divided into teams. A couple of weeks ago a number of teams spent a few days reorganizing their files. Keeping things organized is an ongoing process.. a good programmer refactors code when it gets out of hand, for example when a code file gets too big that it gets tricky to manage, they should split it. It's just the same with a folder of files.
Scott Langham
These teams could never have predicted 3 years ago what structure they'd need now. If they'd tried to guess then, I think they would have ended up needing to reorganize anyway. So, I shouldn't worry about it. If you're trying to develop a good practice at the start of a project, you're better of spending your time coming up with a good way of organizing how to unit-test the code, and how to get tests to run as part of an automated build... because unit-testing is definitely something that's hard to introduce once you're underway.
Scott Langham
+3  A: 

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

Caleb Huitt - cjhuitt
Yeah, navigating the directory is going to be a major annoyance. But a good editor/IDE will help. gf in VIM or Ctrl-Shift-G in Visual Studio will open the header file for you. I know some developers just symlink all the files they care about into their own directory structure.
Shing Yip