Build OpenJDK6 with a pre-built OpenJDK/IcedTea

(This was written for OpenJDK b12)

OpenSolaris

32-bit (i586)

As OpenJDK6 still needs some Motif headers (dependency is removed for OpenJDK7), download Lesstif, configure it and build the headers:

$ tar -xjf lesstif-0.95.0.tar.bz2
$ cd lesstif-0.95.0
$ ./configure
$ make -C include/Motif-2.1/

This should create you the missing Xm.h. You also need some symlinks to give the OpenJDK build system what it wants:

$ cd include
$ ln -s Motif-2.1 include
$ cd ..
$ ln -s include motif21

The OpenJDK build system needs a number of environment variables:

export ALT_BINARY_PLUGS_PATH=$HOME/projects/openjdk/binary-plugs
export ALT_BOOTDIR=$HOME/projects/openjdk/icedtea6-bootstrap/build-hotspot/openjdk/control/build/solaris-i586/j2sdk-image
export ALT_COMPILER_PATH=/opt/SunStudioExpress/bin
export ALT_CUPS_HEADERS_PATH=/usr/include
export ALT_MOTIF_DIR=$HOME/projects/openjdk/lesstif/lesstif-0.95.0
export ANT_HOME=/usr
export ENFORCE_C_COMPILER_REV=5.10
export ENFORCE_COMPILER_REV=5.9
export HOTSPOT_BUILD_JOBS=2
export IMPORT_BINARY_PLUGS=false
export LANG=C
export NO_DOCS=true

To trick the build system, I created a fake binary-plugs directory structure:

$ mkdir -p $HOME/projects/openjdk/binary-plugs/jre/lib/i386
$ cd $HOME/projects/openjdk/binary-plugs
$ touch jre/lib/rt-closed.jar jre/lib/i386/libjsoundhs.so

To build OpenJDK should be as simple as:

$ cd control/make
$ make

The resulting image should be here:

$ control/build/solaris-i586/j2sdk-image/bin/java -version
openjdk version "1.6.0-internal"
OpenJDK Runtime Environment (build 1.6.0-internal-twisti_19_oct_2008_17_12-b00)
OpenJDK Server VM (build 10.0-b19, mixed mode)

64-bit (amd64)

To build the 64-bit OpenJDK bits, simply type:

$ cd control/make
$ make ARCH=amd64 ARCH_DATA_MODEL=64

Since some of the libraries being built link against libjvm.so, we need a 64-bit version of that library. As I couldn't remember from the top of my head how to make an empty shared library (and I'm not sure it would work), I used a 64-bit version from JamVM and linked it into the boot Java:

$ cd $HOME/projects/openjdk/icedtea6-bootstrap/build-hotspot/openjdk/control/build/solaris-i586/j2sdk-image/jre/lib
$ mkdir -p amd64/server
$ cd amd64/server
$ ln -s $HOME/install/jamvm-m64/lib/libjvm.so .

The resulting image should be here:

$ control/build/solaris-amd64/j2sdk-image/bin/java -version
-bash: control/build/solaris-amd64/j2sdk-image/bin/java: No such file or directory

Hmm, something is wrong. Looking closer reveals there is an amd64 directory:

$ ls control/build/solaris-amd64/j2sdk-image/bin/
amd64/
$ control/build/solaris-amd64/j2sdk-image/bin/amd64/java -version
Error occurred during initialization of VM
java/lang/NoClassDefFoundError: java/lang/Object

A little better, but not much. Looking closer again, but this time at the big picture, shows that the image created only contains the 64-bit libraries. This looks like a 64-bit add-on. Let's copy the stuff together:

$ cp -a control/build/solaris-i586/j2sdk-image .
$ cp -a control/build/solaris-amd64/j2sdk-image .
cp: overwrite `./j2sdk-image/jre/LICENSE', overriding mode 0444? n
cp: overwrite `./j2sdk-image/jre/ASSEMBLY_EXCEPTION', overriding mode 0444? n
cp: overwrite `./j2sdk-image/ASSEMBLY_EXCEPTION', overriding mode 0444? n
cp: overwrite `./j2sdk-image/LICENSE', overriding mode 0444? n
$ j2sdk-image/bin/amd64/java -version
openjdk version "1.6.0-internal"
OpenJDK Runtime Environment (build 1.6.0-internal-twisti_19_oct_2008_17_12-b00)
OpenJDK 64-Bit Server VM (build 10.0-b19, mixed mode)

Here we are!


How to use OpenJDK's j2se as CACAO's Java core library (desperately outdated)

These instructions are for OpenJDK b19.

In this text some variables are used instead of path names to make it easier to read. These are:

First of all a CACAO installation which was built for OpenJDK is required.

$ ./configure \
--prefix=$CACAOOPENJDK \
--with-java-runtime-library=openjdk \
--with-java-runtime-library-prefix=$OPENJDK/control/build/linux-$ARCH/ \
--enable-jre-layout
$ make
$ make install

There is a small bootstrap problem because we don't have the OpenJDK classes built already. We can solve this by using the IcedTea classes for generating the CACAO headers. First, get yourself IcedTea and build the fake plugs JDK:

$ cd $ICEDTEA
$ ./configure
$ make plugs

Then we can build the CACAO headers:

$ make -C src/native/include CLASSPATH=$ICEDTEA/lib/rt/rt.jar

This patch is required to build OpenJDK on PowerPC (but I don't know why it's required):

Index: j2se/make/common/Defs-linux.gmk
===================================================================
--- j2se/make/common/Defs-linux.gmk     (revision 248)
+++ j2se/make/common/Defs-linux.gmk     (working copy)
@@ -215,7 +215,7 @@ endif
 
 EXTRA_LIBS += -lc
 
-LDFLAGS_DEFS_OPTION  = -z defs
+LDFLAGS_DEFS_OPTION  = -Xlinker -z -Xlinker defs
 LDFLAGS_COMMON  += $(LDFLAGS_DEFS_OPTION)
 
 #
Index: j2se/make/common/Program.gmk
===================================================================
--- j2se/make/common/Program.gmk        (revision 248)
+++ j2se/make/common/Program.gmk        (working copy)
@@ -85,7 +85,7 @@ ifneq (,$(findstring $(PLATFORM), linux 
        endif
     endif
     ifeq ($(PLATFORM), linux)
-       LDFLAGS += -z origin
+       LDFLAGS += -Xlinker -z -Xlinker origin
        LDFLAGS += -Wl,--allow-shlib-undefined
        LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)/jli
        LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../jre/lib/$(LIBARCH)/jli
Index: j2se/make/java/instrument/Makefile
===================================================================
--- j2se/make/java/instrument/Makefile  (revision 248)
+++ j2se/make/java/instrument/Makefile  (working copy)
@@ -109,7 +109,7 @@ else
     LDFLAGS += -R \$$ORIGIN/jli
   endif
   ifeq ($(PLATFORM), linux)
-    LDFLAGS += -z origin
+    LDFLAGS += -Xlinker -z -Xlinker origin
     LDFLAGS += -Wl,--allow-shlib-undefined
     LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/jli
   endif

For non-HotSpot architectures you need to set the correct ARCH_DATA_MODEL and the required compiler version in the build system:

Index: j2se/make/common/shared/Platform.gmk
===================================================================
--- j2se/make/common/shared/Platform.gmk        (revision 248)
+++ j2se/make/common/shared/Platform.gmk        (working copy)
@@ -225,13 +225,19 @@ ifeq ($(SYSTEM_UNAME), Linux)
       ARCH=sparcv9
     endif
   else
-    # i586 is 32-bit, amd64 is 64-bit
     ifndef ARCH_DATA_MODEL
       ifeq ($(ARCH), i586)
+        # i586 is 32-bit
         ARCH_DATA_MODEL=32
-      else
+      endif
+      ifeq ($(ARCH), amd64)
+        # amd64 is 64-bit
         ARCH_DATA_MODEL=64
       endif
+      ifeq ($(ARCH), ppc)
+        # ppc is 32-bit
+        ARCH_DATA_MODEL=32
+      endif
     endif
   endif

Index: j2se/make/common/shared/Compiler-gcc.gmk
===================================================================
--- j2se/make/common/shared/Compiler-gcc.gmk    (revision 246)
+++ j2se/make/common/shared/Compiler-gcc.gmk    (working copy)
@@ -91,6 +91,11 @@ ifeq ($(PLATFORM), linux)
     REQUIRED_CC_VER = 3.2
     REQUIRED_GCC_VER = 2.9[56789].*
   endif
+  ifeq ($(ARCH), ppc)
+    # ppc
+    REQUIRED_CC_VER = 3.2
+    REQUIRED_GCC_VER = 3.2
+  endif
   endif
   endif
   # Option used to create a shared library

Because GNU Classpath does not support parsing float/double values as hexadecimal values, we need this patch:

Index: j2se/src/share/classes/java/lang/Float.java
===================================================================
--- j2se/src/share/classes/java/lang/Float.java (revision 242)
+++ j2se/src/share/classes/java/lang/Float.java (working copy)
@@ -77,7 +77,8 @@ public final class Float extends Number 
      * {@code 0x1.fffffeP+127f} and also equal to
      * {@code Float.intBitsToFloat(0x7f7fffff)}.
      */
-    public static final float MAX_VALUE = 0x1.fffffeP+127f; // 3.4028235e+38f
+    //public static final float MAX_VALUE = 0x1.fffffeP+127f; // 3.4028235e+38f
+    public static final float MAX_VALUE = 3.4028235e+38f;
 
     /**
      * A constant holding the smallest positive normal value of type
@@ -87,7 +88,8 @@ public final class Float extends Number 
      *
      * @since 1.6
      */
-    public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f
+    //public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f
+    public static final float MIN_NORMAL = 1.17549435E-38f;
  
     /**
      * A constant holding the smallest positive nonzero value of type
@@ -95,7 +97,8 @@ public final class Float extends Number 
      * hexadecimal floating-point literal {@code 0x0.000002P-126f}
      * and also equal to {@code Float.intBitsToFloat(0x1)}.
      */
-    public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f
+    //public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f
+    public static final float MIN_VALUE = 1.4e-45f;
 
     /**
      * Maximum exponent a finite {@code float} variable may have.  It
Index: j2se/src/share/classes/java/lang/Double.java
===================================================================
--- j2se/src/share/classes/java/lang/Double.java        (revision 242)
+++ j2se/src/share/classes/java/lang/Double.java        (working copy)
@@ -77,7 +77,8 @@ public final class Double extends Number
      * {@code 0x1.fffffffffffffP+1023} and also equal to
      * {@code Double.longBitsToDouble(0x7fefffffffffffffL)}.
      */
-    public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
+    //public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
+    public static final double MAX_VALUE = 1.7976931348623157e+308;
 
     /**
      * A constant holding the smallest positive normal value of type
@@ -87,7 +88,8 @@ public final class Double extends Number
      *
      * @since 1.6
      */
-    public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
+    //public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
+    public static final double MIN_NORMAL = 2.2250738585072014E-308;
  
     /**
      * A constant holding the smallest positive nonzero value of type
@@ -96,7 +98,8 @@ public final class Double extends Number
      * {@code 0x0.0000000000001P-1022} and also equal to
      * {@code Double.longBitsToDouble(0x1L)}.
      */
-    public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324
+    //public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324
+    public static final double MIN_VALUE = 4.9e-324;
 
     /**
      * Maximum exponent a finite {@code double} variable may have.

Then you have to add some of the compiled classes to the bootclasspath of CACAO. The easiest way to do this is to create a zip file (e.g. icedtea.zip) and add that zip file to the default endorsed directory of CACAO:

$ cd $ICEDTEA/lib/rt/
$ zip icedtea.zip \
com/sun/jmx/snmp/SnmpSession.class \
sun/awt/FontConfiguration\$2.class \
sun/awt/FontConfiguration\$PropertiesHandler\$FontProperties.class \
sun/awt/FontConfiguration\$PropertiesHandler.class \
sun/awt/FontConfiguration.class \
sun/text/CompactByteArray.class \
sun/util/calendar/AbstractCalendar.class \
sun/util/calendar/BaseCalendar\$Date.class \
sun/util/calendar/BaseCalendar.class \
sun/util/calendar/CalendarDate.class \
sun/util/calendar/CalendarSystem.class \
sun/util/calendar/CalendarUtils.class \
sun/util/calendar/Gregorian\$Date.class \
sun/util/calendar/Gregorian.class \
sun/util/calendar/ZoneInfoFile.class
$ mkdir -p $CACAO/jre/lib/endorsed/
$ ln -s $ICEDTEA/lib/rt/icedtea.zip $CACAO/jre/lib/endorsed/

When using an opensource javac from Sun, you need some kind of wrapper because a plain javac does not understand the -J options. I used this small script:

ARGS=""

for ARG in "$@"; do
    OUT=`echo "$ARG" | grep "^-J"`
    if [ "$OUT" = "" ]; then
        ARGS="$ARGS $ARG"
    fi
done

cacao -Xmx512m -jar $HOME/cacao/javac/javac.jar $ARGS

To build the j2se libraries used this command:

$ make \
ALT_BOOTDIR=$CACAO \
ALT_HOTSPOT_IMPORT_PATH=$CACAOOPENJDK \
ALT_BINARY_PLUGS_PATH=$ICEDTEA/bootstrap/jdk1.7.0 \
ALT_JDK_IMPORT_PATH=$CACAOOPENJDK \
EXTERNAL_ZLIB=true \
j2se_fastdebug_only

When building a non amd64, i586, ia64, sparc or sparcv9 architecture, you need to create a new architecture directory in the OpenJDK repository and copy jvm.cfg from one of the other architectures into the new directory (I picked sparcv9):

$ cd $OPENJDK
$ mkdir j2se/src/solaris/bin/$ARCH
$ cp j2se/src/solaris/bin/sparcv9/jvm.cfg j2se/src/solaris/bin/$ARCH/

To get the OpenJDK wrappers working with Boehm-GC, you need to apply the following patch:

Index: j2se/src/share/bin/java.c
===================================================================
--- j2se/src/share/bin/java.c   (revision 244)
+++ j2se/src/share/bin/java.c   (working copy)
@@ -367,7 +367,8 @@ main(int argc, char ** argv)
       args.classname = classname;
       args.ifn = ifn;
 
-      return ContinueInNewThread(JavaMain, threadStackSize, (void*)&args, ret);
+/*       return ContinueInNewThread(JavaMain, threadStackSize, (void*)&args, ret); */
+      return JavaMain((void*)&args);
     }
 }

Notes for s390

cacaowiki: OpenJDK (last edited 2010-08-25 09:34:44 by localhost)