###############################################################################
#
#
# Filename: Makefile
#
# Author:   Robert Thornburrow
# Project:  JavaVM
# Created:  19th January 1998
#
# Purpose:  Makefile for JavaVM.
#
# (c) Copyright R.H.Thornburrow, 2002-3
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
###############################################################################
#
# Targets are:
#
#   all        : builds the executable configured by JAVAVM, OUTDIR and CFLAGS
#   src-tar    : builds a tarball of all the source files
#   riscos-tar : builds a tarball of the sources using a RISCOS dir structure
#   install    : does a make all, then installs the files
#
###############################################################################
#
# Set OUTDIR and JAVAVM to suit your platform.
#
###############################################################################

ifndef prefix
prefix=/opt
endif

VERSION=1.1.0

#OUTDIR=cygwin32
OUTDIR=linux-i386

#JAVAVM=javavm.exe
JAVAVM=javavm

#LIBS=
LIBS=-lm

##############
## Debug build
#CFLAGS=-g -D_DEBUG
#CFLAGS=-O1 -D_DEBUG

#LDFLAGS=


################
## Release build
CFLAGS=-O1 -finline-functions -DOPTIMIZED
#CFLAGS=-O3 -DGCC_OPTIMIZER_CLUDGE

LDFLAGS=-O1


#############
# JDK Version

ifdef JDK_VERSION
CFLAGS+=-DJDK_VERSION=$(JDK_VERSION)
endif


#######################################
# Sources to be compiled (all versions)

SRC=main/main.c main/native-io.c \
	engine/disasm.c       engine/engine.c \
	engine/instructions.c engine/linker.c \
	engine/loader.c       engine/native.c \
	engine/util.c         engine/verifier.c \
	engine/memory.c       engine/zipload.c \
	engine/jstring.c      engine/hashtable.c \
	engine/zipfile.c \
	native/java_lang_Class.c      native/java_lang_ClassLoader.c \
	native/java_lang_Math.c       native/java_lang_Object.c \
	native/java_lang_Runtime.c    native/java_lang_SecurityManager.c \
	native/java_lang_String.c     native/java_lang_System.c \
	native/java_lang_Throwable.c  native/java_lang_Thread.c \
	native/java_lang_reflect_Constructor.c \
	native/java_lang_reflect_Field.c \
	native/java_io_File.c               native/java_io_FileDescriptor.c \
	native/java_io_FileInputStream.c    native/java_io_FileOutputStream.c \
	native/java_io_ObjectStreamClass.c  native/java_io_ObjectInputStream.c \
	native/java_io_ObjectOutputStream.c native/java_io_RandomAccessFile.c \
	native/java_util_ResourceBundle.c


# Sources to be compiled (JDK 1.4)
	
SRC140=native/java_io_UnixFileSystem.c     native/java_lang_StrictMath.c \
    native/java_security_AccessController.c \
    native/sun_misc_Signal.c                native/sun_misc_Unsafe.c \
    native/sun_reflect_NativeConstructorAccessorImpl.c \
    native/sun_reflect_Reflection.c \
    zip/java_util_jar_JarFile               zip/java_util_zip_ZipFile.c \
    zip/java_util_zip_ZipEntry.c


# Object files to be produced (all versions)

OBJ=$(OUTDIR)/main.o         $(OUTDIR)/native-io.o \
	$(OUTDIR)/disasm.o       $(OUTDIR)/engine.o \
	$(OUTDIR)/instructions.o $(OUTDIR)/linker.o \
	$(OUTDIR)/loader.o       $(OUTDIR)/native.o \
	$(OUTDIR)/util.o         $(OUTDIR)/verifier.o \
	$(OUTDIR)/memory.o       $(OUTDIR)/zipload.o \
	$(OUTDIR)/jstring.o      $(OUTDIR)/hashtable.o \
	$(OUTDIR)/zipfile.o \
	$(OUTDIR)/java_lang_Class.o      $(OUTDIR)/java_lang_ClassLoader.o \
	$(OUTDIR)/java_lang_Math.o       $(OUTDIR)/java_lang_Object.o \
	$(OUTDIR)/java_lang_Runtime.o    $(OUTDIR)/java_lang_SecurityManager.o \
	$(OUTDIR)/java_lang_String.o     $(OUTDIR)/java_lang_System.o \
	$(OUTDIR)/java_lang_Throwable.o  $(OUTDIR)/java_lang_Thread.o \
	$(OUTDIR)/java_lang_reflect_Constructor.o \
	$(OUTDIR)/java_lang_reflect_Field.o \
	$(OUTDIR)/java_io_File.o               $(OUTDIR)/java_io_FileDescriptor.o \
	$(OUTDIR)/java_io_FileInputStream.o    $(OUTDIR)/java_io_FileOutputStream.o \
	$(OUTDIR)/java_io_ObjectStreamClass.o  $(OUTDIR)/java_io_ObjectInputStream.o \
	$(OUTDIR)/java_io_ObjectOutputStream.o $(OUTDIR)/java_io_RandomAccessFile.o \
	$(OUTDIR)/java_util_ResourceBundle.o


# Object files to be produced (JDK 1.4)

OBJ140=$(OUTDIR)/java_io_UnixFileSystem.o     $(OUTDIR)/java_lang_StrictMath.o \
    $(OUTDIR)/java_security_AccessController.o \
    $(OUTDIR)/sun_misc_Signal.o                $(OUTDIR)/sun_misc_Unsafe.o \
    $(OUTDIR)/sun_reflect_NativeConstructorAccessorImpl.o \
    $(OUTDIR)/sun_reflect_Reflection.o \
    $(OUTDIR)/java_util_jar_JarFile.o          $(OUTDIR)/java_util_zip_ZipFile.o \
    $(OUTDIR)/java_util_zip_ZipEntry.o


# Test Suite classes to be compiled

TEST=lib\test\TestSuite.class lib\test\Test.class \
    lib\test\ByteTest.class lib\test\ShortTest.class \
    lib\test\IntTest.class lib\test\LongTest.class \
    lib\test\FloatTest.class lib\test\DoubleTest.class \
    lib\test\ExceptionTest.class lib\test\ArrayTest.class \
    lib\test\LoopTest.class


# Project build files (for MSVC, Unix and RISC OS)

RISCOS_MAKEFILES = Makefile.RISCOS engine/Makefile.RISCOS \
    main/Makefile.RISCOS native/Makefile.RISCOS zip/Makefile.RISCOS

PROJECT_FILES = Makefile javavm.spec JavaVM.dsp JavaVM.dsw \
    javavm-ER5.mmp javavm-ER6.mmp Bld.inf \
    engine/Engine.dsp native/Native.dsp zip/Zip.dsp \
    $(RISCOS_MAKEFILES)

RISCOS_PROJECT_FILES = $(RISCOS_MAKEFILES:%.RISCOS=riscos/%)


# Documentation files

DOC_FILES = COPYING HISTORY INSTALL docs/javavm.1


# Scripts - used to build BIN_FILES, the actual list of scripts

SCRIPTS = appletviewer jar java javac javadoc javakey javap jdb native2ascii \
    rmic rmiregistry serialver

BIN_FILES = $(SCRIPTS:%=bin/%) $(SCRIPTS:%=bin/%.bat) $(SCRIPTS:%=bin/%.oby) \
    bin/javac2 bin/javac2.bat

RISCOS_BIN_FILES = $(SCRIPTS:%=riscos/!JavaVM/bin/%.oby)


# Lib files (files to install in lib)

LIB_FILES = lib/zip.dll lib/zip.so

RISCOS_LIB_FILES = $(LIB_FILES:%=riscos/!JavaVM/%)


# RISCOS specific files (to go in !JavaVM)

RISCOS_APP_FILES = riscos/!JavaVM/!Help.txt \
    riscos/!JavaVM/!Boot.oby riscos/!JavaVM/!Run.oby \
    riscos/!JavaVM/!Sprites22,ff9 riscos/!JavaVM/!Sprites,ff9


# Source Files (all .c and .h files)

ENGINE_C_FILES = $(wildcard engine/*.c)
ENGINE_H_FILES = $(wildcard engine/*.h)
MAIN_C_FILES   = $(wildcard main/*.c)
NATIVE_C_FILES = $(wildcard native/*.c)
NATIVE_H_FILES = $(wildcard native/*.h)
ZIP_C_FILES    = $(wildcard zip/*.c)
ZIP_H_FILES    = $(wildcard zip/*.h)

SRC_FILES = \
    $(ENGINE_C_FILES) $(ENGINE_H_FILES) \
    $(MAIN_C_FILES) \
    $(NATIVE_C_FILES) $(NATIVE_H_FILES) \
    $(ZIP_C_FILES) $(ZIP_H_FILES)

RISCOS_SRC_FILES = \
    $(ENGINE_C_FILES:engine/%.c=riscos/engine/c/%) \
    $(ENGINE_H_FILES:engine/%.h=riscos/engine/h/%) \
    $(MAIN_C_FILES:main/%.c=riscos/main/c/%) \
    $(NATIVE_C_FILES:native/%.c=riscos/native/c/%) \
    $(NATIVE_H_FILES:native/%.h=riscos/native/h/%) \
    $(ZIP_C_FILES:zip/%.c=riscos/zip/c/%) \
    $(ZIP_H_FILES:zip/%.h=riscos/zip/h/%)


# List of files to be tar'red up to make src.tar

TAR_FILES = $(DOC_FILES) $(PROJECT_FILES) $(BIN_FILES) $(LIB_FILES) \
    $(SRC_FILES) main/javavm.ico main/JavaVM.rc
	    
RISCOS_TAR_FILES = $(DOC_FILES:%=riscos/%) $(RISCOS_PROJECT_FILES) \
    $(RISCOS_BIN_FILES) $(RISCOS_LIB_FILES) $(RISCOS_APP_FILES) \
    $(RISCOS_SRC_FILES)

SRC_TAR_FILES = $(TAR_FILES:%=javavm-$(VERSION)/%)

.SUFFIXES: .c .h .o .bat .oby .java .class .RISCOS


#########
# Targets

.PHONY: all
all: $(OUTDIR) $(OUTDIR)/$(JAVAVM)

$(OUTDIR):
	if [ ! -d $(OUTDIR) ] ; then mkdir $(OUTDIR); fi

$(OUTDIR)/$(JAVAVM): $(OBJ) $(OBJ140)
	gcc $(LDFLAGS) $(LIBS) -o $(OUTDIR)/$(JAVAVM) $(OBJ) $(OBJ140)

.PHONY: install
install: all
	install -d -m 755 $(DESTDIR)$(prefix)/javavm/bin
	install -m 755 bin/appletviewer \
	     $(DESTDIR)$(prefix)/javavm/bin/appletviewer
	install -m 755 bin/jar $(DESTDIR)$(prefix)/javavm/bin/jar
	install -m 755 bin/java $(DESTDIR)$(prefix)/javavm/bin/java
	install -m 755 bin/javac $(DESTDIR)$(prefix)/javavm/bin/javac
	install -m 755 bin/javac2 $(DESTDIR)$(prefix)/javavm/bin/javac2
	install -m 755 bin/javadoc $(DESTDIR)$(prefix)/javavm/bin/javadoc
	install -m 755 bin/javakey $(DESTDIR)$(prefix)/javavm/bin/javakey
	install -m 755 bin/javap $(DESTDIR)$(prefix)/javavm/bin/javap
	install -m 755 bin/jdb $(DESTDIR)$(prefix)/javavm/bin/jdb
	install -m 755 bin/native2ascii \
	     $(DESTDIR)$(prefix)/javavm/bin/native2ascii
	install -m 755 bin/rmic $(DESTDIR)$(prefix)/javavm/bin/rmic
	install -m 755 bin/rmiregistry $(DESTDIR)$(prefix)/javavm/bin/rmiregistry
	install -m 755 bin/serialver $(DESTDIR)$(prefix)/javavm/bin/serialver
	install -d -m 755 $(DESTDIR)$(prefix)/javavm/lib
	install -m 755 lib/zip.so $(DESTDIR)$(prefix)/javavm/lib/zip.so
	install -d -m 755 $(DESTDIR)$(prefix)/javavm/$(OUTDIR)
	install -m 755 $(OUTDIR)/javavm \
	    $(DESTDIR)$(prefix)/javavm/$(OUTDIR)/javavm
	install -d -m 755 $(DESTDIR)/usr/share/man/man1
	install -m 644 docs/javavm.1 $(DESTDIR)/usr/share/man/man1/javavm.1

clean:
	rm -f $(OBJ) $(OBJ140) $(OUTDIR)/$(JAVAVM)

################################
# only run under Cygwin or Linux

.PHONY: src-tar
src-tar: javavm-$(VERSION).tar.gz

javavm-$(VERSION).tar.gz: $(TAR_FILES)
	cd ..; tar czvf javavm-$(VERSION)/javavm-$(VERSION).tar.gz \
	    $(SRC_TAR_FILES)
	
.PHONY: riscos-tar
riscos-tar: riscos-dirs riscos.tgz

.PHONY: riscos-clean
riscos-clean:
	rm -rf riscos

.PHONY: riscos-dirs
riscos-dirs: riscos riscos/engine riscos/engine/c riscos/engine/h \
    riscos/main riscos/main/c riscos/native riscos/native/c riscos/native/h \
    riscos/zip riscos/zip/c riscos/zip/h riscos/docs \
    riscos/!JavaVM riscos/!JavaVM/bin riscos/!JavaVM/lib
	
riscos riscos/engine riscos/engine/c riscos/engine/h \
    riscos/main riscos/main/c riscos/native riscos/native/c riscos/native/h \
    riscos/zip riscos/zip/c riscos/zip/h riscos/docs \
    riscos/!JavaVM riscos/!JavaVM/bin riscos/!JavaVM/lib:
	if [ ! -d $@ ] ; then mkdir $@ ; fi

riscos/%: %.RISCOS
	cp -p $< $@

riscos/engine/c/%: engine/%.c
	cp -p $< $@

riscos/engine/h/%: engine/%.h
	cp -p $< $@

riscos/main/c/%: main/%.c
	cp -p $< $@

riscos/native/c/%: native/%.c
	cp -p $< $@

riscos/native/h/%: native/%.h
	cp -p $< $@

riscos/zip/c/%: zip/%.c
	cp -p $< $@

riscos/zip/h/%: zip/%.h
	cp -p $< $@

riscos/!JavaVM/%: %
	cp -p $< $@

riscos/%: %
	cp -p $< $@

riscos.tgz: $(RISCOS_TAR_FILES)
	cd riscos; tar czvf ../riscos.tgz $(RISCOS_TAR_FILES:riscos/%=%)


#######################
# only run under Cygwin

#RELEASE=Debug
RELEASE=Release

testsuite: $(TEST)
	-cd lib; ../win32/Debug/javavm.exe test/TestSuite

test-win32:
	./testheader java > test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe Hello >> ../test-win32.log 2>&1
	./testheader javac >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/tools/javac/Main Hello.java >> ../test-win32.log 2>&1
	./testheader appletviewer >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/applet/AppletViewer Hello.html >> ../test-win32.log 2>&1
	./testheader jar >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/tools/jar/Main cvf Hello.jar Hello.class >> ../test-win32.log 2>&1
	./testheader javap >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/tools/javap/JavaP Hello >> ../test-win32.log 2>&1
	./testheader javadoc >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/tools/javadoc/Main Hello.java >> ../test-win32.log 2>&1
	./testheader rmic >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/rmi/rmic/Main RMITest >> ../test-win32.log 2>&1
	./testheader rmiregistry >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/rmi/registry/RegistryImpl >> ../test-win32.log 2>&1
	./testheader serialver >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/tools/serialver/SerialVer SerializationTest >> ../test-win32.log 2>&1
	./testheader javakey >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/security/provider/Main l >> ../test-win32.log 2>&1
	./testheader jdb >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/tools/ttydebug/TTY Hello >> ../test-win32.log 2>&1
	./testheader native2ascii >> test-win32.log
	-cd lib; ../win32/$(RELEASE)/javavm.exe sun/tools/native2ascii/Main test.properties >> ../test-win32.log 2>&1
	-diff test-win32.log test-win32.ref > test-win32-new.dif


#######################
# only run under Cygwin

testsuite-cygwin32: $(TEST)
	@echo Testing Taurus JavaVM...
	bin/java test/TestSuite

test-cygwin32: $(OUTDIR) $(OUTDIR)/$(JAVAVM)
	./testheader java > test-cygwin32.log
	-bin/java Hello >> test-cygwin32.log 2>&1
	./testheader javac >> test-cygwin32.log
	-bin/javac Hello.java >> test-cygwin32.log 2>&1
	./testheader appletviewer >> test-cygwin32.log
	-bin/appletviewer Hello.html >> test-cygwin32.log 2>&1
	./testheader jar >> test-cygwin32.log
	-bin/jar cvf Hello.jar Hello.class >> test-cygwin32.log 2>&1
	./testheader javadoc >> test-cygwin32.log
	-bin/javadoc Hello.java >> test-cygwin32.log 2>&1
	./testheader javap >> test-cygwin32.log
	-bin/javap Hello >> test-cygwin32.log 2>&1
	./testheader rmic >> test-cygwin32.log
	-bin/rmic RMITest >> test-cygwin32.log 2>&1
	./testheader rmiregistry >> test-cygwin32.log
	-bin/rmiregistry >> test-cygwin32.log 2>&1
	./testheader serialver >> test-cygwin32.log
	-bin/serialver SerializationTest >> test-cygwin32.log 2>&1
	./testheader javakey >> test-cygwin32.log
	-bin/javakey l >> test-cygwin32.log 2>&1
	./testheader jdb >> test-cygwin32.log
	-bin/jdb Hello >> test-cygwin32.log 2>&1
	./testheader native2ascii >> test-cygwin32.log
	-bin/native2ascii test.properties >> test-cygwin32.log 2>&1
	diff test-cygwin32.log test-cygwin32.ref > test-cygwin32.dif

###############################
# Generic rules (GNU make only)

$(OUTDIR)/%.o: main/%.c
	gcc -c $(CFLAGS) -o $@ $<

$(OUTDIR)/%.o: engine/%.c
	gcc -c $(CFLAGS) -o $@ $<

$(OUTDIR)/%.o: native/%.c
	gcc -c $(CFLAGS) -o $@ $<

$(OUTDIR)/%.o: zip/%.c
	gcc -c $(CFLAGS) -o $@ $<


#########################
# Dependencies

$(OUTDIR)/main.o: main/main.c engine/config.h
$(OUTDIR)/native-io.o: main/native-io.c engine/config.h
$(OUTDIR)/disasm.o: engine/disasm.c engine/config.h
$(OUTDIR)/engine.o: engine/engine.c engine/boolean.c engine/char.c \
                    engine/double.c engine/float.c engine/integer.c \
                    engine/long.c engine/object.c engine/short.c \
                    engine/if.c engine/engine.h engine/config.h
$(OUTDIR)/instructions.o: engine/instructions.c engine/config.h
$(OUTDIR)/linker.o: engine/linker.c engine/config.h
$(OUTDIR)/loader.o: engine/loader.c engine/config.h
$(OUTDIR)/native.o: engine/native.c engine/engine.h engine/config.h
$(OUTDIR)/util.o:   engine/util.c engine/config.h
$(OUTDIR)/verifier.o: engine/verifier.c engine/config.h
$(OUTDIR)/memory.o: engine/memory.c engine/config.h
$(OUTDIR)/zipload.o: engine/zipload.c engine/config.h
$(OUTDIR)/jstring.o: engine/jstring.c engine/config.h
$(OUTDIR)/hashtable.o: engine/hashtable.c engine/config.h
$(OUTDIR)/zipfile.o: engine/zipfile.c engine/config.h

$(OUTDIR)/java_lang_Class.o:           native/java_lang_Class.c engine/config.h
$(OUTDIR)/java_lang_ClassLoader.o:     native/java_lang_ClassLoader.c engine/config.h
$(OUTDIR)/java_lang_Math.o:            native/java_lang_Math.c engine/config.h
$(OUTDIR)/java_lang_Object.o:          native/java_lang_Object.c engine/config.h
$(OUTDIR)/java_lang_Runtime.o:         native/java_lang_Runtime.c engine/config.h
$(OUTDIR)/java_lang_SecurityManager.o: native/java_lang_SecurityManager.c engine/config.h
$(OUTDIR)/java_lang_String.o:          native/java_lang_String.c engine/engine.h engine/config.h
$(OUTDIR)/java_lang_System.o:          native/java_lang_System.c engine/engine.h engine/config.h
$(OUTDIR)/java_lang_Thread.o:          native/java_lang_Thread.c engine/engine.h engine/config.h
$(OUTDIR)/java_lang_reflect_Constructor.o: native/java_lang_reflect_Constructor.c engine/engine.h engine/config.h
$(OUTDIR)/java_lang_reflect_Field.o:   native/java_lang_reflect_Field.c engine/engine.h engine/config.h
$(OUTDIR)/java_io_File.o:              native/java_io_File.c engine/config.h
$(OUTDIR)/java_io_FileDescriptor.o:    native/java_io_FileDescriptor.c engine/config.h
$(OUTDIR)/java_io_FileInputStream.o:   native/java_io_FileInputStream.c engine/config.h
$(OUTDIR)/java_io_FileOutputStream.o:  native/java_io_FileOutputStream.c engine/config.h
$(OUTDIR)/java_io_ObjectStreamClass.o: native/java_io_ObjectStreamClass.c engine/config.h
$(OUTDIR)/java_io_ObjectInputStream.o: native/java_io_ObjectInputStream.c engine/config.h
$(OUTDIR)/java_io_ObjectOutputStream.o: native/java_io_ObjectOutputStream.c engine/config.h
$(OUTDIR)/java_io_RandomAccessFile.o:  native/java_io_RandomAccessFile.c engine/config.h
$(OUTDIR)/java_util_ResourceBundle.o:  native/java_util_ResourceBundle.c engine/config.h

######################
# JDK 1.4 Dependencies

$(OUTDIR)/java_io_UnixFileSystem.o:   native/java_io_UnixFileSystem.c engine/config.h
$(OUTDIR)/java_lang_StrictMath.o:      native/java_lang_StrictMath.c engine/config.h
$(OUTDIR)/java_security_AccessController.o: native/java_security_AccessController.c engine/config.h
$(OUTDIR)/sun_misc_Signal.o:           native/sun_misc_Signal.c engine/config.h
$(OUTDIR)/sun_misc_Unsafe.o:           native/sun_misc_Unsafe.c engine/config.h
$(OUTDIR)/sun_reflect_NativeConstructorAccessorImpl.o: native/sun_reflect_NativeConstructorAccessorImpl.c engine/config.h
$(OUTDIR)/sun_reflect_Reflection.o:    native/sun_reflect_Reflection.c engine/config.h

$(OUTDIR)/java_util_jar_JarFile.o:     zip/java_util_jar_JarFile.c engine/config.h
$(OUTDIR)/java_util_zip_ZipFile.o:     zip/java_util_zip_ZipFile.c engine/config.h
$(OUTDIR)/java_util_zip_ZipEntry.o:    zip/java_util_zip_ZipEntry.c engine/config.h

#################
# Build TestSuite

{lib\test\}.java{lib\test\}.class:
	cd lib
	javac test\TestSuite.java
	cd ..
