sab39

... indistinguishable from magic
effing the ineffable since 1977
ecj and ikvm

ecj and ikvm

1/6/2005
A goal of mine for a while has been to integrate a Java compiler with ikvm to provide a direct Java-source-to-.NET compiler. I haven't achieved that goal yet, but I have taken a baby-step in that direction and successfully compiled the Eclipse Java compiler, ecj, to run under ikvm. The remaining issues are the big ones: detect classes in .NET dlls so that the Java code can refer to them, and pass the result through the ikvm compiler to get a .NET executable or dll as output. These steps are still some way in the future if I manage them at all.

Just being able to run ecj under IKVM is a significant step, though, so I thought I'd post the instructions here in case anyone wants to try it.
(These instructions haven't been tested in exactly this form; I went down a bunch of dead ends in between the steps and had some of the file locations different. Hopefully I didn't screw up the process of putting the steps into a logical order for these instructions. If I did, sorry.)

1) Make a working folder:
   mkdir ecj
   cd ecj

2) Check out the sources:
   cvs -z3 -d:pserver:anonymous@dev.eclipse.org:/home/eclipse co org.eclipse.jdt.core

3) There are some screwy dependencies from the "compiler" module to the "model" module which in turn pull in a bunch of files from somewhere outside core. We can fix these by putting them in a separate directory and trimming them down to remove the unsatisfiable dependencies. "Util.java" is a trimmed down version of the copy in model\org\eclipse\jdt\internal\core\util with only the methods that Signature.java depends on. On linux obviously replace \ with /, and use mkdir -p to create parent directories in one shot.
   mkdir modelhack\org\eclipse\jdt\core
   mkdir modelhack\org\eclipse\jdt\internal\core\util
   copy org.eclipse.jdt.core\model\org\eclipse\jdt\core\Signature.java modelhack\org\eclipse\jdt\core
   copy [...path\to\]Util.java modelhack\org\eclipse\jdt\internal\core\util

4) Get a list of all the files in the compiler, batch and modelhack folders with a .java extension
5) Make a build folder and copy all the .properties and .rsc files from the compiler, batch and model folders into it.
   On Windows, the easiest way to do steps 4 and 5 together was to use a little perl script:
   cd org.eclipse.jdt.core
   perl [...path\to\]ecjfiles.pl >..\files.lst
   On Linux these steps can be done straight in the shell (UNTESTED!):
   cd org.eclipse.jdt.core
   find ../modelhack -name *.java >../files.lst
   find compiler -name *.java >>../files.lst
   find batch -name *.java >>../files.lst
   mkdir ../build
   (cd compiler; tar c `find . -name *.properties -o -name *.rsc`) | (cd ../build; tar x)
   (cd batch; tar c `find . -name *.properties -o -name *.rsc`) | (cd ../build; tar x)
   (cd model; tar c `find . -name *.properties -o -name *.rsc`) | (cd ../build; tar x)

6) Compile everything (replace jikes with your java compiler of choice):
   jikes -classpath "..\build;..\modelhack;compiler;batch;[...path\to\]rt.jar" -d ..\build @..\files.lst -Xstdout

7) Test it.
   a) Can you get a usage message?
      cd ..
      java -cp build org.eclipse.jdt.internal.compiler.batch.Main
   b) Can you compile a simple Java file using 1.5 features?
      java -cp build org.eclipse.jdt.internal.compiler.batch.Main -verbose -1.5 Test.java
      java -cp . Test

8) Compile it to a .NET exe:
   ikvmc -target:exe -out:ecj.exe -main:org.eclipse.jdt.internal.compiler.batch.Main -recurse:build
   copy [...path\to\]ikvm\bin\*.dll .
   Try for another usage message:
   ecj

9) Get it an rt.jar:
   ikvmstub IKVM.GNU.Classpath.dll
   (ignore the warning if there is one)
   ren IKVM.GNU.Classpath.jar rt.jar

10) Compile a test program:
    ecj -cp rt.jar -verbose -1.5 Test.java
    java -cp . Test

Note that my test program used 1.5 language features but none of the generic aspects of the class library; if it had, the ikvmstub-generated rt.jar wouldn't have been enough and you'd have to point it to Sun's libraries (or a build of the Classpath generics branch if you have one).

Note too that ikvm (as of the snapshot I have) can't run the resulting Test.class because it refuses the 1.5 class format version.