Some tips to help with static linking of GCJ generated programs.
Normally java programs compiled with GCJ are dynamically linked against libgcj.so. While convenient, this makes it necessary to have libgcj.so available at runtime and libgcj.so is quite large.
An alternative is to statically link against libgcj. This causes its own set of problems, but in some cases it is worth the extra hassle to save space.
For versions of GCJ before 4.2
One way to link libgcj statically is to use a link line similar to this (on linux):
Take a look at Foo
public class Foo { public static void main(String args[]) { System.out.println("Hello."); } }
Now lets statically link against libgcj...
gcj -c Foo.java gcj --main=Foo -save-temps Foo.java gcc -o Foo Foo.o Foomain.i -shared-libgcc -Wl,-non_shared -lgcj -Wl,-call_shared -lsupc++ -Wl,--as-needed -lz -lgcc_s -lpthread -lc -lm -ldl -Wl,--no-as-needed
Note that this is quite a bit more complicated than:
gcj -o Foo --main=Foo Foo.java
But the resulting executable does not need libgcj.so. Check it with readelf -d if you are in doubt.
New in GCJ 4.2
Starting in GCJ 4.2 static linking is supported from the gcj command line. The program above can be statically linked like this:
gcj -static-libgcj -o Foo --main=Foo Foo.java
Caution:
Some parts of libgcj use reflection to load needed classes. When doing static linking, the linker will not find that some of these classes are needed and will omit them. If you get a ClassNotFoundException at runtime about some class in libgcj, you can force it to be loaded by adding some dummy code that refers to it. Something like this:
public static void forceLinkingOfLibGcjClasses { object dummy = new fully.qualified.name.of.missing.Class(); . . . }