tags:

views:

355

answers:

5

I am having a bit of trouble organising my source files.

I have my own small, but growing collection of code that I would like to use in various projects. The file and folder layout is something like this:

library\sub1\source.h

library\sub1\source.cpp

library\sub2\source.h

library\sub2\source.cpp

One of my problems is that I want to include this code, as needed, in my other projects. To date I have used absolute paths to point to the libary code, but there must be a better way.

Futhermore, I need to add every library file I use to a project's files Visual Studio in order for it to compile correctly.

So my question in short is how do I fix this? What is the proper/best way to handle the above situation.

+1  A: 

Take a look - C++ Programming/Code/File Organization

adatapost
The link does not provide information on the particular question of how to organize .h/.cpp files in directories.
David Rodríguez - dribeas
+2  A: 

I don't think that there's a proper way to do this - it's going to depend on exactly what you are trying to achieve.

Here's some things you might not be aware of:

  • You can use relative paths in your projects.

  • You can use environment variables in paths.

  • You can add directories to Visual Studio's search rules.

This gives you a little more control over where you put the include files and if you add your folders to Visual Studio's search rules you don't have to include any paths at all.

ChrisF
+1  A: 

First: Add all used directorys to your project include paths. Add them as relative paths if possible.

Second: You must add all used librarys/source files to your project. This can be either done in the project explorer, or in the Project->Linker tab. In the latter case, you'll have to add the used directories to the projects library paths as well.

Usually its not a good idea to use paths in #include directives.

RED SOFT ADAIR
+2  A: 

You shouldn't, in general, add source files from libraries directly to other projects. Compile them separatly as a library and use those.

For organising the library's directory structure itself, right now I settled on something like the following structure

  • library1/widget.h
  • library1/private/onlyinlib.h
  • library1/private/widget.cpp

(and if applicable)

  • library1/private/resources/widget.jpg
  • library1/private/project/widget.xcode

I put all headers directly in the library path, and have a subfolder private which will contain everything that's only used by the library, but should never be shared / exposed.

The greatest advantage is that every project I start only needs a include path pointing at the directory containing my libraries, then every (public) include is done like

#include "library1/widget.h"

private includes are simply

#include "onlyinlib.h"

This has a number of advantages:

  • If new libraries are introduced, there's no messing with project /compiler settings to get the headers 'visible'.
  • Moving to other compilers / platforms is also very little hassle.
  • The headers are automatically 'namespaced', i.e. by including part of the path too, it's next to impossible to get a nameclash with the includes
  • It's immediatly obvious where a header comes from, and if a header is part of the public interface or not
Pieter
A: 

If you must include third-party code instead of just linking with a pre-compiled version (e.g., perhaps you need to make modifications or tweaks to it), consider branching it in whatever you use for source-control:

  • /trunk/... --- your code goes here
  • /thirdparty --- pristine copies of third-party libraries go here
    • /thirdparty/lib1
    • /thirdparty/lib2
    • etc.
  • /trunk/lib1 --- branched from: /thirdparty/lib1, perhaps with local changes
    • this is the version that you build/link with.

Assuming you use a decent source-control system, this scheme will allow you to easily upgrade to newer versions of third-party libraries and then merge those changes with the changes you've made locally.

For example, suppose "lib1" releases a new version:

  • Commit the change to /thirdparty/lib1.
  • Merge from /thirdparty/lib1 to /trunk/lib1
  • Fix any merge conflicts.

This is, IMO, the only sane way to handle upgrading third-party libraries to which you've made local modifications.

ijprest