[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: compiling SableCc natively
Another thing, I've forgot to mention; but that could get you into trouble.
GCJ is a typical GNU tool. In their traditions, they normally build projects
from sources with makefiles, ./configure and things like that. Since, I
wasn't interested in figuring out the rebarbative makefile syntax, I just
carried on with Ant. Now, that works too, but it requires you to do a few
counter-intuitive things.
(1) Java doesn't have header files (and good so :).
Building a source file separately, out of order, doesn't work out of the
box, without first separately resolving dependencies. I resort to building
the .class files first, and use them as classpath for GCJ. However, in
JDK1.4, javac writes its .class exception tables in a different way than
before. That yields GCJ errors, complaining about it. Therefore, I use
jikes; and supply the jikes-created class files as "header files" to GCJ.
<target name="cls-compile" depends="init">
<property name="build.compiler" value="jikes"/>
<javac srcdir="src" destdir="cls" includes="
**/*.java"/>
</target>
And indeed, therefore, it seems necessary to compile twice.
(2) Linking a large number of *.o files
This works up to about 350 *.o files (on win2K). With SableCc it still works
(only just). Larger than that, CreateProcess() on win32 fails, because the
commandline becomes too large. I've found a workaround for this. I link
every namespace into a seperate *.a archive file with the binutil tool "ar".
<apply failonerror="true" executable="ar" parallel="true">
<fileset dir="obj/mynamespace" includes="**/*.o"/>
<arg line="-cr arc/mynamespace.a"/>
</apply>
Then I link the archive files together, along with the resources:
<target name="link">
<apply failonerror="true" executable="gcj" parallel="true">
<fileset dir="arc/" includes="*.a"/>
<arg value="--main=myMainClass"/>
<arg value="res/*.o"/>
<arg value='-s'/>
<arg value='-Os'/>
<arg line="-o exe/myexe"/>
<srcfile/>
</apply>
</target>
GCJ is a bit of a collision between two different worlds: the native GNU
toolchain, and the existing Java practices. I've decided to carry on as much
as possible with the existing Java practices; while focusing on gaining the
(zero-install, ...) advantages of native executables.