Before we get started i'd like to thank Corbin Hart who gave me the original version of this build system which immensely helped our team. The build system itself is made up of multiple parts and is defined by the folder structure, the build script generator tool, and the configuration files. In this post we are going to be talking about all of these things and how you can take the build system my game team has been using and tailor it for your own needs.
What are build script generators?
To steal from Premake's website:
Imagine yourself the owner of an open source software project. Your users are asking for a Visual Studio 2008 solution, but you don't have Visual Studio! Or perhaps you are a cross-platform game developer struggling to keep projects, solutions, and makefiles in sync. Its a common problem for open and cross-platform projects: restrict yourself to a single, potentially sub-optimal build tool—driving away potential contributors—or manually maintain two, three, or more sets of build scripts.
Not working cross-platform? Have you ever been stuck using an old version of Visual Studio because it was too difficult to upgrade the entire team?
Or maybe you just want an easy way to reconfigure your project for different situations or environments, pulling in different source code or libraries, switches and options.
- You no longer have to worry about Visual Studio solution or project file conflicts when merging branches. Instant time saver.
- Smaller repository size (no more Visual Studio build artifacts.)
- Easy to implement cross-platform support.
- Easy to support multiple compilers, and IDE's.
- Easy to organize your source code, dependency code, and build configuration data.
- And much more!
- Your Visual Studio solution usually needs to be rebuilt every time you pull or merge branches when using subversion. You need to do this since new file might have been added and your solution won't be updated to accommodate these new files until you've rebuilt it.
- You should have your repository ignore the directory which contains your actual Visual Studio project files since they are intended to be temporary per-machine files.
- You must use physical folders to organize your code instead of putting them in filters which you have done before when using Visual Studio.
- You can no longer use the "Add > New File" option in Visual Studio unless you make sure that the file is being created in the correct place.
How can build systems help improve my team's productivity?
I highly recommend you follow along with this post by configuring the build system to work with your own game project. Here is the download. Since this uses Premake you are going to need to know a very minimal amount of lua.
If at any point you want more explanation relating to a premake4 feature visit their wiki for the official documentation.
So go ahead and unrar the build system and take a look.
Which folders do what?
- bin - This folder acts as the working directory for your program when it runs, you're going to want to put your content in here.
- build - This folder contains the base build system configuration files and your visual studio solution will be created inside of this directory in a sub folder called vs2013. It also has the GenerateBuild.bat which is the one-click way of creating your solution. Something important to keep in mind is that the vs2013 folder should be ignored entirely by your subversion software, never ever push it to your repository!
- deps - (short for dependencies) Any third-party libraries belong here in their own folders. If these third party libraries must be compiled then the build system will create a second solution called deps which is used to compile all of these libraries.
- src - All of your game code belong inside of this folder. If your game consists of only one project then you're doing things wrong. Your graphics, physics, core engine, and gameplay logic should all be in different projects, this will help will keeping things logically separated and helps prevent silly dependencies (it also has many other benefits.)
- tools - Any tools used in your build system should go here, for instance the actual premake executable.
Now that we've gone over the main folders we're going to go right in and start by adding some new projects.
How do I add new projects?
- project - This is the first thing you'll see, this is the name of the project, once again you should probably name it the same thing you named the folder.
- kind - This is the type of project, this could be a WindowedApp, StaticLib (lib), SharedLib (dll), or ConsoleApp.
- pchheader/source - This is for using a precompiled header (which you really should!) you can change the path and name if you wish but make sure you have one before building your project.
- files - This is for all of the header and cpp files you want included inside of your project (view-able from the solution explorer in Visual Studio.) The * character acts as a wildcard and the ** character acts as a recursive directory/file wildcard.
- includedirs - This is for including directories to look for header files from other projects and libraries. You need to include "../(Project/FolderName)" by default so that your project can use it's own header files. You should also include your global include directories (using Core.includedirs). If your project relies on things like FMOD or WWise then this is where you would add in the directory to look for their header files.
There are a number of variables which you can use for getting useful directories like src (by using srcdir), deps (by using depsdir), and bin (by using bindir).
- deps - This is where you want to put all of your dependencies that need to be linked for your project. This only matters linking wise if the project is a WindowedApp or a ConsoleApp since they actually produce executables, however by filling this in you allow Visual Studio to establish the order in which to build your projects. Including your global dependencies here is useful (Core.deps).
- defines - Preprocessor defines go here!
- libdirs - This is where Visual Studio will look for the .lib files it needs to link. Once again it's only useful if the project produces an executable. You're going to use this for third party libraries which you aren't building yourself (like FMOD.)
- postbuildcommands - Sometimes you're going to want to run command line options after building, this is where you'd put the command. What's nice is Visual Studio macros (stuff like $SolutionDir) still work here.
- configuration - These defines specific configuration for building this project. Unless you're going to support multiple compilers i wouldn't worry too much about this, what's important however is the ability to declare Debug and Release configurations using this. For more information visit this page.
- Additional Settings - There are a number of additional settings which can be used that can be found on Premake