All of the current build systems are lacking in a lot of ways. It's a sad fact. The following is an outline of what I believe makes for a good build system.
- Cross platform
- The same build script should be able to build on all platforms without any modifications
- Each platform's implementation will be modified to facilitate this, the implementation knows where things are located, what things are available, and what proper substitutes exist if any
- Modular build list construction
- There should be more than one way to tell the build system what to do
- Python construction
- One method of construction should be short, concise and expressive, a python based method would be appropriate
- XML construction
- The other method should be universally legible by applications, XML is exactly that.
- Unlike other XML based systems, however, this should also be as short, concise, and as expressive as possible, so that hand editing of XML files is possible.
- File globbing
- Files should be accessible as groups as well as individual files.
Globbing
- Specifying *.cpp would collect all of the cpp files in the current directory.
Regex
- Regular expressions will be available to seek out files
Modular build process
- Support multiple languages
- Support cross compiling
Variant builds
No configuration
- Build list construction often is plagued by conditionals
- These obfuscate the build list
- They complicate the build list
- ‣ They reduce time spent on the program itself
Fast Incremental Builds
- Daemon mode
- The program could stay resident and accept commands from the "client" program
- Pickle classes in between running
Should not clutter development directory with intermediate files
Now, there are plenty of build systems out there and each should be considered.
Autotools -
This is the oldest and the ugliest of the build systems. It requires multiple input files, and often one in each subdirectory. Autoconf files are written in the arcane M4 macro language, a language few bother to learn except to write autoconf files. A build system should not force the programmer to learn an entirely new language, if the build listing insists on being a script, it should be a well known language. Autoconf files have the added complexity of requiring extensive configuration and checks. This is a product of the times, the fact of the matter is, nowadays POSIX compliant systems all provide a sane or semi-sane build environment, which can be taken for granted. Automake files require the tedious listing of each individual source file, resulting in long lines or excessive line breaks, not to mention the monotony of cracking open the file and adding yet another source file to the list every time a new file is added. Then there's the fact that autotools is more than one tool, it's an entire toolchain, each of which must be invoked separately and in the correct order to build a project, the fact that most every project inevitably creates its own autogen.sh is a testament to this sad fact. Last, but not least, autotools mucks up your development tree with tons of intermediate files, and at the end of the day the product is a simple makefile. (
And of course there's the issue of recursive make)
SCons -
SCons gets a lot right, it uses a well known scripting language, doesn't clutter the development environment with intermediate files (at least not SCons intermediate files, object files are ok) and simple SConstruct files can be made relatively quickly. Now for the bad, the worst thing about SCons is the amount of documentation browsing required to compile a simple c++ program with a few library dependencies. Add to that the fact that half of the functions in the documentation are, well, undocumented, and you have a recipe for a lot of hair pulling. Another annoyance is the fact that you must list source files individually, the way around this of course is importing the glob module and using it, but that sort of functionality should already be included. In the end SCons isn't a terrible build system, but there are a lot of places it needs work, especially in the API provided.
CMake -
Next to autotools this is my least favorite of the bunch, I have plenty of gripes with it, though admittedly i never delved too deep into it. This is another makefile generator, and like all makefile generators it is limited by the capabilities of make, including the aforementioned recursive make problem. CMake makes many things easy, but most example files are heavy on conditionals and configuration. Including libraries is also non-trivial, it involves including multiple CMake files such as FindOpenGL.cmake and using the libraries after that, to add to the confusion these modules aren't uniformly named and aren't available for all libraries one might need. CMake also uses its own scripting language which isn't horrible, however, it isn't well known outside of the cmake community.
Waf -
I was excited about waf when I first heard about it and saw how it worked, however my soaring expectations were quickly shot down when I finally used it. I'll start with the good, because there was a lot of it. First, the script files were in python, a big bonus, many people dabble in python and would know enough to get by in waf. The second good thing was the scripts were well organized, they were divided into different functions which had different tasks. It supports variant builds and the icing on the cake was, it supported an XML format. Now for the bad, first of all it's immature and it shows. It was hard to tell what was a bug and what was intended behavior. It was totally unintuitive for me, I always want to write one script in the project directory and be done with it, but waf didn't function correctly unless I put one in the source dir that did all the work, and the script in the project directory had to explicitly delegate work to the script in the source directory. Then there was the uselib system, which seemed rather roundabout and cumbersome, far more work than I feel is necessary. As for the XML format, it was a mess, little more than a python script formatted like XML, hardly the short, concise build list I was hoping it would be.
Note: I know I have left out a few build systems including plain old make, Ant, NAnt and a few others, however I don't have enough experience with the Ants to speak about them, and make's shortcommings are well known.
Having expressed my displeasure with all of the current build systems it's now time for me to transform from a whiner into someone who will do something about it, I've been working for a time on my project which I call "yams" which stands for yet another make system. My project aims to fulfill all of the goals mentioned above, and possibly more in the future, it currently does nothing, but I hope to work on my system this summer and turn it into something worthy of attention and praise.
So what do you guys think about my criteria and my analysis of the existing build systems? I'm not looking to start any flame wars or anything but I really feel there is a large void for a good (and easy to use) cross platform build system.
And my apologies if my writing was poor or even my formatting was poor.
cheers
-Dan
P.S. My html list may be a bit mucked up, I built it sort of hastily and I don't think all of the tags match up correctly.
EDIT: made my introductory statement a little less inflammatory, and improved my grammar, I must be tired.
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."