<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Depth-First: Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt</title>
    <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Walking the Web of Chemical Informatics</description>
    <item>
      <title>Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt</title>
      <description>&lt;p&gt;&lt;a href="http://openbabel.sf.net/"&gt;&lt;img src="http://depth-first.com/files/Babel256.png" align="right"&gt;&lt;/img&gt;&lt;/a&gt;Wouldn't it be great to be able to compile code written in languages like FORTRAN, C, and C++ to Java bytecode? &lt;a href="http://nestedvm.ibex.org/"&gt;NestedVM&lt;/a&gt; - almost magically - can do just that. This article documents a failed first attempt to compile the popular cheminformatics toolkit &lt;a href="http://openbabel.sf.net"&gt;Open Babel&lt;/a&gt;, which is written in C and C++, to pure Java bytecode with NestedVM.&lt;/p&gt;

&lt;p&gt;A previous article described the &lt;a href="http://depth-first.com/articles/2007/10/31/jinchi-run-inchi-anywhere-java-runs"&gt;successful compilation of the InChI toolkit&lt;/a&gt;, a C library, to a platform-independent executable jarfile.&lt;/p&gt;

&lt;h4&gt;The Problem&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://openbabel.sf.net"&gt;Open Babel&lt;/a&gt; is one of cheminformatics' most &lt;a href="http://sourceforge.net/project/stats/?group_id=40728&amp;amp;ugn=openbabel"&gt;widely-used&lt;/a&gt; open source packages. It interconverts dozens of molecular languages, performs a host of cheminformatics analyses, and serves as a platform for many programs and Web services.&lt;/p&gt;

&lt;p&gt;As useful as Open Babel is, it doesn't run directly on a Java Virtual Machine (JVM). Although an &lt;a href="http://openbabel.sourceforge.net/wiki/Java"&gt;Open Babel JNI&lt;/a&gt; interface does exist, using it introduces a platform dependency, which in many cases is not acceptable. JNI is a great solution in some cases, but when maintaining a single version of a program is important, or when applets need to be used, or when code needs to work with unusual system configurations, it's a poor choice.&lt;/p&gt;

&lt;p&gt;Our goal is to compile Open Babel's "babel" command-line utility into pure Java bytecode that can be run on any recent JVM without using JNI.&lt;/p&gt;

&lt;h4&gt;Overview of NestedVM&lt;/h4&gt;

&lt;p&gt;In a nutshell, NestedVM converts MIPS binaries to Java class files. In theory, this allows software written in any language that can be compiled to a MIPS binary to be run on a JVM.&lt;/p&gt;

&lt;p&gt;To do this, NestedVM distributes two categories of tools: (1) a complete MIPS cross-compiler toolchain; and (2) a MIPS binary to Java bytecode compiler and accessories.&lt;/p&gt;

&lt;h4&gt;Building NestedVM&lt;/h4&gt;

&lt;p&gt;The preferred method to install NestedVM is to compile it from source found in the project repository. There are a number of prerequisites your system must meet in order to be able to do so. For now, this article assumes your system has all of them. Some of the following steps can be found in &lt;a href="http://wiki.brianweb.net/NestedVM/QuickStartGuide"&gt;these instructions&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;To obtain the source code from the NestedVM darcs repository:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ darcs get --repo-name=nestedvm http://nestedvm.ibex.org
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Then change into the &lt;strong&gt;nestedvm&lt;/strong&gt; directory and build the main code:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ cd nestedvm
$ make
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;On my machine, this step takes 10-15 minutes.&lt;/p&gt;

&lt;p&gt;To make sure your build works, run the tests:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ make test
...
1.574000e+00
-4.315000e+01l
-43
-4.315000e+01
4.315000e+01
Hello, World
7F
fabs(-2.24) = 2.34
Destructor!
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;NestedVM doesn't build the g++ compiler by default - it's something that needs to be done manually. Fortunately, it's not difficult to do:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ make cxxtest
...
java -cp build tests.CXXTest
Test's constructor
Name: 0x50b40
Name: PKc
Is pointer: 1
Name: 0x50b3c
Name: i
Is pointer: 0
Hello, World from Test
Now throwing an exception
sayhi threw: const char *:Hello, Exception Handling!
Test's destructor
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Finally, with all tools built, we need to set up our environment:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ make env.sh
$ source env.sh
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We're now ready to cross-compile Open Babel.&lt;/p&gt;

&lt;h4&gt;Cross-Compiling Open Babel&lt;/h4&gt;

&lt;p&gt;For this tutorial, we'll use the &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=40728&amp;amp;package_id=32894&amp;amp;release_id=521581"&gt;Open Babel 2.1.1&lt;/a&gt; source distribution. Unpack the tarball and change into the directory.&lt;/p&gt;

&lt;p&gt;Next, we'll need to set up our cross-compiler environment. Fortunately, NestedVM has made this easy. If you check your environment variables, you'll find that &lt;tt&gt;CXX&lt;/tt&gt; and &lt;tt&gt;CC&lt;/tt&gt; have both been set. All that remains is to notify the configure script that we'll be cross-compiling:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ ./configure --host=mips-unknown-elf
&lt;/div&gt;

&lt;p&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Then we build the MIPS binaries:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ make
&lt;/div&gt;

&lt;p&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Peeking into the &lt;strong&gt;tools&lt;/strong&gt; directory, we can see all of the Open Babel command line tools have been built, including &lt;tt&gt;babel&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Unless you're running a MIPS machine, though, this binary won't be executable.&lt;/p&gt;

&lt;p&gt;So far, it looks like everything worked. Although it didn't work the first time I tried it, the NestedVM team &lt;a href="http://groups.google.com/group/nestedvm/browse_thread/thread/7373accf6010d6d7"&gt;were most helpful&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Building the Java Class File&lt;/h4&gt;

&lt;p&gt;We're now ready for the final stage in the process, converting the MIPS binary to a Java class file. Again, NestedVM makes this simple:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ cd tools
$ java org.ibex.nestedvm.Compiler -outfile Babel.class Babel babel
Exception in thread "main" java.lang.IllegalStateException: unresolved phantom target
        at org.ibex.classgen.MethodGen.resolveTarget(MethodGen.java:555)
        at org.ibex.classgen.MethodGen._generateCode(MethodGen.java:664)
        at org.ibex.classgen.MethodGen.generateCode(MethodGen.java:618)
        at org.ibex.classgen.MethodGen.dump(MethodGen.java:888)
        at org.ibex.classgen.ClassFile._dump(ClassFile.java:193)
        at org.ibex.classgen.ClassFile.dump(ClassFile.java:160)
        at org.ibex.nestedvm.ClassFileCompiler.__go(ClassFileCompiler.java:380)
        at org.ibex.nestedvm.ClassFileCompiler._go(ClassFileCompiler.java:72)
        at org.ibex.nestedvm.Compiler.go(Compiler.java:259)

&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Unfortunately, NestedVM has blown up with an exception. Although our target class file, &lt;strong&gt;Babel.class&lt;/strong&gt; is now in our working directory, it is not complete and won't run.&lt;/p&gt;

&lt;h4&gt;What Went Wrong?&lt;/h4&gt;

&lt;p&gt;After bringing this problem to the &lt;a href="http://groups.google.com/group/nestedvm"&gt;NestedVM mailing list&lt;/a&gt;, it appears that this is a &lt;a href="http://groups.google.com/group/nestedvm/browse_thread/thread/b5d114a20a6b672b"&gt;NestedVM bug&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, the way &lt;tt&gt;babel&lt;/tt&gt; works is to load its various language modules dynamically. It may be possible to fix the problem by producing a version of &lt;tt&gt;babel&lt;/tt&gt; containing all of its modules in a single binary.&lt;/p&gt;

&lt;p&gt;Although there is a major issue to be resolved, this tutorial illustrates the full process of compiling C++ code to Java bytecode using NestedVM.&lt;/p&gt;</description>
      <pubDate>Mon, 19 Nov 2007 10:42:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:63647f0e-a238-45dd-af26-f57319f21001</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt</link>
      <category>Tools</category>
      <category>nestedvm</category>
      <category>openbabel</category>
      <category>crosscompile</category>
      <category>mips</category>
      <category>bytecode</category>
    </item>
    <item>
      <title>"Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt" by &#191;&#191;&#191;Fortunately, it's not difficult to do:????</title>
      <description>I found this error:

alberto@alberto:~/nestedvm-2007-01-12$ make cxxtest
make -C upstream tasks/build_gcc_step2 usr="/home/alberto/nestedvm-2007-01-12/upstream/install" \
		MIPS_CFLAGS="-O3 -mmemcpy -ffunction-sections -fdata-sections -falign-functions=512 -fno-rename-registers -fno-schedule-insns -fno-delayed-branch -freduce-all-givs -march=mips1 -I. -Wall -Wno-unused" \
		MIPS_PCFLAGS="-O3 -mmemcpy -ffunction-sections -fdata-sections -falign-functions=512 -fno-rename-registers -fno-schedule-insns -fno-delayed-branch -freduce-all-givs -march=mips1 -I. -Wall -Wno-unused --big-endian" \
		MIPS_LDFLAGS="-march=mips1 --static -Wl,--gc-sections"
make[1]: se ingresa al directorio `/home/alberto/nestedvm-2007-01-12/upstream'
mkdir -p /home/alberto/nestedvm-2007-01-12/upstream/install
mkdir -p build/gcc-obj &amp;&amp; cd build/gcc-obj &amp;&amp; \
		echo | ../gcc-3.3.6/configure --prefix=/home/alberto/nestedvm-2007-01-12/upstream/install --target=mips-unknown-elf --disable-threads --with-gnu-ld --with-gnu-as --with-newlib=yes --enable-sjlj-exceptions --enable-languages="c" --enable-languages="c,c++,f77" &amp;&amp; \
		make TARGET_CFLAGS="-O3 -mmemcpy -ffunction-sections -fdata-sections -falign-functions=512 -fno-rename-registers -fno-schedule-insns -fno-delayed-branch -freduce-all-givs -march=mips1 -I. -Wall -Wno-unused" &amp;&amp; \
		make install
Configuring for a i686-pc-linux-gnu host.
Created "Makefile" in /home/alberto/nestedvm-2007-01-12/upstream/build/gcc-obj
cc1: error: opci&#243;n `memcpy' inv&#225;lida
*** The command 'gcc -o conftest -O3 -mmemcpy -ffunction-sections -fdata-sections -falign-functions=512 -fno-rename-registers -fno-schedule-insns -fno-delayed-branch -freduce-all-givs   conftest.c' failed.
*** You must set the environment variable CC to a working compiler.
make[1]: *** [tasks/build_gcc_step2] Error 1
make[1]: se sale del directorio `/home/alberto/nestedvm-2007-01-12/upstream'
make: *** [upstream/tasks/build_gcc_step2] Error 2


Any help??? </description>
      <pubDate>Thu, 18 Sep 2008 16:02:23 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:40307f2d-76ab-4ba9-b0f0-611863566071</guid>
      <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt#comment-738</link>
    </item>
    <item>
      <title>"Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt" by yash</title>
      <description>&lt;p&gt;hiiiiiiiii
i want software for converting smi file to mol file&lt;/p&gt;</description>
      <pubDate>Fri, 22 Feb 2008 12:42:33 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:0427c612-8bde-4de0-ad7d-8e552f8746ab</guid>
      <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt#comment-419</link>
    </item>
    <item>
      <title>"Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt" by Rich Apodaca</title>
      <description>&lt;p&gt;Zoli, I haven't tried converting 64-bit MIPS binaries or performing the conversion on a 64-bit OS, if that's what you mean. &lt;/p&gt;

&lt;p&gt;I'd be interested in knowing if it works for you, though.&lt;/p&gt;</description>
      <pubDate>Mon, 26 Nov 2007 10:57:25 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:cde123d3-b31f-460e-bdf8-e735d5281aeb</guid>
      <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt#comment-270</link>
    </item>
    <item>
      <title>"Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt" by Zoli</title>
      <description>&lt;p&gt;Can you make it in 64-bit?&lt;/p&gt;</description>
      <pubDate>Mon, 26 Nov 2007 07:37:20 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:4056b51a-db82-4a45-8606-23fe5218992e</guid>
      <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt#comment-268</link>
    </item>
    <item>
      <title>"Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt" by Brian Alliet</title>
      <description>&lt;p&gt;For the record, this bug has been fix. See the bug report above.&lt;/p&gt;

&lt;p&gt;-Brian (&lt;a href="mailto:brian@brianweb.net" rel="nofollow"&gt;brian@brianweb.net&lt;/a&gt;)&lt;/p&gt;</description>
      <pubDate>Tue, 20 Nov 2007 14:17:37 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:2a1b19d4-36d5-4e7f-bd9a-a01947c25527</guid>
      <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt#comment-266</link>
    </item>
    <item>
      <title>"Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt" by Oleg</title>
      <description>&lt;p&gt;On my machine (SuSE linux x64) to statically compile I use the following config command
./configure --disable-dynamic-modules --enable-static=yes --enable-shared=no&lt;/p&gt;

&lt;p&gt;it should work also for mips target.&lt;/p&gt;

&lt;p&gt;Oleg. (&lt;a href="mailto:OUrsu@salud.unm.edu" rel="nofollow"&gt;OUrsu@salud.unm.edu&lt;/a&gt;)&lt;/p&gt;</description>
      <pubDate>Tue, 20 Nov 2007 11:35:49 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:b15dd8ca-94dc-469b-ba57-0e52c7223a01</guid>
      <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt#comment-265</link>
    </item>
    <item>
      <title>"Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt" by Rich Apodaca</title>
      <description>&lt;p&gt;Oleg, good question. It sure seems feasible, but I'm still trying to learn how to do it.&lt;/p&gt;

&lt;p&gt;Do you know how to configure Open Babel to statically compile one large binary for the &lt;strong&gt;babel&lt;/strong&gt; program?&lt;/p&gt;</description>
      <pubDate>Mon, 19 Nov 2007 17:26:35 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:4e853350-1c9c-45b0-8de3-320dff23cb79</guid>
      <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt#comment-262</link>
    </item>
    <item>
      <title>"Compiling Open Babel to Pure Java Bytecode with NestedVM: An Unsuccessful First Attempt" by Oleg (OUrsu@salud.unm.edu)</title>
      <description>&lt;p&gt;what if you compile statically everything in one large MIPS binary file?&lt;/p&gt;

&lt;p&gt;Oleg.&lt;/p&gt;</description>
      <pubDate>Mon, 19 Nov 2007 14:45:32 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:b0f0c2c0-7dbd-4810-bbfa-5dce0056164e</guid>
      <link>http://depth-first.com/articles/2007/11/19/compiling-open-babel-to-pure-java-bytecode-with-nestedvm-an-unsuccessful-first-attempt#comment-261</link>
    </item>
  </channel>
</rss>
