Ant Based Builds in J2ME Application Development
This article takes a look at the point of using Ant based build tools in J2ME application / game development and what are the various build tools and so on. The article is basically built on the documents mentioned under the reference title.
What’s the difference?
When developing J2SE applications, things are much easier, mostly because of two steps which are required by J2ME which aren’t in J2SE. With J2ME your compiled classes must be preverified before you can upload them to the device. In J2SE verification of class files takes place in the JVM, but because of the memory limitations on the device, the CLDC-VM or KVM (Sun’s implementation) has a stripped down verifier and some of the functions were moved to the compile-phase (off-device). One thing more we have to watch out for is the emulation of the device. In J2SE, the development platform is the device, not so in J2ME. Because of this, we must have a suitable testing step. Due the heavy fragmentation in J2ME devices (differences in screen sizes, heap, implementation of sound etc.) leads that each application / game has to be specifically tuned for devices. This is pretty cumbersome with managing of different code base for each and every device. A solution for this problem is use preprocessing commands like #include, #if defined etc. in a single code base and let the build system make different target source for each devices based on conditional compilation. Hence we need a defined build process
Why do we need a defined build process?
A defined build process is an essential part of any development cycle because it helps close the gap between the development, integration, test, and production environments. A build process alone will speed the migration of software from one environment to another. It also removes many issues related to compilation, classpath, or properties that cost many projects time and money.
Make Tool
In computer programming, make is a utility for automatically building large applications. Files specifying instructions for make are called Makefiles. make is most commonly used in C/C++ projects, but in principle it can be used with almost any compiled language.
The basic tool for building an application from source code is the compiler. make is a separate, higher-level utility which tells the compiler which source code files to process. It tracks which ones have changed since the last time the project was built and it invokes the compiler on only the components that depend on those files. Although in principle one could always just write a simple shell script to recompile everything at every build, in large projects this would consume a prohibitive amount of time. Thus, a makefile can be seen as a kind of advanced shell script which tracks dependencies instead of following a fixed sequence of steps.
Today, programmers increasingly rely on Integrated Development Environments and language-specific compiler features to manage the build process for them instead of manually specifying dependencies in makefiles. However, make remains widely used, especially in Unix-based platforms.
Makefile structure
A makefile consists of lines of text which define a file (or set of files) or a rule name as depending on a set of files. Output files are marked as depending on their source files, for example, and source files are marked as depending on files which they include internally. After each dependency is listed, a series of lines of tab-indented text may follow which define how to transform the input into the output, if the former has been modified more recently than the latter. In the case where such definitions are present, they are referred to as "build scripts" and are passed to the shell to generate the target file. The basic structure is:
# Comments use the pound sign (aka hash)target: dependencies command 1 command 2 . . . command n A makefile also can contain definitions of variables and inclusion of other makefiles. Variables in makefiles may be overridden in the command line arguments passed to the make utility. This allows users to specify different behaviour for the build scripts and how to invoke programs, among other things. For example, the variable "CC" is frequently used in makefiles to refer to a C compiler, and the user may wish to provide an alternate compiler to use.
Example makefile
Below is a very simple makefile that would compile a source called "helloworld.c" using cc, a C compiler. The PHONY tag is a technicality that tells make that a particular target name does not produce an actual file. The $@ and $<>
helloworld: helloworld.o cc -o $@ $< helloworld.o: helloworld.c cc -c -o $@ $< .PHONY: cleanclean: rm -f helloworld helloworld.o Issues with the Make Tool
The make tool is been in the existence for more than 20 years, though it is still used widely it has it long list of limitations.
- Make tool based builds are not portable as they rely on the underneath shell and the features of the file system.
- Issues like one-letter names for macros, one namespace for file and command targets make Make tool one of the most complex of the build systems.
- Limited Syntax
- Difficult Debugging
The Make Alternatives
A lot of make alternatives are currently available which include Opus Make, GNU Make, Nmake and there are evolutions like JAM, COOK which move away from the syntax of the existing Makefile system. There are also alternative build tools like GNU Build System. However one of the most notable and interesting script based make alternative is the ANT
Defining Build Process with ANT
Ant is a platform-independent scripting tool that lets you construct your build scripts in much the same fashion as the "make" tool in C or C++. You can use a large number of built-in tasks in Ant without any customization. Some of the most important tasks are shown in the following table but explained in more detail in the example that follows.
Here are some useful commands that are built in the Ant distribution.
| Command | Description |
| Ant | Used to execute another ant process from within the current one. |
| Copydir | Used to copy an entire directory. |
| Copyfile | Used to copy a single file. |
| Cvs | Handles packages/modules retrieved from a CVS repository. |
| Delete | Deletes either a single file or all files in a specified directory and its sub-directories. |
| Deltree | Deletes a directory with all its files and subdirectories. |
| Exec | Executes a system command. When the os attribute is specified, then the command is only executed when Ant is run on one of the specified operating systems. |
| Get | Gets a file from an URL. |
| Jar | Jars a set of files. |
| Java | Executes a Java class within the running (Ant) VM or forks another VM if specified. |
| Javac | Compiles a source tree within the running (Ant) VM. |
| Javadoc/Javadoc2 | Generates code documentation using the javadoc tool. |
| Mkdir | Makes a directory. |
| Property | Sets a property (by name and value), or set of properties (from file or resource) in the project. |
| Rmic | Runs the rmic compiler for a certain class. |
| Tstamp | Sets the DSTAMP, TSTAMP, and TODAY properties in the current project. |
| Style | Processes a set of documents via XSLT. |
While other tools are available for doing software builds, Ant is easy to use and can be mastered within minutes. In addition, Ant lets you create expanded functionality by extending some of its classes.
Simple build process with Ant (simple.xml)
The first line contains information about the overall project that is to be built.
The most important elements of the project line are the default and the basedir.
The default attribute references the default target that is to be executed. Because Ant is a command-line build tool, it is possible to execute only a subset of the target steps in the Ant file.
% ant -buildfile simple.xml init That will execute the ant command and run through the simple.xml file until the init target is reached. So, in this example, the default is deploy. The Ant process invoked in the following line will run through the simple.xml file until the deploy command is reached:
% ant -buildfile simple.xml The basedir attribute is fairly self-explanatory as it is the base directory from which the relative references contained in the build file are retrieved. Each project can have only one basedir attribute so you can choose to either include the fully qualified directory location or break the large project file into smaller project files with different basedir attributes.
The next line of interest is the target line. Two different versions are shown here:
The target element contains four attributes: name, if, unless, and depends. Ant requires the name attribute, but the other three attributes are optional.
Using depends, you can stack the Ant tasks so that a dependent task is not initiated until the task that it depends on is completed. In the above example, the clean task will not start until the init task has completed. The depends attribute may also contain a list of comma-separated values indicating several tasks that the task in discussion depends on.
The if and unless commands let you specify commands that are to be performed either if a certain property is set or unless that property is set. The if will execute when the property value is set, and the unless will execute if the value is not set. You can use the available command to set those properties as shown in a following example, or you can set them via the command line.
The init target from the simple example contains four lines of property commands as shown here:
These property lines let you specify commonly used directories or files. A property is a simple name value pair that allows you to refer to the directory or file as a logical entity rather than a physical one.
If you wanted to reference the sourceDir variable later in the Ant file, you could simply use the following syntax to alert Ant to obtain the value for this tag: ${sourceDir}.
Two other commands present in the above buildfile are:
These commands are used to ensure that there are no extraneous files in the outputDir (or classes directory when dereferenced as mentioned above). The first command removes the entire tree contained under the outputDir. The second command creates the directory again.
The last line of major interest to the developer is the following compilation line:
The javac command requires a source directory (the input location of the .java files) and a destination directory (the output location of the .classes file). It is important to note that all directories must either exist prior to the running of the ant command or be created using the mkdir command. Ant does not create directories based upon intuition, so you must create the outputDir, using the mkdir command prior to the compilation step above.
After the compile task has completed, the deploy task will perform the copy operation to move all JSP files from the source directory to a deployment directory.
Ant for J2ME
Ant can be easily used for building J2ME application. To start with we need to define a directory structure. One of the most commonly used directory structure for J2ME application is listed here. Presented here is a sample build.xml file for this structure. However one need to modify the it for their own specific use.
|
| Directory Contents | Manually Created |
| /bin | Where you would place the JAD and MANIFEST file | Yes |
| /src | Where you would place the source files, its not necessary to include the structure of the java packages, but you can if you like. The package structure should be automatically taken care of as long as the java source files properly define the package names | Yes |
| /res | Where you place resources such as graphics, maps, text files… etc. You will need to explicitly create the path to correctly represent the package layout defined in the java source files. | Yes |
| /build | Where you place resources such as graphics, maps, text files… etc. You will need to explicitly create the path to correctly represent the package layout defined in the java source files. | No |
| /obf | Where compile and preverify takes place | No |
| /deploy | The final result you would deploy to production | No |
| | | |
jarfile="${build}/bin/${program_name}.jar"
manifest="bin/MANIFEST.MF">
jarfile="${build}/bin/${program_name}.jar"
manifest="bin/MANIFEST.MF">
Reference
1. ANT MIDP Build Process (focus on Siemens C55)
(c) by Marc Logemann (Loge)
2. J2ME - Using Ant With J2ME
By Jason Lam
Expert Author
Article Date: 2003-06-11
3. Adrian Neagu, in Editorials -
http://freshmeat.net/articles/view/1702/
No comments:
Post a Comment