Currently viewing: GipsySoft » Front Page» Articles

Trouble Free Project Layout


The projects I write invariably involve some libraries, DLLs or shared header files. Developing and using libraries and DLLs can be a real hassle, the library can't be found, unresolved externals etc. and then once the program is linked it will not run because a DLL can't be found. The benefits of sharing the same binary code outweigh the hassles. This article describes my own method of overcoming the hassles of project structure, I have used this simple method for several years with only minor modification.

One of the biggest problems that has caused me to change the structure was having outside developers use my code. This was only a problem because I relied on the PATH, LIB and INCLUDE environment variables.

Other developers were unwilling to alter their environment, and who would blame them, so I was forced to alter mine.

Directory Structure

All of my projects exist below a directory from the root of a hard drive (which drive is irrelevant) in a directory imaginatively called projects.

Below projects I have a directory called components. Below components exist all of the project files, source code, resources etc. that build my components, with each component in a separate directory. This is how this structure looks for a project DLL called DebugHlp.

At the same level as components I have a directory called bin. This is where all compiled files go when built. This includes DLL, LIB and EXE files.

When I created the project DebugHlp I changed it's build settings so that rather than creating .\Debug\DebugHlp.DLL and LIB and .\Release\DebugHlp.DLL and LIB it would instead create ..\..\bin\DebugHlpD.DLL and LIB and ..\DebugHlp.DLL and LIB. The main header file for DebugHlp, that is the client interface for it, exists in the component/DebugHlp directory.

If you have shared project files then you'll need to add an extra include directory for every project. For example; DebugHLP doesn't need anything because it has no external dependencies but DialogSizer does because it uses DebugHLP. I added ../ to the extra include paths for DialogSizer so that an include of #include would work. I do this for every project I write.


What's in the 'bin'

All DLL, LIB and EXE files are built into this directory. This is required if an EXE depends on a DLL component you are building - the OS simply won't be able to find the DLL if the DLL and EXE do not live in the same directory.

I didn't like this at first as it meant that all of my projects named "demo" or "test" were now in the same directory and would clash. Now that I've been using it for a while I prefer it. It just seems so clean and simple.


Naming Your Component

When naming a DLL I like to stick to 8.3 format for the resulting filename (I have had some bad experiences when my code is installed on older networks). Of course, because I never ship the debug version of the DLL there is no problem with that ending up longer than 8.3

For each project I usually build a DEBUG and RELEASE version and I may build a UNICODE and ANSI version. Using these combinations can give me four DLLs and four LIBs. I have adopted the method of post-fixing the DLL/LIB name with U for UNICODE and D for debug. Thus MyLib could, and probably would, have the following names:
MyLib ANSI release
MyLibU UNICODE release
MyLibD ANSI debug

To alter the output names for a Microsoft Visual C++ DLL project you need to edit the settings on Link tab of the Project|Settings dialog, in the Category drop down list select General. In the Output file name edit control enter the new DLL name e.g. ..\DebugHlp.dll, then in the Project Options edit control at the bottom of this tab you will need to find and change the .PDB and LIB filenames so they have the same naming convention and will be output to the same directory.