Fubsy is a tool for efficiently building software. Roughly speaking, Fubsy lets you (re)build target files from source files with minimal effort based on which source files have changed. More generically, Fubsy is an engine for the conditional execution of actions based on the dependencies between a collection of related resources.
Let’s unpack that generic description and see how it relates to a concrete example. Typically, resources are files: source code that you maintain plus output files created by compilers, linkers, packagers, etc. For example, consider a simple C project that consists of four source files:
mytool.c util.c util.h README.txt
Initially, your goal is simply to build the executable mytool by compiling mytool.c and util.c, and then linking the two object files together. More importantly, you want to perform the minimum necessary work whenever source files change: if you modify mytool.c, then recompile mytool.o and relink the executable. But if you modify util.h, you may need to recompile both util.o and main.o before relinking. This is exactly the sort of problem that Fubsy is designed for.
(At this point, outraged Windows programmers might point out that they build mytool.obj and mytool.exe This platform variation is a quirk of C/C++ that Fubsy’s C/C++ plugins handle, but which core Fubsy knows nothing about.)
Currently, this document is more of a specification than a description of actual software. Many of the features described here have barely even been thought through, never mind implemented and tested. Mentally add a “not implemented yet” footnote to every sentence in this guide, and you won’t be too far off from the truth. I’ve tried to help by adding explicit “this actually works” and “not implemented yet” notes here and there, but don’t be surprised if Fubsy doesn’t behave quite as the document promises.
Furthermore, it’s quite likely that the final product will differ considerably from the description in this document; that’s just the nature of software. Consider this an invitation to join in the development of Fubsy and influence how it will turn out.
Of course, Fubsy is hardly the first piece of software that attempts to tackle this problem. Most C programmers are familiar with Make, which does a reasonable job for small-to-medium C/C++ projects on Unix-like systems. However, Make has awkward syntax, confusing semantics, is hard to extend, and is largely limited to Unix. These limitations have led many people over the years to paper over its difficulties by writing programs that generate Makefiles, without actually tackling the real problems with Make.
Similarly, most Java programmers are familiar with Ant, which attempts to solve the problem in a radically different way. Ant doesn’t provide much in the way of dependency management (which is surprisingly difficult for Java) , but it is extensible in a real programming language (Java). As a result, it works the same across platforms, which is more than Make can say. Unfortunately, Ant takes “awkward syntax” to a whole new level by using XML rather than a custom language. And it’s useless for programmers outside the Java ecosystem.
Some C/C++ programmers are familiar with SCons, which brought a new level of rigour, consistency, and extensibility to build tools. SCons puts the graph of dependencies front and centre. It requires developers to get their dependencies right, guaranteeing a correct build in exchange for the effort. Additionally, SCons ships with excellent support for C and C++ which makes many build scripts trivial. Unfortunately, SCons suffers from poor performance, and its dependency engine is incapable of handling weird languages like Java where target filenames are not easily predicted from source filenames.
|||Terminology note: most Java programmers understand “dependency” in the sense of “my application depends on commons-lang.jar”, so “dependency management” in the Java world typically means “figure out a way to get commons-lang.jar into the build environment”. C/C++ programmers, however, usually speak of dependencies at the file level: “foo.c includes util.h, so foo.o depends on util.h”. That is, if util.h changes, we need to rebuild foo.o. In Fubsy, “dependency” takes the C/C++ programmer’s meaning: for example, MyApp.class depends on MyApp.java as well as commons-lang.jar.|