Java Support in Mac OS X

For Octave to be compiled with Java support enabled we need to have some requisite JDK installation and header files available in the host system where Octave is built. For cross-mingw compilation, it was fairly difficult. You can refer to the previous posts on this blog related to adding Java support for more information.

For Mac OS X, I installed the latest Oracle Java SE Development Kit from Oracle’s website. You need to accept the Oracle Binary Code License Agreement for Java SE to download the software.
checking for java... /usr/bin/java
checking for javac... /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/javac
checking for jar... /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/jar
checking for Java version... 1.6.0_51
checking for libjvm.dylib... /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries
checking for include file <jni.h>... /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers

This is the platform specific jni_md.h file  used by configure. It comes with the JDK installation for Mac OS X.

The following are extracts of the configure details of Octave:

Java home: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
Java JVM path: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries
Java CPPFLAGS: -I/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/include -I/System/Library/Frameworks/JavaVM.framework/Home/include -I/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Headers -I/System/Library/Frameworks/Jav$
Java libraries: -framework JavaVM


Build Java interface: yes

Reusing MXE Octave to build Octave for Mac OS X

It is interesting to see that MXE Octave has become more capable than the original MXE. It can not only be used to cross-compile Octave, but is now capable of natively compiling Octave (mingw and msvc) as well. Since I have used MXE Octave to complete the first half of the project to cross-compile Octave to Windows, it is wise to re-use the same to natively compile Octave under Mac OS X. The builds, as far as I can say are supported on a range of platforms. This wouldn’t have been possible if I were to build an app bundle.

On the Mac I am using for my work, config.guess returns x86_64-apple-darwin12.2.1. Also the command gcc -dumpmachine returns i686-apple-darwin11. Hence the target I am using to compile Octave is i686-apple-darwin11. Using x86_64-apple-darwin12.2.1 as the target results in many errors like "Undefined symbols for architecture x86_64: "

I am writing some of the things I did to build a very basic version of Octave (lacks support for many libraries) for Mac OS X using my repo mxe-octave-anirudha.

  • Since GCC doesn’t work for native builds yet, so I used the system GCC provided by XCode. The variable USE_SYSTEM_GCC is automatically set to yes if we pass the --enable-native-build option to configure.
  • Till now I have compiled everything using the cross compile configurations making changes wherever required. On my system, the configure was unable to find the Fortran compiler. I had to manually add the path MXE_F77 := /opt/local/bin/gfortran-mp-4.7 in the Makefile as well as add set(CMAKE_Fortran_COMPILER /opt/local/bin/gfortran-mp-4.7) in usr/x86_64-apple-darwin12.2.1/share/cmake/mxe-conf.cmake. This was necessary for packages like BLAS, Lapack, and Octave. I will later commit a patch to detect the Fortran compiler path automatically.
  • The compilation is likely to stop when dbus is built. This is because dbus needs root privileges during build, else it will throw “Permission denied” error. Running sudo make dbus works fine.
  • Since we are building for a 64-bit target, we must use ./Configure darwin64-x86_64-cc instead of ./config to build package openssl.
  • Compiling Qt succeeds but MXE_PKG_CONFIG is unable to extract the QT_LDFLAGS and QT_LIBS. It is perhaps the reason why the build of Octave fails when GUI is enabled. The variable (PKG)_CONFIGURE_ENV must be set correctly for Mac OS X. To get past Qt build I used the MSVC configurations. The command pkg-config --libs-only-L ./usr/x86_64-apple-darwin12.2.1/lib/pkgconfig/QtCore.pc returns nothing, which might be the reason why Octave doesn’t build with GUI.
  • I had to disable Readline support by adding --disable-readline in src/octave.mk. Since my repo uses Octave 3.7.5 I had to add the patch to make ctrl-c abort the actual octave command in linux (bug #37672). In Octave 3.7.6, the patch has been merged, so it must be removed from the src folder.

After the build completed, Octave was configured for “x86_64-apple-darwin12.2.1”. I will be pushing the changesets to my repo soon. Octave can be launched by doing  ./usr/x86_64-apple-darwin12.2.1/bin/octave. It will launch the CLI version of Octave since GUI was disabled during build. Here is a screenshot.

octave_mac_osx_1

Octave for Mac OS X

Having passed the mid-term evaluations of GSoC, it is time to start my work on making Octave available for Mac OS X. I have never used a Mac, so I will utilize the coming days in studying about the build system of Mac OS X. Thanks to the Director of our university for giving me access to a Mac Pro at Mobile Computing Lab. I have full physical access to it till 5pm. After that, I am permitted to use the machine through TeamViewer/SSH/Telnet (I haven’t figured it out yet).

At this moment, creating a new Mac OS X App Bundle using Macports seems most practical to me. App bundles are directory hierarchies, with the top-level directory having a name that ends with a .app extension. Using Macports, we can produce binary packages with standalone installers that are pre-compiled. The final app bundle doesn’t require Macports to be installed on the target system. All the dependencies will be a part of the bundle. A dmg disk image of the fiinal package is also desirable. The .app bundle can also be run directly like any normal app without any installation. This is just like executing the file bin/octave.exe in Windows version of Octave, where all the dependencies are pre-built.

There is a real app bundle already existing for Octave 3.2 by Thomas Treichl. I am not sure if working on this will be a good idea. It is very old and I have known that the scripts in it might not work properly for newer versions of Octave, while digging up the mailing list. As of now, using Macports seems a good option to me. It also has some great documentation to help me get started. I also know that Ben Abbott had used this approach to produce working app bundles for Octave. I will discuss about the project with the Octave community and write another blog article about what I am going to do exactly in this second half of GSoC.

Java Support in Octave

The trick I was using earlier to get Java support in Octave was merely a workaround. My mentor Michael told me that cross-compiling Octave with Java support was not working out of the box. Firstly, including Java support required us to get a local Windows installation of JDK. Only the Windows version of JDK had the file jvm.dll which was checked during configure. Linux version of java (OpenJDK) didn’t have that file. After some discussion, I came to know that jvm.dll is not required to build Octave with Java. Apparently the only files necessary to get Java support was jni.h and the platform dependent jni_md.h.

To remove jvm.dll checking, I used the following patch:

diff --git a/src/octave-2-no-jvm-check.patch b/src/octave-2-no-jvm-check.patch
new file mode 100644
--- /dev/null
+++ b/src/octave-2-no-jvm-check.patch
@@ -0,0 +1,18 @@
+This file is part of MXE.
+See index.html for further information.
+
+Contains patch to remove checking for jvm.dll during integration of Java support in Octave
+
+diff -r bb713af2e1d9 configure.ac
+--- a/configure.ac	Tue Jul 30 00:49:37 2013 -0400
++++ b/configure.ac	Thu Aug 01 02:57:25 2013 +0530
+@@ -2441,9 +2441,6 @@
+     darwin*)
+       jvmlib=libjvm.dylib
+     ;;
+-    mingw* | cygwin*)
+-      jvmlib=jvm.dll
+-    ;;
+     *)
+       jvmlib=libjvm.so
+     ;;

The process of exporting all missing symbols has now been added as a patch. So there is no need to make the change in the original package, get the sha1 checksum and update octave.mk.

Even though jvm.dll checking was removed, the compiler complained about missing jni_md.h file. OpenJDK had the file jni.h, but it was not enough to build Java enabled Octave. So Michael suggested something much better. He said that it should be possible to download the two header files and put them somewhere into the include directory of mxe-octve (like usr/i686-pc-mingw32/include/java/) and then make Octave to use them. I have pushed a changeset in my repo to do this. Now, one will be able to build Octave with Java enabled without having to hack the –with-java-homedir, –with-java-includedir, and –with-java-libdir options. The using of separate JNI headers during build is limited just to cross-compilation. For native builds, Octave would compile just like it did before. See the new src/octave.mk file here.