Posted by Wolf Paulus on Jan 19, 2009 in Embedded
A few days ago, I wrote here about how the PhoneME JavaVM can be built with and integrated into OpenWrt, the Linux distribution optimized for WiFi routers or any device that connects over Wifi. However, even with a powerful Java runtime environment available on the target hardware platform, we still need to develop and simulate/test on a development workstation, which may very well be a Mac.
Developing for the PhoneME JavaVM becomes much easier and more fun, if you have the same VM available on your development platform; so here is what I did to get the PhoneME VM build for OS X 10.5 (Intel).
Again, we need to get the sources from the SVN server on java.net here: https://phoneme.dev.java.net/svn/phoneme. Don’t get everything, just the trunk (i.e. phoneme/components/cdc/trunk) and tools (i.e. phoneme/components/tools) folder. However, trunk and tools need to end up on the same level (like siblings) on the build machine.
Unfortunately, the currently available trunk only builds on older Macs that is Macs built on the Power-PC architecture. For newer Macs, i.e. Intel based machines, a patch needs to be installed into the just created trunk folder.
Markus Heberling has made this patch available here: http://markus.heberling.net/wp-uploads/2008/04/phoneme-cdc-darwin-x86.zip. The three folders in this patch just need to be added into the source tree in trunk:
- patch cdc/src/darwin-x86 becomes trunk/src/darwin-x86
- patch cdc/src/darwin-x86 becomes trunk/src/darwin-x86
- patch cdc/buld/darwin-x86-mac becomes trunk/build/darwin-x86-mac
All ducks are in a row now to kick-off the PhoneME build. But there is still one final decision to be made, what kind of PhoneME runtime should be built?
The J2ME_CLASSLIB argument provided to Make, defines what class library will eventually be created:
- cdc – (default) will create a limited class library (cdc.jar 884 KBytes) that is meant for testing purposes only.
- foundation – creates the full Foundation Profile class library (foundation.jar 1.475 KBytes).
- personal – creates the full Personal Profile class library (personal.jar 2.047 KBytes).
Just like you would expect, compared to the Personal Profile, Foundation is missing java.applet.* and java.awt.*. And compared to the Foundation Profile, the cdc.jar is missing some of the networking and security related classes.
Running Java applications on a Mac that depend on the Personal Profile, also require The X Window System (available athttp://xquartz.macosforge.org/trac/wiki) and QT3, the Cross-Platform GUI application framework, installed. QT3 is best installed using FINK and Fink Commander. I usually prefer Porticus but even after several attempts could not make Personal Profile depending Java Apps run. Only after installing QT3 using Fink, did they work flawlessly.
cd trunk/build/darwin-x86-mac
make J2ME_CLASSLIB=foundation
With the Java Runtime Environment built, we can now either use and ANT script like this, to build (and deploy) a Java app:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2009 Wolf Paulus - http://wolfpaulus.com
OpenWrt / PhoneME / Java Project build.xml
-->
<project name="fon" default="deploy" basedir=".">
<!-- =================================================================== -->
<!-- Initialization target -->
<!-- =================================================================== -->
<target name="init" description="initialize properties and folder variables">
<tstamp/>
<!-- remote target information -->
<property name="remote.addr" value="192.168.1.1"/>
<property name="remote.uid" value="root"/>
<property name="remote.pw" value="admin"/>
<property name="remote.dir" value="/usr/java"/>
<!-- Project Attributes -->
<property name="build.id" value="1001"/>
<property name="version" value="1.0 (#${build.id})"/>
<property name="year" value="2009"/>
<property name="packages" value="com.carlsbadcubes.*"/>
<!-- Folders -->
<property name="src.dir" location="src"/>
<property name="build.dir" location="build"/>
<property name="build.src" location="build/src"/>
<property name="build.dest" location="build/classes"/>
<property name="build.javadocs" location="build/apidocs"/>
<!-- Replace tokens in source code before compilation -->
<filter token="year" value="${year}"/>
<filter token="version" value="${version}"/>
<filter token="date" value="${TODAY}"/>
<filter token="log" value="true"/>
<filter token="verbose" value="true"/>
<!-- Complier Settings -->
<property name="compile.source" value="1.4"/>
<property name="compile.target" value="1.4"/>
<property name="compile.compiler" value="modern"/>
<property name="compile.debug" value="true"/>
<property name="compile.optimize" value="true"/>
<property name="compile.deprecation" value="true"/>
<property name="JSDK.home" location="/Users/wolf/Work/Embedded/phoneme-advanced/OSX/phoneme-x86"/>
<!-- Compilation class path -->
<path id="compile.classpath">
<pathelement location="${JSDK.home}/btclasses.zip"/>
<pathelement location="${JSDK.home}/lib/foundation.jar"/>
</path>
</target>
<!-- =================================================================== -->
<!-- Clean up -->
<!-- =================================================================== -->
<target name="clean" depends="init" description="Removes build the distribution files">
<delete dir="${build.dir}"/>
</target>
<!-- =================================================================== -->
<!-- Prepares the build directories and souce -->
<!-- =================================================================== -->
<target name="prepare" depends="clean,init" description="Creates build folder(s) and copies sources">
<mkdir dir="${build.dir}"/>
<!-- create directories -->
<mkdir dir="${build.src}"/>
<mkdir dir="${build.dest}"/>
<!-- copy src files -->
<copy todir="${build.src}" filtering="yes">
<fileset dir="${src.dir}" excludes="**/*.png"/>
</copy>
<!-- copy doc images (e.g. uml diagrams)-->
<copy todir="${build.src}" filtering="no">
<fileset dir="${src.dir}" includes="**/*.png"/>
</copy>
</target>
<!-- =================================================================== -->
<!-- Compiles the source directory -->
<!-- =================================================================== -->
<target name="compile" depends="prepare" description="Compiles the source code">
<javac
srcdir="${build.src}"
destdir="${build.dest}"
debug="${compile.debug}"
optimize="${compile.optimize}"
deprecation="${compile.deprecation}"
compiler="${compile.compiler}"
target="${compile.target}"
source="${compile.source}">
<classpath refid="compile.classpath"/>
</javac>
</target>
<!-- =================================================================== -->
<!-- Package Classes into JAR -->
<!-- =================================================================== -->
<target name="package" depends="compile" description="Package Classes into JAR">
<jar destfile="${ant.project.name}.jar">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Implementation-Vendor" value="Carlsbad Cubes."/>
<attribute name="Implementation-Title" value="${ant.project.name}.jar"/>
<attribute name="Implementation-Version" value="${version}"/>
</manifest>
<fileset dir="${build.dest}"/>
</jar>
</target>
<!-- =================================================================== -->
<!-- Deploy to target (opt ant task, http://www.jcraft.com/jsch/) -->
<!-- =================================================================== -->
<taskdef name="scp" classname="org.apache.tools.ant.taskdefs.optional.ssh.Scp"/>
<target name="deploy" depends="package" description="Deploy on to target hardware">
<scp file="${ant.project.name}.jar" todir="${remote.uid}:${remote.pw}@${remote.addr}:${remote.dir}"/>
</target>
</project>
.. or create a new JSDK in an IDE, like IntelliJ IDEA
you may have to rename the trunk/build/darwin-x86-mac/cvm into trunk/build/darwin-x86-mac/java
As of Snow Leopard 10.6.2, I had to add -m32 to these settings in cdc/build/darwin-x86-mac/GNUmakefile:
ASM_ARCH_FLAGS = -m32 -march=i686
CC_ARCH_FLAGS = -m32 -march=i686
LINK_ARCH_FLAGS = -m32



Read More