Greetings, all,
As part of the Version 7.0 release planning, I wanted to try to address a build issue
that has bugged me for a long time.
Consider the situation of someone who wants to develop their own Hackystat module
(hackyFoo) and build a local version of the system with their hackyFoo extension
incorporated. Currently, that process is (a) difficult and (b) undocumented.
Essentially, you have to hack our build.xml file in several places:
- The "checkModuleAvailability" task must be hacked to check for the availability of the
new hackyFoo module.
- A new "doInternal_hackyFoo" task must be written for the new module, indicating its
dependencies on other modules.
- The "doAll" task must be hacked to include the new "doInternal_hackyFoo" task.
Of course, each time we release a new version of Hackystat, with possible changes to the
build.xml, the person who has implemented hackyFoo has to go in and manually edit the new
build.xml to include the hackyFoo changes.
This is totally bogus. The basic problem is that our build.xml file, as currently
written, hard-wires in knowledge about all of the known modules for Hackystat. What we
really need is a build.xml file that "discovers" the set of Hackystat modules at Ant
invocation time. Consider the following idea:
Right now, each module must include its own local.build.xml file, which provides
module-specific tasks to support compilation and installation. This is A Good Thing and
works very well. Let's extend this to say that each module also needs to include a
local.module.definition.xml file, which might look like this:
<hackystat-module>
<name>hackyFoo</name>
<available>on</available>
<dependent-modules>
<module>hackyKernel</module>
<module>hackyStdExt</module>
</dependent-modules>
</hackystat-module>
As you can see, a module definition is simple: it just specifies the module name, whether
it is "available" (this replaces the hackyFoo.available property in
hackystat.properties), and what modules it depends upon (this replaces all of the
information now hard-wired into build.xml).
Now, let's apply the "autoconf" pattern to the problem. A simple way to solve things
would be to say that when someone wants to build Hackystat for the first time with a new
or changed module definition, one must do:
ant config
what that does is search all of the "sibling" directories to hackyBuild, looking for
occurrences of local.module.definition.xml files. When it finds them, it reads in the
data, and uses that information to _generate_ a build.xml file that includes the
checkModuleAvailability, doInternal_<module>, and doAll tasks with all known modules.
At this point one can invoke all of the normal set of commands. Furthermore, each time
one runs a "normal" command, there is first a quick check of the timestamps associated
with all known local.module.definition.xml files, and if their timestamps are later than
the timestamp associated with build.xml, then the invocation fails with a notice that the
developer needs to re-run 'ant config' to get an up to date version of build.xml.
This particular scheme seems quite feasible to me, since it requires no changes to the
current build process other than the creation of a "configuration" step.
Questions for discussion:
- There might be ways to simplify the resulting build.xml file by using recent ant
features like macrodefs and so forth.
- Is there a more radical way to re-invent the build process to accomplish this
same goal?
I'd really like to get this fixed in the near future; I think it will significantly
simplify external involvement in hackystat development.
Let me know what you think.
Cheers,
Philip