[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.