Cross compiling JVLC for win32

(on Ubuntu 6.10 appliance running under VMWare Player).

Version 0.2 : Updated on 29/07/2007. (Ubuntu 6.10 instead of Ubuntu 6.06)
Version 0.1 : Creation on 05/12/2006.
Author : Philippe MORIN.

Introduction

You can cross compile a version of JVLC using the mingw cross-compiler.

Requirements

1. Install cross compilation environment for your platform (here Ubuntu 6.10 appliance running on VMWare Player for Windows).   
You can follow the howtos at http://developers.videolan.org/vlc/ .
You need to install autoconf, automake, gettext, libtool, mingw32, tofrodos ( for dos2unix tool), subversion and some other packages.
Warning : If you are executing VMPlayer on a FAT32 disk, you may experience some limitations for image disk size is limited to 4Gb size and
Ubuntu 6.10 + VLC environment + JDKs + compiled files are about 4Gb.
2. Get source files from VLC's svn tree, doing a svn check out.
svn checkout svn://svn.videolan.org/vlc/trunk vlc-trunk
3. Install a Java JDK for win32 from Sun site ( or other Java compiler you want to use ).  
We describe the process with Sun's Java JDK. It should work the same way with other flavors of Java compiler.
Compilation of JNI files requires include/jawt.h and include/win32/jawt_md.h files. These files are found in JDK for Windows.
You can download Sun JDK there : http://java.sun.com .
The path where your JDK is installed will be referred as JAVA_WIN32_HOME.
4. Install a Java JDK for Linux on Ubuntu. PLEASE USE THE SAME VERSION AS THE WIN32.
The path where your JDK is installed will be referred as JAVA_UBUNTU_HOME. It is different from JAVA_WIN32_HOME because these are 2 JDKs
for different hosts.
Note: With Cygwin, you can use the same Java tools for compiling JNI files .cc and Java classes because running a java.exe from Cygwin is possible.
With the Ubuntu 6.10 cross compilation, you need to have one JDK for Java classes compilation (running under Ubuntu ) and one JDK for compiling
the JNI .cc files running under win32 (the target). In fact, you just need the include directory of the JDK running on the target (win32).

Optional

It is always a good idea (and no waste of time) to carefully read documentation of the tools you are using.
Here is the ld documentation for version 2.16: http://sourceware.org/binutils/docs-2.16/ld/.

Configuration

To enable java bindings compilation, you must add the option --enable-bindings-java in the configure-vlc file.

Current Java detection looks for a java.exe file and then tries to compile a Test.java file.

When on Ubuntu host, it will looks for a win32 Java compiler  i.e. javac.exe and will
try to compile javac.exe Test.java.

Unfortunately, you can not run java.exe on your Ubuntu environment.

A way to work around the problem is to create a symbolic link between java.exe and your Ubuntu's Java JDK's java file.
> ln -s java.exe $JAVA_UBUNTU_HOME/bin/java
> ln -s javac.exe $JAVA_UBUNTU_HOME/bin/javac

Compilation

The normal way to get things compiled is to type in vlc-trunk directory :
../configure-vlc
make
A good idea is to look if current tree of svn version is compiling well.
Please have a look at buildbot.videolan.org at column I386-Win32Cross-TrunkContrib.
If win32 is not cross compiling, you'll have to choose another revision of the tree that compiles well.

Linker option

We are using jawt library. So we must provide a jawt.lib on command line.
So we link with option :
-L$(JAVA_WIN32_HOME)/lib -ljawt
This will tell the linker to search for a jawt.lib or jawt.dll in $(JAVA_WIN32_HOME)/lib path.

We want to export symbols we use in order to get loaded by Java when System.loadLibrary("jvlc") is called.
-Wl,--kill-at is win32 specific and allows symbol export removing @n at the end of functions' names.

If jvlc.dll is not automaticcaly generated, write something similar in your Makefile and type
> make libjvlc.so

JINCLUDES = -I${JAVA_WIN32_HOME}/include -I${JAVA_WIN32_HOME}/include/win32
LIBJINCLUDES = -L${JAVA_WIN32_HOME}/lib -ljawt
JCH = javah
JAVACXXFLAGS = `top_builddir=../.. ../../vlc-config --cflags pic` -I../../ -I ../../include $(JINCLUDES)
JAVALDFLAGS = -mno-cygwin -L../../src -lvlc `top_builddir=../.. ../../vlc-config --libs builtin vlc pic` -Wl,--kill-at
export JINCLUDES

libjvlc.so: $(OBJECTS)
    $(MAKE) -C src
    $(CXX) -shared $(COBJECTS) $(LIBJINCLUDES) $(LDFLAGS) $(JAVALDFLAGS) -o jvlc.dll

At the end, we have a jvlc.dll file suitable for use with JVLC on win32 system.

Packaging

It is a good ideo to do a
> make package-win32-zip

You can now copy the .zip file to your win32 platform along with jvlc.dll, libvlc.dll, (libvlc-control.dll?).

In order to run examples, you have to set up a JVLC environnment.
It consists in
----------------------------
jvlc.dll
org/videolan/jvlc/*.class
plugins/*.dll ( which were compiled with VLC)
----------------------------
examples/*.java

References

VideoLAN :
http://www.videolan.org
GNU ld manual :
http://sourceware.org/binutils/docs-2.16/ld/

Happy JVLC.

Philippe.