File organisation - directory structure
Hi, sorry if this post is a bit long.
Before now I've only worked on very small projects which have consisted purely of a bunch of .cpp and .h files in a single directory. However, I'm not working on something a little bit larger, and I'm trying to be more organised by separating my header files from my source files, etc.
I'm using Anjuta (http://anjuta.sourceforge.net), and my project directory contains a directory called 'src' and another called 'include' (this is how Anjuta set it up for me). I've put my .h files in project/include and my .cpp files in project/src.
My project (at this early stage) contains a bunch of classes (mostly only entity management stuff right now) which I'm trying to make as reusable as possible, and some other code which uses these classes to make a functional application. I realised I should get the reusable stuff (engine-ish) separate from the rest too. So I created another directory for it - let's called it 'engine', and placed my class .h and .cpp files in there.
So now my directory structure looks like this:
project/
....src/
........main.cpp
........CSprite.cpp
........CSpriteFactory.cpp
........etc.
....include/
........CSprite.h
........CSpriteFactory.h
........etc.
....engine/
........CRenderer.h
........CRenderer.cpp
........CEntity.h
........CEntity.cpp
........CEntityFactory.h
........CEntityFactory.cpp
And so on... That little diagram-ish thing is just rough and incomplete...
Anyway, even at this stage I'm facing problems getting stuff to compile correctly. I've had to change lots of #include statements and stuff as you'd expect, but now I'm still getting lots of linker errors. However, I'm not really asking how to solve my linker errors - I can probably sort that out by myself. What I want to know is how I should really be organising my files here. See, by doing it this way things are a little tidier but now I have a new problem:
I'll want to maintain the 'engine' files as their own project probably... And that would mean separating the engine's .cpp files from it's .h files (they're currently all in the same engine/ directory.
The other thing is that although the engine files should sort of be their own project, they need compiling and linking with the application's files when I compile my project... So should the engine files be in both the engine project and the application project?
I've just confused myself here really... I'm not even sure if I'm making sense. My inexperience is probably a bit too obvious right now.
Before I go any further and make a big mess of this, I'd like to ask how some of you people organise your projects, so that I can learn something from your experience. I'm not sure if it was really necessary for me to go into a detailed explanation of what I've done with my files, but oh well. I'm interested to know how I can do it without running into problems.
Thanks.
Your "engine" should have been an Anjuta project of its own, with its own src and include directories. If Anjuta supports it, make "engine" a sub-project. Also read this article to understand the fundamentals of organizing and compiling C source code files. Once you have a firm grasp on that, you can organize the files as you see fit and consider optimal.
At work we have a large project that is written in Visual Studio. The software is plugin-based, and we have a directory structure something like this:
main directory
|
+-- plugins
| |
| +-- type 1 plugins
| | |
| | +-- plugin (cpp & headers)
| | +-- etc
| |
| +-- type 2 plugins
| |
| +-- plugin (cpp & headers)
| +-- etc
|
+-- include (some headers)
| |
| +-- common (headers for common plugin)
|
+-- common (cpp for common plugin)
|
+-- shell (cpp & headers for app shell)
"common" is a common plugin (dll) that all plugins and the shell use so we have that stuff in a separate directory.
Hope that gives you some ideas!
cheers
sam.
main directory
|
+-- plugins
| |
| +-- type 1 plugins
| | |
| | +-- plugin (cpp & headers)
| | +-- etc
| |
| +-- type 2 plugins
| |
| +-- plugin (cpp & headers)
| +-- etc
|
+-- include (some headers)
| |
| +-- common (headers for common plugin)
|
+-- common (cpp for common plugin)
|
+-- shell (cpp & headers for app shell)
"common" is a common plugin (dll) that all plugins and the shell use so we have that stuff in a separate directory.
Hope that gives you some ideas!
cheers
sam.
This organisation is experimental, and I'm currently in the process of converting a large project to use it, but I spent awhile planning it, and I think it'll work out nicely. Ok, here's the overall structure.
Solution
....Game
........Source Files
........Header Files
....Engine
........Source Files
........Header Files
....Math
........Source Files
........Header Files
The "Solution" is basically just a collection of projects. In this example, I'm making a game that has a few seprate components, such as the math library and 3D engine, so I put these seperate components into their own projects. A project should output some kind of standalone library or executable. All source files that belong to a project go into either the "Source Files" folder, or the "Header Files" folder, depending on what they are. It's not a good idea to shove the cpp and h files in the same folder, because things like static libraries require the header files to be available for use by other projects, in order for them to use that library. If you want to send this library to someone else, you'll need to seperate all those header files. I used to split the header files into a few other folders too, for things like inline files and macros, but I stopped doing that, because then you have to add multiple folders to the header search directories when using that library in a seperate project, or qualify all #include statements with the folder name, which is just unnessicary hassle.
When doing a build, the projects output all their junk into either a Debug or a Release subdirectory, depending on whether I'm doing a debug or a release build. The final binary however (be it an executable or a library or whatever) is outputted into the main project directory. A debug build is prefixed by "DBG_", to make it perfectly clear that something is a debug build, so I don't accidentally use or release a debug version, thinking it's a release version. It's also nessicary, because I don't want debug builds overriting my release builds, and vice versa. I output both the release and debug binaries into the same directory, because in the case of a game, there is often external data that game needs, and having them in the same folder allows me to give them the same general "data" folder, without having to put a full pathname in the file, or duplicate the data into both the debug and release folders.
In the case that I have a solution that contains multiple projects, under VC++.NET, I set the build dependencies for the solution, so if the Game project relies on the Engine and Math projects being built, I set that association, and now it can manage things like order of compilation for me. I also configure the debug configuration of my executables to link to the debug versions of my libraries, while the release versions of my executables link to the release versions of my libraries. This means I can trace into my math library, if I get an exception in it while running my game, but when I compile in release mode, I get the optimised release versions of both.
Anyway, that's the basics of how I arrange the basic project setup and the folder structure. I also have a system for arranging my source files into logical folders within a project tree, as well as a system for generating my header file structures, but I won't go into them unless you want me to (too much typing).
Solution
....Game
........Source Files
........Header Files
....Engine
........Source Files
........Header Files
....Math
........Source Files
........Header Files
The "Solution" is basically just a collection of projects. In this example, I'm making a game that has a few seprate components, such as the math library and 3D engine, so I put these seperate components into their own projects. A project should output some kind of standalone library or executable. All source files that belong to a project go into either the "Source Files" folder, or the "Header Files" folder, depending on what they are. It's not a good idea to shove the cpp and h files in the same folder, because things like static libraries require the header files to be available for use by other projects, in order for them to use that library. If you want to send this library to someone else, you'll need to seperate all those header files. I used to split the header files into a few other folders too, for things like inline files and macros, but I stopped doing that, because then you have to add multiple folders to the header search directories when using that library in a seperate project, or qualify all #include statements with the folder name, which is just unnessicary hassle.
When doing a build, the projects output all their junk into either a Debug or a Release subdirectory, depending on whether I'm doing a debug or a release build. The final binary however (be it an executable or a library or whatever) is outputted into the main project directory. A debug build is prefixed by "DBG_", to make it perfectly clear that something is a debug build, so I don't accidentally use or release a debug version, thinking it's a release version. It's also nessicary, because I don't want debug builds overriting my release builds, and vice versa. I output both the release and debug binaries into the same directory, because in the case of a game, there is often external data that game needs, and having them in the same folder allows me to give them the same general "data" folder, without having to put a full pathname in the file, or duplicate the data into both the debug and release folders.
In the case that I have a solution that contains multiple projects, under VC++.NET, I set the build dependencies for the solution, so if the Game project relies on the Engine and Math projects being built, I set that association, and now it can manage things like order of compilation for me. I also configure the debug configuration of my executables to link to the debug versions of my libraries, while the release versions of my executables link to the release versions of my libraries. This means I can trace into my math library, if I get an exception in it while running my game, but when I compile in release mode, I get the optimised release versions of both.
Anyway, that's the basics of how I arrange the basic project setup and the folder structure. I also have a system for arranging my source files into logical folders within a project tree, as well as a system for generating my header file structures, but I won't go into them unless you want me to (too much typing).
I use similar layout as Nemesis2k2. Except that I have .h and .cpp in same folder, I use only folders in Visual Studio project to organize these files.
All my directories are separate projects, so it looks like this:
Solution:
..test_application
..engine
..core
..opengl
..math
..ui
..vis
Every folder is separate project. engine and opengl compile as dll, others as static lib, test_application as application of course.
All my directories are separate projects, so it looks like this:
Solution:
..test_application
..engine
..core
..opengl
..math
..ui
..vis
Every folder is separate project. engine and opengl compile as dll, others as static lib, test_application as application of course.
Thanks for the advice guys.
As I say, I've never worked on a project where more than one component is present, such as the situation I described where I have engine code separate to application code.
Should I be doing something like create an 'engine' project which builds a dynamic library, then create the 'application' (or 'game', whatever) project which links to the engine library and builds an executable? Is that a way of doing it?
I've not tried making my own libraries like that before so I'll need to read up on them I guess. If I built a library with my engine project, then my game project would just need to link to the engine library and include the engine headers, right?
EDIT: Started typing that out before you posted your reply, b2b3. Your post partially answers this I guess. How do I decide when I want to use a dynamic library and when I want to use a static one? Is it purely to do with whether or not I want the reduced executable size and saved memory of using dynamic? In that case, wouldn't I always want to use a dynamic library? When is a static library preferred?
As you can tell, I'm not familiar with the whole library business.
As I say, I've never worked on a project where more than one component is present, such as the situation I described where I have engine code separate to application code.
Should I be doing something like create an 'engine' project which builds a dynamic library, then create the 'application' (or 'game', whatever) project which links to the engine library and builds an executable? Is that a way of doing it?
I've not tried making my own libraries like that before so I'll need to read up on them I guess. If I built a library with my engine project, then my game project would just need to link to the engine library and include the engine headers, right?
EDIT: Started typing that out before you posted your reply, b2b3. Your post partially answers this I guess. How do I decide when I want to use a dynamic library and when I want to use a static one? Is it purely to do with whether or not I want the reduced executable size and saved memory of using dynamic? In that case, wouldn't I always want to use a dynamic library? When is a static library preferred?
As you can tell, I'm not familiar with the whole library business.
Quote:Should I be doing something like create an 'engine' project which builds a dynamic library, then create the 'application' (or 'game', whatever) project which links to the engine library and builds an executable? Is that a way of doing it?
Yes, that's the way you should be doing it. In the case of the example I posted, the Engine and Math projects build static libraries, which are used by the Game project, to output an executable that incorporates them.
Quote:If I built a library with my engine project, then my game project would just need to link to the engine library and include the engine headers, right?
Correct.
Quote:How do I decide when I want to use a dynamic library and when I want to use a static one? Is it purely to do with whether or not I want the reduced executable size and saved memory of using dynamic? In that case, wouldn't I always want to use a dynamic library? When is a static library preferred?
You've got a few things wrong there. While you'll get a reduced executable size, the combined size of the seperate dll and your executable will be larger. Memory usage will also be larger, because that dll will need a whole page of memory to itself. You will also loose cache efficiency.
Dynamic link libraries have several features, that quite simply allow you to do some things you can't do with static libraries, namely:
1. If you update a dll, every program that uses it gets the advantages of the new dll instantly. With a static library, when you want to update it, you have to recompile every program that uses it in order for them to benefit from it
2. A dll can be linked dynamically (funnily enough), which means that you can support the concept of a plugin system. If someone supplies you with a filename for a dll, and a function name within it, you can load that dll and call that function. It's a very powerful feature, and the only real way to do it.
These two things however are really the only advantages of it. Unless you're going to have a massively used library in many programs, most importantly, programs that you haven't made (ie, ones you don't have the source code for, and can't recompile to use the never version), or you want to allow another programmer to replace or add components as plugins, you probably don't want to make it a dll. A dll is more powerful, but it comes at a cost of performance.
Thanks a lot for the info - very useful.
I see your point. A static sounds like it would be more efficient.
Should I link to the library file sitting in the engine project directory, or should I copy it somewhere first or something? Or in other words: is there any reason not to link to the copy which is overwritten each time I rebuild the engine?
I see your point. A static sounds like it would be more efficient.
Should I link to the library file sitting in the engine project directory, or should I copy it somewhere first or something? Or in other words: is there any reason not to link to the copy which is overwritten each time I rebuild the engine?
No, in fact, you should. This way, when you make a new build of the engine, that new build will automatically be used the next time you recompile your game.
I have engine as dll, because I wanted to try it. opengl is only renderer dll, because I want(ed) to support multiple renderers which can be loaded dynamically.
others are static libs, because it's faster and simpler to use than dll.
others are static libs, because it's faster and simpler to use than dll.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement