This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: example of using ant to drive a gcj build


Apologies for replying to an ancient message.  I was browsing the
gcj archives and couldn't help responding to this, and decided to
send it to the list because others appeared interested at the time.

On Sun, Nov 03, 2002 at 03:17:55PM -0800, Adam Megacz wrote:
> Here's GCJ.xml, the build file used to build XWT on gcj-supported
> targets (Win32, Linux, Solaris) demonstrating the use of gcjh, gcj,
> g++, ld, and jikes in a coordinated build.

I was interested in why Adam considers his Ant build.xml file better
than a Makefile.  However, I don't know anything about the gcj build
and am too lazy to download it, so I made up a Makefile based on
Adam's build.xml (there are some holes where I wasn't sure of the
intent).  It is at the bottom.  I prefer the Makefile for several
reasons.

It is shorter (I combined some things that Adam didn't, but even if
he did the build.xml would still be longer), yet I find it more
readable.  Ant and make syntax both have their warts, so I'll let
others judge this for themselves.

The Makefile is more modular.  The files involved are specified all
in one place.  The special case for Trap.java is handled without
duplication.  The relationship between "build" and "link" is in one
place.

Most importantly, the Makefile is more declarative.  Every file
involved is added to the dependency graph in a uniform way, and
there is no procedural control flow.  In the build.xml file, the
build target consists of five steps executed in series, followed by
an explicit call to another target; and up-to-datedness is checked
in two different ways: by <apply/>, and by <uptodate/>--which puts
the result of the check into a variable, which is checked in a
different target!  (What if someone had invoked the "link" target
directly?)  Further, no up-to-datedness checking is done before
calling GCJHTask; presumably, it does some itself (?), but this is
hidden from both the build tool and the reader of build.xml.

> Note the use of both parallel and serial <apply/>'s -- something make
> can't do.

This had me confused at first--I thought "parallel" meant running
multiple instances of the command in parallel.  Actually, it means
sticking all the prerequisites (or only the newer ones?) on one
command line.  At any rate, the Makefile does both the "parallel"
and "serial" versions.

> The dependency analysis here is very, very fine-grained --

In fact (and this is perhaps my biggest gripe with Ant), the
dependencies are not fine-grained at all.  Or rather, the
dependencies that are fine-grained are not "first class".  So you
can't build just one .o file.  And Ant can't parallelize compiling
the .java files and the .xwar files.  

Andrew

DEST_DIR     := bin-$(PLAT)

JAVA_SOURCES := $(wildcard src/org/xwt/*.java)
JAVA_SOURCES += $(wildcard src/org/xwt/util/*.java)
JAVA_SOURCES += src/org/xwt/plat/GCJ.java
JAVA_SOURCES += src/org/xwt/plat/$(SUBPLAT).java
JAVA_SOURCES += $(shell find src/org/bountycastle -name *.java)
JAVA_SOURCES += $(shell find src/org/mozilla -name *.java)
JAVA_OBJECTS := $(JAVA_SOURCES:src/%.java=$(DEST_DIR)/%.o)

CC_SOURCES   := src/org/xwt/plat/$(SUBPLAT).cc
CC_OBJECTS   := $(CC_SOURCES:src/%.cc=$(DEST_DIR)/%-nat.o)

XWAR_SOURCES := $(shell find bin -name *.xwar)
XWAR_OBJECTS := $(XWAR_SOURCES:bin/%.xwar=$(DEST_DIR)/%.o)

# objects in $(DEST_DIR) don't get linked into the binary
LINK_OBJECTS := $(foreach f, \
                          $(JAVA_OBJECTS) $(CC_OBJECTS) $(XWAR_OBJECTS), \
                          $(if $(filter-out $(DEST_DIR)/, $(dir $(f))), $f))

GCJ := $(GCC_PATH)/bin/$(GCC_TARGET)gcj

GCJ_FLAGS := -O9 -g
# turn off optimization of Trap.java due to a compiler bug
$(DEST_DIR)/org/xwt/Trap.o: GCJ_FLAGS := -O0 -g

all: $(DEST_DIR)/$(BINARY_NAME)

# ??? not sure where this fits
gcjh:
	# whatever GCJHTask does

$(JAVA_OBJECTS): $(DEST_DIR)/%.o: src/%.java
	$(GCJ) -fCLASSPATH=bin/ $(GCJ_FLAGS) -c $< -o $@

$(CC_OBJECTS): $(DEST_DIR)/%-nat.o: src/%.cc
	$(GCJ) -g -Ibin-$(PLAT) -c $< -o $@

$(XWAR_OBJECTS): $(DEST_DIR)/%.o: bin/%.xwar
	$(GCJ) --resource org/xwt/builtin.xwar -c $< -o $@

$(DEST_DIR)/$(BINARY_NAME): $(LINK_OBJECTS)
	$(GCJ) -fCLASSPATH=$(GCC_PATH)/share/libgcj.jar --main=org.xwt.Main \
	       -o $(DEST_DIR)/$(BINARY_NAME) $^ $(LINK_FLAGS)

> <!-- Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] -->
> <!--
>
>     Subclasses of org.xwt.plat.GCJ should include a .xml file which
>     sets the following properties, then invokes <ant antfile="src/org/xwt/plat/GCJ.xml"/>
> 
>         gcc-target    - the gcc target name to use (for example, i686-pc-mingw32)
>         linkflags     - extra flags to pass to gcj during the link phase, if any
>         binaryname    - the name to give to the final binary
> 
> -->
> 
> <project name="GCJ" default="build">
> 
>     <target name="build">
> 
>         <echo message='extracting .class -> .h'/>
>         <taskdef name='gcjh' classname='org.xwt.tasks.GCJHTask'>
>             <classpath path='bin/'/>                                                                               
>         </taskdef>
>         <gcjh out='bin-${plat}' classpath='bin'/>
> 
>         <echo message='compiling   .java -> .o'/>
>         <apply failonerror='true' executable='${gcc-path}/bin/${gcc-target}gcj' dest='bin-${plat}'>
>             <arg value='-fCLASSPATH=bin/'/>
>             <arg value='-O9'/>
>             <arg value='-g'/>
>             <arg value='-c'/>
>             <srcfile/>
>             <arg value='-o'/>
>             <targetfile/>
>             <fileset dir='src/'>
>                 <include name='org/xwt/*.java'/>
>                 <include name='org/xwt/util/*.java'/>
>                 <include name='org/xwt/plat/GCJ.java'/>
>                 <include name='org/xwt/plat/${subplat}.java'/>
>                 <include name='org/bouncycastle/**/*.java'/>
>                 <include name='org/mozilla/**/*.java'/>
>                 <exclude name='org/xwt/Trap.java'/>
>             </fileset>
>             <mapper type='glob' from='*.java' to='*.o'/>
>         </apply>
> 
>         <!-- we have to turn off optimization here due to a compiler bug -->
>         <apply failonerror='true' executable='${gcc-path}/bin/${gcc-target}gcj' dest='bin-${plat}'>
>             <arg value='-fCLASSPATH=bin/'/>
>             <arg value='-O0'/>
>             <arg value='-g'/>
>             <arg value='-c'/>
>             <srcfile/>
>             <arg value='-o'/>
>             <targetfile/>
>             <fileset dir='src/'>
>                 <include name='org/xwt/Trap.java'/>
>             </fileset>
>             <mapper type='glob' from='*.java' to='*.o'/>
>         </apply>
> 
>         <echo message='compiling     .cc -> .o'/>
>         <apply failonerror='true' executable='${gcc-path}/bin/${gcc-target}gcj' dest='bin-${plat}/'>
>             <arg value='-g'/>
>             <arg value='-Ibin-${plat}'/>
>             <arg value='-c'/>
>             <srcfile/>
>             <arg value='-o'/>
>             <targetfile/>
>             <fileset dir='src/' includes='org/xwt/plat/${subplat}.cc'/>
>             <mapper type='glob' from='*.cc' to='*-nat.o'/>
>         </apply>
>                                                                               
>         <echo message='wrapping    .xwar -> .o'/>
>         <apply failonerror='true' executable='${gcc-path}/bin/${gcc-target}gcj' dest='bin-${plat}/'>
>             <fileset dir='bin/' includes='**/*.xwar'/>
>             <arg value='--resource'/>
>             <arg value='org/xwt/builtin.xwar'/>
>             <arg value='-c'/>
>             <srcfile/>
>             <arg value='-o'/>
>             <targetfile/>
>             <mapper type='glob' from='*.xwar' to='*.o'/>
>         </apply>
> 
>         <echo message='linking        .o -> ${binaryname}'/>
>         <uptodate property="linked" targetfile="bin-${plat}/${binaryname}">
>             <srcfiles dir="bin-${plat}/" includes="**/*.o" excludes='*.o'/>
>         </uptodate>
>         <antcall target="link"/>
> 
>     </target>
> 
>     <target name="link" unless="linked">
>         <apply failonerror='true' executable='${gcc-path}/bin/${gcc-target}gcj' parallel='true'>
>             <fileset dir='bin-${plat}/' includes='**/*.o' excludes='*.o'/>
>             <arg value='-fCLASSPATH=${gcc-path}/share/libgcj.jar'/>
>             <arg value='--main=org.xwt.Main'/>
>             <arg line='-o bin-${plat}/${binaryname}'/>
>             <srcfile/>
>             <arg line='${linkflags}'/>
>        </apply>
>     </target>
> 
> </project>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]