Tips on porting Java to other architectures

sossego

Retired from the forums
Paraphrasing Greg Lewis and others, "In order to build Java, you must have Java already installed."
  1. Install the latest version of Java to a i386/AMD64 machine.
  2. If not already enabled, turn on NFS client and server.
  3. Enable NFS on the other machine - PPC(64), MIPS(64), et al.
  4. Export the Java environment to the other machine.
  5. Download the Java source. For reference you can use 7 to build 6 and 7.
  6. Build every dependency onto the guest/non-standard machine.
Once the entire environment has been built on the guest/non-standard, you should be able to do a native build.

Thanks to the FreeBSD Java mailing list for this.
 
After each step, be sure to run /usr/libexec/locate.updatedb .

Make sure that the version of NFS you are using is the same across all of your machines' architecture. NFS exporting from Linux based systems to FreeBSD will not work. This is due to the fact that Linux is still at version 2.x.
 
I have a hypothesis that using the bootstrap method of architecture to architecure may work better; so,
  1. Enable NFS v2 on a machine with FreeBSD and a machine with Linux.
  2. Follow the previous posts suggestions.
I am back down to a single device and hope that I will get another soon.
 
sossego said:
NFS exporting from Linux based systems to FreeBSD will not work. This is due to the fact that Linux is still at version 2.x.
I think this depends on the distribution. Debian (and as a consequence Ubuntu) and RHEL (including CentOS, Fedora, Scientific Linux and all) support NFSv4 server and client.
 
As I've made some progress on this, I will post my setup:
You need:
- an AMD64/i386 machine running FreeBSD with java/openjdk7 and
java/bootstrap-openjdk, with the following IP address: 192.168.2.1
- an ARM machine (or a qemu-bsd-user ARM jail) with GCC from base, ie the world needs to be compiled with these flags: make TARGET_ARCH=armv6 WITHOUT_CLANG=yes WITHOUT_CLANG_IS_CC=yes WITH_GCC=yes WITH_GNUCXX=yes buildworld

You need to share the same java source between your AMD64 and ARM machine
The share will be /data/openjdk7
On your AMD64 machine:
Code:
cd /usr/ports/java/openjdk7 ; make patch
rsync /usr/ports/java/openjdk7/work/ /data/openjdk7

On your ARM machine:
Code:
mount -t nfs 192.168.2.1:/data/openjdk7 /data/openjdk7/
mount -t nfs 192.168.2.1:/usr/ports /usr/ports
mount -t nfs 192.168.2.1:/usr/ports/distfiles /usr/ports/distfiles
or, if you're using a bsd-qemu-user jail (do this from your AMD64 machine, /data/11armv6 is my ARM jail):
Code:
mount_nullfs /data/openjdk7 /data/11armv6/data/openjdk7/
mount_nullfs /usr/ports /data/11armv6/usr/ports
mount_nullfs /usr/ports/distfiles /data/11armv6/usr/ports/distfiles

On your ARM, you need some environment variables:
Code:
setenv LANG C

setenv JAVA_BOOTHOST 192.168.2.1
setenv JAVA_BOOTDIR /usr/local/openjdk7
setenv ALT_BOOTDIR /data/boot-java

setenv ANT_HOME /data/openjdk7/apache-ant-1.9.4
setenv ALT_FREETYPE_HEADERS_PATH /usr/local/include
setenv ALT_FREETYPE_LIB_PATH /usr/local/lib
setenv ALT_CUPS_HEADERS_PATH /usr/local/include
setenv NO_DOCS true
setenv ZERO_BUILD true
setenv BUILD_CORBA false
setenv BUILD_JAXP false
setenv BUILD_JAXWS false

setenv LIB_ARCH arm
setenv ZERO_LIBARCH arm
setenv ZERO_ARCHDEF ARM
setenv ZERO_ENDIANNESS little
setenv JVM_VARIANT_ZERO true

setenv LIBFFI_CFLAGS "-I/usr/local/lib/libffi-3.0.13/include "
setenv LIBFFI_LIBS "-lffi "

On your ARM machine, you need the boot-java shell scripts, grab the boot-java.tar.gz attachment from this email: http://docs.freebsd.org/cgi/mid.cgi?200 ... 4033544.he and decode / uncompress it using b64decode / tar:
b64decode -r boot-java.tar.gz.b64 | tar xf - -C /data

Next, fix the location of sh-lib.sh inside /data/boot-java/javah

On your AMD64 machine, you need some java binaries that will be used to boostrap the ARM build (yes, boot-java is distinct between your ARM and AMD64 machine):
Code:
mkdir -p /data/boot-java/bin
ln -s /usr/local/bootstrap-openjdk/bin/jar /data/boot-java/bin/jar
ln -s /usr/local/bootstrap-openjdk/bin/java /data/boot-java/bin/java
ln -s /usr/local/bootstrap-openjdk/bin/javac /data/boot-java/bin/javac
ln -s /usr/local/bootstrap-openjdk/bin/javah /data/boot-java/bin/javah
ln -s /usr/local/bootstrap-openjdk/bin/javap /data/boot-java/bin/javap

You need the following patch otherwise the architecture is not correctly detected and you will have errors because the jlong typedef is wrong (LP64 thingies)
Code:
--- /data/openjdk7/openjdk/jdk/make/common/shared/Platform.gmk.orig       2014-08-26 18:39:02.220931884 +0200
+++ /data/openjdk7/openjdk/jdk/make/common/shared/Platform.gmk 2014-08-26 19:12:33.465794227 +0200
@@ -348,7 +348,7 @@
   ARCH_FAMILY := $(ARCH)

   # i586, sparc, and ppc are 32 bit, amd64 and sparc64 are 64
-  ifneq (,$(findstring $(ARCH), i586 sparc ppc))
+  ifneq (,$(findstring $(ARCH), i586 sparc ppc arm))
     ARCH_DATA_MODEL=32
   else
     ARCH_DATA_MODEL=64

You should be good to go, on your ARM machine do the following:
cd /data/openjdk7/openjdk ; gmake
The boostrap will use ssh a lot, so I recommand you to generate an ssh key and put it your AMD64 root account (and make sure sshd is configured to accept root login). Next you can do a eval `ssh-agent` ; ssh-add (sadly this won't work with qemu-bsd-user)
 
Could and would you share this on the FreeBSD JAVA mailing lists for the others?
 
Back
Top