Questions about typical project directory structures

Started by
5 comments, last by tstrimp 17 years, 5 months ago
Hi all, I'm just getting started on a fairly large software project, and was just wondering how most of you generally set up your directory structure. I've got my own ideas about how it should work, but not all of my team agrees, and I was hoping some more experienced developers could give us some guidance! The application is plugin based, and whole thing is split up into seperate projects - one for the core, and one for each plugin. It's all in a Subversion repository. We're using SCons as our build tool, and although it's cross-platform we'll still use project files for a few IDEs (MSVC and Eclipse primarily). As such, the current structure is something like this:

/
-branches/
-tags/
-trunk/
--core/
---branches/
---tags/
---trunk/
----SConstruct.py
----core.vcproj
----core.sln
----bin/
----build/
----docs/
----external/
----lib/
----src/
-----SConscript.py
--plugin1/
---branches/
---tags/
---trunk/
----SConstruct.py
----....

etc.
As far as we understand, it's standard fare to have branches, tags and trunk for each project in the repository, and I've shown them here. src/ is purely for source code (.cpp & .h), and a SConscript file. bin/ and lib/ are where binaries and libraries get built to. external/ contains headers and libraries for any external project we may use docs/ contains Doxygen generated documentation The confusion is mostly surrounding the build directory and src directory - I think that all generated files (mostly just .o files) should go in build/, leaving src/ unaltered during a build, and only containing source files, and lib/ and bin/ containing only the final result of compilation. Other team members think the source should be built to src/, which doesn't make a lot of sense to me. Also, since source control is meant for source and things required to build the source, do directories like build, lib and bin really need to be in the repository? Or should they just be created on the local machine when a build is invoked? So, really what I'm asking is: What project directory structures do you chaps use? What should the build/ directory be used for, if anything? Should lib, bin and build be in the repository? and lastly, what do you think of the layout mentioned above? Please don't reply with "it doesn't matter, just do what you want", since it does matter - this is eventually going to be open source, and I don't want it to be a complete mess! Thanks in advance!
Advertisement
The way I lay out my trunk is like this:

branches
--project-joes-i18n-experiment
----(stuff)
tags
--project-0.1
----(stuff)
--project-0.2
----(stuff)
trunk
--Makefile
--src
----(core-sources)
----subdirs
------(grouped-sources)
--doc
--bin

I let the object files build up with the source files that generate them, but I make sure to include a proper 'clean' target in my makefile. doc has the doxygen files and other notes. I keep README and TODO in the main directory. I do include a bin directory for the final executable, but I make sure to clean it too.

As far as externals, you can include them, but when you're distributing, you should leave it up to the end user (or developer) to install dependencies on their own.

Don't include the bin/object/external/doxygen files in your repository, but include the directories they will be built into.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Thanks for your reply, erissian, I've rated you up.

Don't you find that building to the source directory just clutters things up needlessly? It seems to me that building to another directory is so easy to do, there's not a lot of point in not doing it. It makes cleaning easier too; delete the build directory.

I figured externals should probably be left to the end users and developers, but unfortunately the team has decided to place these in the repository. It's going to be a pain checking out 72MB of boost libraries each....

Any other opinions on all this? I'm sure erissian can't be the only one!
Putting the libraries in the repository ensures consistent versions are being used by each developer. Besides, you only check them out one time (the first time), since they shouldn't be changing often.
We have a structure like this:

\projects\<gamename>\bin\core
\projects\<gamename>\bin\render
\projects\<gamename>\bin\plugin1
\projects\<gamename>\game\ // contains only launcher.exe
\projects\<gamename>\game\system // all binaries, dll's, ...
\projects\<gamename>\game\pak // content in big binaries
\projects\<gamename>\game\scripts
\projects\<gamename>\source\projects\<gamename>\source\core
\projects\<gamename>\source\render
\projects\<gamename>\source\plugin1
\projects\<gamename>\source\game
\projects\<gamename>\sdk\projects\<gamename>\tools

easy to erase all compiled files (obj, lib, ...) by just erasing
the bin directory.
Easy also to make backups of the sourcecode, since you don't
have 1 gb of lib's & obj's spread out everywhere in your source.

We also check in the sdk's in the cvs-repository - this way, if
anyone new comes to our company, they only pull the sources
and everything works - I've had several people react suprised
that it 'pull sources, rebuild, go' - no configuration needed.

A buildserver generates big zip-files from all our raw assets,
you only have to copy this into the \game directory and then
rebuild to get the latest version.

Don't put sdk's into a (subdir) of source because they tend
to grow big and slow down the update-process (esp on a windows
cvs-server) - and there's no need to update sdk's which rarely
change (but take lots of time to check if sth changed).

Tools are also check into a seperate dir - every little tool
related to our project gets in there, no matter how small.

visit my website at www.kalmiya.com
Quote:Original post by hymerman
The confusion is mostly surrounding the build directory and src directory - I think that all generated files (mostly just .o files) should go in build/, leaving src/ unaltered during a build, and only containing source files, and lib/ and bin/ containing only the final result of compilation. Other team members think the source should be built to src/, which doesn't make a lot of sense to me.

If you ever choose to go multiplatform, you would benefit immensely by having your build and source environments completely separate. That way, you can check kout a snapshot from SVN onto a share and build from that share simultaneusly on all your target platforms. Continuous integration, nightly builds, etc.

Also, if your source is kept clean it's a lot easier to know what to check in and what not to.
Quote:Also, since source control is meant for source and things required to build the source, do directories like build, lib and bin really need to be in the repository? Or should they just be created on the local machine when a build is invoked?

My experience: never ever check generated files into source control. It just won't work if you're multiplatform, and it results in wholescale churn on updates as everyone checks in their regenerated files with just the slightest platform differences.

There are more appropriate was to package and install the built products so developers can update when necessary. In fact, you packaging and distribution should be a part of your build (each target platform will have different requirements in this repect, as well).

Stephen M. Webb
Professional Free Software Developer

This is the way I have it setup now.

Not under source control
\Solution\build\Solution\build\Project-Debug\Solution\build\Project-Debug\bin\Solution\build\Project-Debug\tmp\Solution\include\Solution\lib


Under Source Control
\Solution\Project-Name\Solution\Project-Name\assets\Solution\Project-Name\assets\global\Solution\Project-Name\assets\debug\Solution\Project-Name\assets\release


Whenever an application builds it puts the executable file into \Solution\build\Project-Debug\bin\ and all of the tmp file associated with it (vs debug databases, .obj files etc) into the \Solution\build\Project-Debug\tmp\ dir. After that, the dlls associated with the application get copied into the \Solution\build\Project-Debug\bin\ directory along with any assets that are located in \Solution\Project-Name\assets\global\ then any assets located in \Solution\Project-Name\assets\debug\. The idea is that \Solution\build\Project-Debug\bin\ now contains a working copy of the application along with any resources needed to run it. I should be able to zip up that dir and send it to someone else to run (I also have copies of the msvc*80d.dlls in there). Nothing under the build directories is maintained under source control (we don't version executables yet).

If I'm building a library, it will still create the \Solution\build\Project-Debug\tmp\ folder but not the bin folder. The binary files get copied to \Solution\lib\ and the appropriate header files get copied into \Solution\include\.

The idea is that all source and assets are easily versioned in source control without having to worry about junk from builds accumulating in there. All the copying is handled with VS post build events. At some point I will setup the release build to trigger a scripted installer setup on the \Solution\build\Project-Release\ directory so that installers are automatically built as part of the build process.

This topic is closed to new replies.

Advertisement