Introduction
As you may remember, I’ve been struggling with a tricky build at my current client. Whilst many of the problems have been around how we’ve used the tools available to us (well, Ant), I realised that Ant itself might just not be up to the job. Once a build becomes non-trivial, you inevitably want to start using it as a program, something Ant itself is not really good at.
“SCons”:http://www.scons.org/ is a build API form python. Being based on a proper programming API the promise of testable build processes, nice syntax (no more ghastly constructs just to do the build equivalent of an @if@) and above all a system more intuitive to the average programmer than Ant is.
When looking to adopt any open source tool it has to prove itself to fairly quickly – in the case of SCons I set it a few challenges and see how it stacked up.
Test 1: Getting my attention
Looking at the docs, SCons claims that building a Java program should be this simple:
Java('classes', 'src')
Which, when placed in a file called @SConstruct@ and run Will the @scons@ command. The source files in directory @src@ get compiled and placed in directory @classes@. So that locks really nice. Taken together with the fact that SCons’ builders (of which @Java@ is but one) handles dependencies, and you can integrate normal python code (the @SConstruct@ file is just a python source file) makes it a very attractive proposition. It is also the build tool used by Doom 3 – so if nothing else it seems able to handle building large C programs.
So now I’m interested – test passed.
Test 2: Doing something trivial in less than five minutes
I fell at the first hurdle. When running this for a simple “Hello World” example, I got the following error:
scons scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... javac -d classes -source path src srcHello.java 'javac' is not recognised as an internal or external command, operable program or batch file. scons: *** [classesHello.class] Error 1 scons: building terminated because of errors.
I ran the command @javac -d classes -source path src srcHello.java@ on the command line and it worked. I send a mail to the mailing list and got a very helpful reply very promptly to tell me that SCons doesn’t look in either the @PATH@ or in @JAVA_HOME@ environment variables for the @javac@ command, which seems frankly bizarre. Anyway, I got a fix (thanks Jean-Baptiste), which involves me creating my own @Environment@ (which in SCons represents the tools available, paths, environment variables and the like) and explicitly telling it where to find @javac@:
import os
env = Environment(ENV = {'PATH' : os.environ['PATH']})
env.Java('classes', 'src')
This worked, but took significantly more than 5 minutes. However the mailing list had already proven itself to be friendly and responsive, which is important when looking at any open source tool. Test failed.
Test 3: Prove that doing something non-trivial is possible in less that 30 minutes
So, the simple task now accomplished, I turned my attention to something a little more complex. I decided to take a medium sized Java project which has little in the way of external dependencies, and attempt to create a build file for it. I chose log4j. Running the same script on the log4j source code however bombed out with the following less than helpful error:
scons: *** [classesorgapachelog4jAppender.class] Error 1 scons: building terminated because of errors.
Again I look at the command line it was trying to run, and realised it was explicitly passing all source files on the command line – which ends up being rather large. When running manually, I get the expected “@The input line is too long@”. Again, the mailing list responded quickly at informed me that this is a known problem (thanks Werner Schiendl) and has been “logged(scons – [ 797472 ] For command lengths > cmd.exe can handle)”:http://sourceforge.net/tracker/index.php?func=detail&aid=797472&group_id=30337&atid=398973 as a bug. So I either have to apply this patch to be able to compile log4j, or I have to heavily edit the @Java@ build in SCons to use a file to contain source files rather than passing them in.
The more worrying aspect is that I would expect any non-trivial Java program to quickly hit the same problem. This leads me to believe that SCons has not been used on non-trivial Java programs – I might get this problem fixed/worked around, but what other problems might I encounter? Test failed.
Conclusion
It may not of passed all of its tests, but the responsive nature of the mailing list, taken together with how horrible Ant can be to use, makes me want to continue looking at it. It clearly works for C & C++ programs, but it’s Java support needs some love. Right now without work I couldn’t suggest its use in a serious Java development project, but it shouldn’t need that much work to get it that level. In the meantime, I’ll continue to play with it, and may even look to improve the Java support. Look for more on SCons soon
4 Responses to “SCons – passes 1 out of three tests – could do better”
Great summary. What a shame that Scons doesn’t handle Java builds well. I’ve had a cursory look at C# support and that doesn’t look to be there yet either.
Thanks to “Simon”:http://www.brunningonline.net/simon/blog/archives/001688.html for spotting this excellent quote which might be of interest to those who’ll say “Ant is good enough” –
“If you decide to go with the same tools and technology as everyone else, you make sure that you won’t fail any worse than they do. However, you also ensure that you won’t succeed any better.”
I was recently enticed into trying scons for my java builds. I ran into the same first problem you described,but managed to stumble into a fix by looking at some extant SConstruct files.
In talking to an scons “guru” he convinved me that the fact that scons does not parse your path is an advantage. In theory this feature makes it easier to port to different environments. Everyone has an example where some tweak of your personal environment leads to something broken, so I actually do buy this argument. The result is a little lengthening of the SCconstruct file, but it still ends up smaller than my equivalent build.xml.
Next problem for me was getting jar to work with a manifest for “Main-Class”. I ended up kludging a Manifest.txt file, so had to learn how to open/write files in python. Basically a couple hours and I had everything “working”.
The first real problem (if you are not offended by kludges) is that scons appears to be broken for anonymous inner classes. And for the first time I can remember recently, google cant find a solution. Uusually you can type in the exact error message or part of it, and google takes you to twenty pages describing how to fix it. The problem appears to be that the naming for anon innner classes is broken, and so scons compiles the source every time, instead of realizing it is up to date.
Occam’s razor suggests maybe I screwed up the source code, but from the command line, or make, or ant, there seems to be no problem. So unless someone from the java community can give scons “some love” (nice!), I will have to look into hacking the javac parser they use. Not a pretty thought.
Cheers,
John
Someone has showered some love! (Greg Ward)
http://www.gerg.ca/hacks/scons/
A couple patches which spawn some complaints applied to 0.97, but do the job. I applied 01, and 02, because I think 03 makes the output uglier.
My hope is the next person who types “scons java inner classes broken” into google can find that page.
Still no support for javadoc in scons, so I had do something a little kludgey. Overall I am happy with the system and am moving to use it everywhere.