I’ve been working to create my own software for a while called myToolbox. It was origianlly created using PHP, Javascript, and MySQL, however, I’ve now decided to move to using Java. Doing so has been both enlightening and frustrating as moving towards a new programming language is not always easy. Especially, when one is moving to a language that is as strict as Java. That said, I’ve gotten past my initial Java woes and began do some coding. The challenge now face is find the tools to create an eco system that is both intuitive and friendly towards Java development. One of the tools I have been looking at is Scons. This is a software build tool written in Python. There are a bunch of other tools specific for Java and various other programming language. I decided to go with Scons because it’s being used in Blender, which I’ve toyed with in the past, and it supports many languages including custom ones. That’s awesome if I ever start doing coding in something else besides Java. So in the brief time that I’ve used it, it’s turned out to be pretty good. About the only issue I had with it was forcing Scons to build and analyse the code in a certain order.
Essentially, Sons attempts to read the python build commands, analyse it and source code dependencies, and then build your project. This was a problem for me because I was wanting Scons to run a Java program after it had completed compiling my source code. This was done with the following Scons command:
action = env.Action('java -jarĀ dist/mypackage.jar')
env.Execute(action)
The problem with doing that is that Scons would execute the line of codeĀ and run the program before it compiled and built the source code to classes. This means that the Java program I was running would run a previous version of the classes that I needed to compile. Again, this is due to the fact that Scons works by first reading and analysing the python build scripts and source code before building.
Now I did searching on several forums on how to circumvent this behaviour by building or injecting custom builders, however, it still was not what I wanted. In the end I came up with a simple solution. I decide to place my build code into a file called defaultBuild.py and then I placed the instructions to run Java in a separate file called Sconstruct, which is the default file Scons looks for when running the ‘scons’ command in the command line. It looks something like this:
File: Sconstruct
# Import the needed Python modules
import os
print '-----------------------------------------'
print 'Building my project...'
print ''
env = Environment()
# This is the command that invokes the python script that has instructions on how
# to build the project
action = env.Action('scons -f defaultBuild.py')
env.Execute(action)
print ''
print 'Done building my project.'
print '-----------------------------------------'
print ''
# Now we run the Java program and the newly compiled class
action = env.Action('java -jar dist/mypackage.jar')
env.Execute(action)
File: defaultBuild.py
# Create the build environment. env = Environment() # Compile the java source files env.Java (target = '/bin', source = '/src') # Package the java class files into a jar file env.Jar(target = '/dist/mypackage.jar', source = '/bin')
What the Sconstruct file does is tell Scons that in the command line run the scons command again but call the defaultBuild.py instead of the default Sconstruct. Scons of course obeys, which cause another instance of Scons to run which builds the needed code and returns with the results. Once it returns the rest of the code in the Sconstruct file is executed which in this case means that the Java Virtual Machine is launched and told to run the Jar file mypackage.jar. Not bad. A simple solution.
Now this is just one way this technique could be used. I figure if one had a bunch of things they needed Scons to do, like cleaning up files, running test suites, or compressing directories to zip files, then this is one way to do it. Break the building process into seperate files and then run each file according to the order the developer needs. Of course being new to Scons I do not know if this has any serious repercussions. So I recommend using this for very simple and basic type of flow control. Hope this technique is useful to others. C ya.
import os
print ‘—————————————–’
print ‘Building myToolbox…’
print ”
env = Environment()
action = env.Action(‘scons -f defaultBuild.py’)
env.Execute(action)
print ”
print ‘Done building myToolbox.’
print ‘—————————————–’
print ”
# Run the program
package = os.path.join(os.curdir, ‘dist’)
package = os.path.join(package, ‘myToolbox.jar’)
action = env.Action(‘java -jar ‘ + package)