Bad News for Scons Fans
We have been talking a lot about Scons recently at the Power of Two Games World Headquarters. MSBuild has proven to be quite a pain to work with for our asset builds and eventually left us dissatisfied (that’s material for a whole other entry). So we kept looking over to Scons as a possible solution.
On paper it looks great:
- Built from the ground up for parallel builds
- Uses a real programming language (Python) instead of overly-complicated XML files
- It allows for discovery of assets to build as other assets are parsed
The big question mark hanging over it was whether it was fast enough. I had done some experiments with Scons and other build systems a few years ago, and Scons totally failed by having ridiculously long incremental build times just checking if anything had changed. That was simply not acceptable. If no data has changed, I want the build system to detect it and come back in a second or less.
Since then, I’ve been told that Scons had finally fixed its dependency checking and it was much faster now. Music to my ears!
So I resurrected the old script I wrote back then to generate a nightmare stress test, downloaded the latest stable version of Scons (1.0.1) and fired it up.
I’m sorry to report that Scons is still as unusable as it was back then. I generated a codebase like the one I used to measure all the build systems (50 libraries, 100 classes each, 15 internal includes, 5 external includes). I built everything once, then ran it again and it took 49 seconds. I have some pretty nice hardware, including a fast SATA hard drive and a 2.8GHz Core2Duo with plenty of RAM, and 49 seconds to say that nothing needs to be changed just doesn’t cut it.
Now to be fair, right now we’re looking at Scons to build our assets, not our code. Maybe the nested project configuration is not particularly realistic, so I tried something simpler: 5000 files in a single library without any dependencies among each other at all. This is a very conservative example for an asset build of a large commercial game.
- It’s only 5000 files. A real game can easily have 10 times as many asset files.
- All the files are tiny (cpp files in this case). Assets can get very large when dealing with textures, sounds, and animations.
- There are zero dependencies among assets in this example. You’ll often have models depending on shaders and textures, levels on game entity definitions, etc.
Building assets doesn’t have to be the instant, no delay kind of build that I require building code. I expect most developers will be building assets locally, tweaking things, rebuilding, and trying them in the game. The faster the build is, the better, but a delay of a few seconds can be acceptable. If Scons can’t handle this build in less than 10 seconds, it’s certainly doomed in a full-scale game.
The result: 37 seconds!
For purely masochistic reasons, I decided to see how it scales, so I threw 20,000 files at it (again, without any dependencies). Incremental build time without any changes: 3 minutes and 46 seconds. That’s over 6 times longer for processing 4 times the number of files, so it doesn’t even scale linearly.
Scons is definitely too slow, and MSBuild has its share of problems. What’s left out there? Any recommendations for good parallel asset building systems? Hopefully something lightweight and easily configurable through a real language. Anything?
Related posts:



Frankly, I had never really considered test-driven builds. We’re definitely test-driving our data conversion tools (take this model from the intermediate format to the final one).
The main problems I see with a test-driven tool is that the high-level build process is a well-understood, generic process. It’s also a process that is highly performance sensitive and it’s going to be stressed with Gigabytes of data, so you want to parallelize it as much as possible. So given that, it seems that trying to adopt someone else’s solution is the way to go. Yes, there’s still no perfect build system out there, but they’re probably better than what a single person can do in a month or so.
On the other hand, if your game doesn’t have too much data, then you can just grab any of them (make, Scons, MSBuild) and be happy with it and you can spend your efforts in the things that really matter (the game). In general I’m not a fan of writing build systems from scratch as a set of custom scripts though.
Incredibuild XGE seems pretty good to me:
http://www.xoreax.com/technology_xge.htm
I haven’t got around to playing with these tools yet, but perhaps you might find some time if your get desperate enough?!
http://sham.sourceforge.net/
http://www.cs.berkeley.edu/~billm/memoize.html
They basically work off of the same idea: run the commands to do the build, monitoring the inputs and outputs with kernel hooks to generate dependencies information. No need to specify or calculate the dependencies explicitly via some heuristic hack.
I imagine it would be pretty easy to implement a parallel build system on top of these. You could simply write your build instructions sequentially in a list with certain barrier points. All commands between barrier N and N+1 could be run in parallel. e.g.
compile blah/foo.cpp blah/out/foo.obj
compile blah/bar.cpp blah/out/bar.obj
compile blah/baz.cpp blah/out/baz.obj
compile guff/foo.cpp guff/out/foo.obj
compile guff/bar.cpp guff/out/bar.obj
compile guff/baz.cpp guff/out/baz.obj
——————————————- # barrier
make-library guff/out/*.obj libs/guff.lib
make-library blah/out/*.obj libs/blah.lib
——————————————- # barrier
# etc …
Can anyone tell me what kind of license/cost KJam is?
Jam, the unsupported devil child of Perforce, may just be the ticket. Many people swear by the Boost version of Jam, I found the “ftjam” version easier to build and it takes the “precompiled header” extensions quite easily.
http://freetype.sourceforge.net/jam/index.html
Stephen Knight, creator of Scons, sits upstairs and works on building, among other things, Chrome. And yes, it sucks, but our previous system sucked more and knew nothing about being cross platform.
This page
http://www.scons.org/wiki/GoFastButton
says
The command ’scons –max-drift=1 –implicit-deps-unchanged’
will execute your build as fast as possible.
We’re using SCons for several years now to do all our asset builds, some code builds (lua wrapping classes), vcproj generation, test building, etc.
It’s horrible.
For one thing, it’s very slow;
Then, there is a constant stream of build-related problems every week (though perhaps we’re doing something wrong here).
Also SCons (as it seems) has a bug with complex dependency checking scheme – i.e. we have a .ma -> .dae -> binary file geometry pipeline, .dae file is scanned for textures, which are built before binary file, so binary file depends on them; if .ma has changed, then in some cases the dependency tree contains BOTH dependencies from old .dae file AND from new one (just generated).
And the best thing of course is that we’re not going to change it.
Hi,
There are two viable alternatives to scons.
The first one is waf. It was written after attempts to convert the KDE project’s build system to scons. After a while, Thomas Nagy found too many limitations in scons (including but not limited to the one you witnessed) and wrote his own build framework in python. It’s used by several open source projects but is not really mainstream.
The other alternative is September 19, 2008 at 5:24 am