Section 7.4. Compiling Our Simple Application with gcj


7.4. Compiling Our Simple Application with gcj

The basic form of gcj is

 gcj [options...] [codefile...] [@listfile...] [libraryfile...] 

We'll go over the options in a moment. For now, let's talk about the various kinds of input files the compiler can process.

In the above command-line synopsis, codefile refers to a Java source file, a compiled .class file (yes, gcj can convert already compiled Java bytecodes into native binaries), or even a ZIP or JAR file. A filename prefixed with the at-sign, @, indicates that the file contains a list of filenames to be compiled. That's the @listfile entry in the command synopsis. Finally, zero or more library files to link with may be specified on the command line. When you specify them directly (as opposed to using the -l command-line option) you must provide the full name of the library.

Like all the other Java compilers we have talked about so far, gcj supports the notion of a classpath. It will look in the classpath for unknown classes referenced by the classes you name to the compiler. Since gcj can read and compile from .class and .jar files, you might think you could just make sure that the JAR files from Sun or IBM Java SDK are on the gcj classpath and you would be able to compile any Java program using any Java APIs. Alas, you would be wrong. Why? Because the Java APIs are full of native methods, and which methods are implemented in Java and which are native is not documented anywhere.

Even if this were not so, it is not permissible under the GPL to distribute binaries without also offering to distribute source code. So, to distribute the Sun or IBM API JAR files would be incompatible with the GPL, and to not distribute them but to depend on them would mean shipping a product that doesn't work out of the box and requires users to obtain some non-Free software in order to work. That is just not acceptable. So the developers of gcj have opted to reimplement as much of the Java APIs as possible.

As you can probably guess if you have browsed the Java API Javadoc files, this is a monumental undertaking. The Java APIs are a moving target, and they started huge and grow larger with every new release. There is a parallel project to gcj called GNU Classpath[8] which is attempting to implement the entire Java API. Its target for the 1.0 release is to be fully compatible with Java 1.1 and "largely compatible" with Java 1.2. You might want to look at that project for better API support than that provided by gcj's libgcj.[9] If you are curious about the present status of libgcj's implementation of the Java APIs, there is a Web page (frequently updated) that compares the status of it against the Java 1.4 packages.[10]

[8] http://www.gnu.org/software/classpath/

[9] The gcj and GNU Classpath projects are in the middle of an effort to merge their libraries into a common library. The GNU Classpath project aims to be a Free Software replacement for the JRE API JAR file. As such, it is meant to be a library of Java bytecodes that may be used as a drop-in replacement in any Java runtime environment. For our discussion, we will assume you are using libgcj as shipped with gcj itself.

[10] http://gcc.gnu.org/java/jdk14-libgcj.html

7.4.1. Compiling FetchURL with gcj

We'll discuss gcj's command-line switches in detail in Section 7.5, but we will have to use a couple of them here. First off, be aware that since gcj is actually part of gcc, all of the non-language-specific switches of that system also work in gcj; thus, -o specifies the name of the binary output file, and so on. There are many references on gcc to which you should refer for details (the manpage on gcc is a good place to start). Example 7.1 shows compiling and running FetchURL with gcj.

Tip

The source code for FetchURL can be found in Example 3.30.


Example 7.1. Compiling and running FetchURL with gcj
 $ gcj -o furl --main=FetchURL FetchURL.java $ ./furl http://www.multitool.net/pubkey.html http://www.multitool.net/pubkey.html: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <TITLE>Michael Schwarz's Public GPG key</TITLE> </HEAD> <BODY> <CENTER> <H1>Michael Schwarz's Public GPG Key</H1> </CENTER> <PRE> -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.0.7 (GNU/Linux) mQGiBDuv6IQRBACn1TIWUXiEuZtfR+0Lqx6tYBAzIRpljL42O6r5nKHmndsWV71e FUnhQpQIf+bNGGPMEt0g0vFpD6YWKP4uIEh2o+u1iyIIMs5QH3iqp8kFjbtVZa21 ... ... ... etc. 

We already explained the -o switch which names the resulting binary. The other switch we use here is --main which specifies the class containing the main() that should be run when the binary is invoked. Remember that every Java class may contain a main(). In a multiclass program, the binary needs to know which main() to run when the binary is executed.

Remember that FetchURL is in the default package,[11] so you simply type the class name as the argument to --main. However, if the class is in a nondefault package, the fully qualified name must be used.

[11] Any class without a package declaration is in the default package.

7.4.2. Compiling a Multiclass Program

For contrast, Example 7.2 shows compiling a multiclass program that is contained in a package (it is the Payback debt/savings/purchase calculator).[12]

[12] Since this chapter was written, XML features were added to Payback that make it no longer work with gcj.

Example 7.2. Compiling and running a multiclass program
 $ cd payback/src $ gcj -o payback -I. --main=net.multitool.Payback.Payback \ net/multitool/Payback/Payback.java $ ./payback Payback -- A savings/credit comparison tool Copyright (C) 2003 by Carl Albing and Michael Schwarz Released under the GNU/GPL. Free Software. ... ... ... etc. 

The -I switch names a directory that is to be prepended to the classpath. In this case, we added "." which is the source directory for the Payback program.[13] Notice the package elements expressed with dots for the --main argument, and with slashes for the filename argument.

[13] The Payback code can be found at the book's Web site: http://www.javalinuxbook.com/.

Note

The gcj compiler does pick up and use the CLASSPATH environment variable if it is specified. Also, gcj has a number of switches besides -I for classpath manipulation. We won't cover those here; -I is the preferred method (according to the gcj manpage at any rate).




    Java Application Development with Linux
    Java Application Development on Linux
    ISBN: 013143697X
    EAN: 2147483647
    Year: 2004
    Pages: 292

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net