# Makefile for GNU Pascal compiler.
#   Copyright (C) 1987, 1992 Free Software Foundation, Inc.
#
# This file is part of GNU CC.
#
# GNU CC 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 1, or (at your option)
# any later version.
#
# GNU CC 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 GNU CC; see the file COPYING.  If not, write to
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

TAR= gtar -czvf

# This makefile assumes you have already compiled the correct version
# of GCC $(gccsrc) to the directory $(gccdir), which should contain
# necessary object files

GPCVERSION=1.1

# GPC source directory
# configure can change this
srcdir = .

# Directory where GNU-C compiler SOURCES are
# configure can change this
gccsrc = ../gcc-2.6.3

# Directory where GNU-C compiler OBJECTS are
# configure can change this
gccdir = ../gcc-2.6.3

# Target host
# Grab it from GCC configure.status with sed
# It now takes the target host from the "target=" config field.
#
target = i486-linux

# GCC version on which the GPC is implemented on.
gccversion=`$(gccdir)/xgcc -dumpversion`

# gcc.o search paths depend on this
version = $(gccversion)

#
# Pascal Validation Suite tests
#
pvsdir = /src/gnu/gpc/pvs

# Your own flags to compile both gpc and the run time system
MY_CFLAGS= 
# Your own library specific flags for rts (see rts/Makefile)
MY_LIBFLAGS= -g

# Define GPC if you wish to compile GPC (obviously)
#
# Flags common to gpc and run time system
COMMON_CFLAGS= -DGPC $(MY_CFLAGS)

# compiler flags including the above
CFLAGS = $(COMMON_CFLAGS) -Dabort=fancy_abort
LINTFLAGS = -DGPC
CC = gcc
LINT = lint
BISON = bison
# drop the -v flag
BISONFLAGS = -d

SHELL = /bin/sh

# For now, it's cp; no real reason.
INSTALL_PROGRAM = cp
# If you do not have/need ranlib use /bin/true
RANLIB = ranlib

# GNU make (gmake) or make
# If your make does not set MAKE variable, set it here
#MAKE = make

# Some extra checks for run time system compilation
RTS_WARN=-Wall -Wno-implicit
# but they are not on now
RTS_WARN=
#
# This needs to be GNU C compiler. Otherwise you'll have trouble
# with the run time system. (e.g. complex_type arguments)
#
RTS_GCC=../$(gccdir)/xgcc -B../$(gccdir)/ $(RTS_WARN)

# GPERF program to generate perfect hash function for pascal
# reserved words
#
# You don't need it, if you don't change 
# gpc.gperf (Pascal's reserved words)
# or the file
# gpc-gperf.c (generated from the previous)
#
# see gperf.texinfo for options
GPERF= gperf -o -j1 -t -p -N is_reserved_word

# Use unidiff for diffs.
#
DIFF= gdiff -u

# Common prefix for installation directories.
# NOTE: This directory must exist when you start installation.
prefix = /usr
# Directory in which to put host dependent programs and libraries
exec_prefix = $(prefix)
# Directory in which to put the executable for the command `gcc'
bindir = $(exec_prefix)/bin
# Directory in which to put the directories used by the compiler.
libdir = $(exec_prefix)/lib
# Directory in which the compiler finds executables, libraries, etc.
libsubdir = $(libdir)/gcc-lib/$(target)/$(gccversion)

# For cccp.c compilation. See gcc/Makefile.in for more info.
#
# NOTE: local_prefix *should not* default from prefix.
localprefix = /usr/local
gxx_include_dir = $(libdir)/g++-include
includedir = $(localprefix)/include
tooldir = $(exec_prefix)/$(target)

# See GCC Makefile for information about flags needeed
# for various systems, if you want to try to compile
# GPC on such systems.

# If you are making gcc for the first time, and if you are compiling it with
# a non-gcc compiler, and if your system doesn't have a working alloca() in any
# of the standard libraries (as is true for HP/UX or Genix),
# then get alloca.c from GNU Emacs and un-comment the following line:
#
# You should not need to define this. See GCC_ALLOCA.
#ALLOCA =

# Alloca is automatically loaded if it exists if $(gccdir)/alloca.o exists.
#
GCC_ALLOCA = `if [ -f "$(gccdir)/alloca.o" ]; then echo "$(gccdir)/alloca.o" ; else true ; fi`

# But if your system has alloca() in /lib/libPW.a, un-comment the following line:
# CLIB= -lPW

# If your system's malloc() routine fails for any reason (and gcc also uses a
# separate malloc package, the following should cause malloc.o to be loaded also
# in gpc)
#
#MALLOC =
#
GCC_MALLOC = `if [ -f "$(gccdir)/malloc.o" ]; then echo "$(gccdir)/malloc.o" ; else true ; fi`

# Change this to a null string if obstacks are installed in the
# system library.
OBSTACK = $(gccdir)/obstack.o
OBSTACK_SRC= $(gccdir)/obstack.c

# Dependency on obstack, alloca, malloc or whatever library facilities
# are not installed in the system libraries.
LIBDEPS = $(OBSTACK) $(ALLOCA) $(MALLOC)
LINTLIBS = $(OBSTACK_SRC) $(ALLOCA_SRC) $(MALLOC_SRC)

# How to link with both our special library facilities
# and the system's installed libraries.
LIBS = $(OBSTACK) $(GCC_ALLOCA) $(ALLOCA) $(GCC_MALLOC) $(MALLOC) $(CLIB) $(LOADLIBES)

INCLUDES = -I. -I$(srcdir) -I$(gccdir) -I$(gccsrc) -I$(gccsrc)/config

native: gpc.status gpc pascal library preprosessor

gpc.status:
	@echo You must run configure from the GPC source directory
	@echo to create '"gpc.status"'. See file DOCONF.example to check
	@echo out for an example of the parameters.
	@false

pascal: gpc1

preprosessor: gpc-cpp

.c.o:
	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) $<

# These object files should be language independent but are currently
# not so.
# 
GPC_LANG_IND_OBJS = stor-layout.o dbxout.o expr.o fold-const.o \
		    optabs.o convert.o function.o setop.o toplev.o

#
# Language specific object files for Pascal
#
# Currently the (c-aux-info.c,c-iterate.c) file is not modified
# so I use the original C-compiler file
#
GPC_OBJS_1 = gpc-parse.o gpc-decl.o gpc-typeck.o gpc-convert.o    \
	gpc-util.o gpc-module.o gpc-lex.o gpc-common.o gpc-lang.o \
	$(gccdir)/c-aux-info.o $(gccdir)/c-iterate.o		  \
	$(gccdir)/c-pragma.o					  \
	$(GPC_LANG_IND_OBJS)

# Files specific to the C interpreter bytecode compiler(s).
BC_OBJS = $(gccdir)/bc-emit.o $(gccdir)/bc-optab.o

# Language-independent object files.
#
OBJS = $(gccdir)/tree.o $(gccdir)/print-tree.o \
       $(gccdir)/stmt.o $(gccdir)/calls.o    \
       $(gccdir)/expmed.o $(gccdir)/explow.o $(gccdir)/varasm.o	  \
       $(gccdir)/rtl.o $(gccdir)/print-rtl.o $(gccdir)/rtlanal.o  \
       $(gccdir)/emit-rtl.o $(gccdir)/real.o			  \
       $(gccdir)/sdbout.o $(gccdir)/dwarfout.o $(gccdir)/xcoffout.o \
       $(gccdir)/integrate.o $(gccdir)/jump.o $(gccdir)/cse.o     \
       $(gccdir)/loop.o $(gccdir)/unroll.o $(gccdir)/flow.o       \
       $(gccdir)/stupid.o $(gccdir)/combine.o $(gccdir)/regclass.o \
       $(gccdir)/local-alloc.o $(gccdir)/global.o $(gccdir)/reload.o \
       $(gccdir)/reload1.o $(gccdir)/caller-save.o $(gccdir)/insn-peep.o \
       $(gccdir)/reorg.o $(gccdir)/sched.o $(gccdir)/final.o      \
       $(gccdir)/recog.o $(gccdir)/reg-stack.o $(gccdir)/insn-opinit.o \
       $(gccdir)/insn-recog.o $(gccdir)/insn-extract.o 		  \
       $(gccdir)/insn-output.o $(gccdir)/insn-emit.o $(gccdir)/insn-attrtab.o \
       $(gccdir)/aux-output.o $(gccdir)/getpwd.o $(EXTRA_OBJS)

# Object files that make up the GNU Pascal compiler
#
GPC_OBJS = version.o $(GPC_OBJS_1) $(OBJS)

# Language specific SOURCE files for Pascal
# The modules on the last line should be
# converted to language independent modules.

# Language independent files that need to be modified
# Setop will be a lang ind source file
GPC_LANG_IND = $(srcdir)/stor-layout.c $(srcdir)/dbxout.c $(srcdir)/expr.c \
	$(srcdir)/fold-const.c $(srcdir)/optabs.c $(srcdir)/convert.c \
	$(srcdir)/function.c $(srcdir)/setop.c $(srcdir)/toplev.c

# Necessary source files for GPC
OTHER_SRC = $(srcdir)/READ* $(srcdir)/DOCONF.example $(srcdir)/DOCONF.kampi \
	$(srcdir)/.gdbinit \
	$(srcdir)/NOTE* $(srcdir)/PROBLEMS $(srcdir)/ChangeLog        \
	$(srcdir)/INSTALL $(srcdir)/NEW-PVS-LIST $(srcdir)/gnuvers*   \
	$(srcdir)/gpc.gperf $(srcdir)/Makefile.in $(srcdir)/configure \
	$(srcdir)/gpc-lang.h $(srcdir)/GPC.GUIDE $(srcdir)/COPYING*   \
	$(srcdir)/gpc-parse.y  $(srcdir)/gpc-cccp.c $(GPC_SRC_0)      \
	$(RTSFILES) $(srcdir)/Version.c $(srcdir)/rts/Makefile.in     \
	$(srcdir)/contrib $(srcdir)/borland2ep.doc

# for tar copies only
GPC_SRC_0 = $(srcdir)/gcc.c $(GPC_SRC_2) $(srcdir)/gpc-parse.c \
	    $(srcdir)/gpc-parse.h

GPC_SRC_1 = $(srcdir)/gpc-decl.c $(srcdir)/gpc-typeck.c \
	$(srcdir)/gpc-convert.c $(srcdir)/gpc-common.c	\
	$(srcdir)/gpc-lang.c				\
	$(GPC_LANG_IND)

# GPC source files (that will go to TAGS)
GPC_SRC_2 = $(srcdir)/gpc-defs.h $(srcdir)/gpc-util.c $(srcdir)/gpc-module.c $(srcdir)/gpc-lex.c \
	$(srcdir)/gpc-gperf.c $(GPC_SRC_1)

GPC_SRC = version.c $(GPC_SRC_2)

# Language-independent SOURCE files. For LINT and ETAGS only
#
# See also $(GPC_LANG_IND) They should come back to this
# list when compilers are merged.
# (most of the changes don't affect the C-compiler anyway)
#
SRC =  $(gccsrc)/tree.c $(gccsrc)/print-tree.c \
       $(gccsrc)/stmt.c $(gccsrc)/calls.c $(gccsrc)/expmed.c $(gccsrc)/explow.c \
       $(gccsrc)/varasm.c  \
       $(gccsrc)/rtl.c $(gccsrc)/print-rtl.c $(gccsrc)/rtlanal.c $(gccsrc)/emit-rtl.c \
       $(gccsrc)/sdbout.c $(gccsrc)/dwarfout.c $(gccsrc)/xcoffout.c \
       $(gccsrc)/integrate.c $(gccsrc)/jump.c $(gccsrc)/cse.c $(gccsrc)/loop.c \
       $(gccsrc)/unroll.c $(gccsrc)/flow.c $(gccsrc)/stupid.c $(gccsrc)/combine.c \
       $(gccsrc)/regclass.c $(gccsrc)/local-alloc.c $(gccsrc)/global.c $(gccsrc)/reload.c \
       $(gccsrc)/reload1.c $(gccsrc)/caller-save.c \
       $(gccsrc)/insn-peep.c $(gccsrc)/reorg.c $(gccsrc)/sched.c $(gccsrc)/final.c \
       $(gccsrc)/recog.c $(gccsrc)/reg-stack.c \
       $(gccsrc)/insn-recog.c $(gccsrc)/insn-extract.c $(gccsrc)/insn-output.c \
       $(gccsrc)/insn-emit.c \
       $(gccsrc)/insn-attrtab.c $(gccsrc)/aux-output.c $(gccsrc)/getpwd.c $(EXTRA_OBJS)

TAGS_FILES = $(GPC_SRC_2) $(SRC) $(srcdir)/gpc-parse.y $(gccsrc)/*.h
TAR_FILES = $(OTHER_SRC)

# reversed order / juki
all: library gpc1 gpc gpc-cpp

gpc: gcc.o  $(LIBDEPS) version.o # version.c
	$(CC) $(CFLAGS) $(LDFLAGS) -o gpc gcc.o version.o $(LIBS)

# Generate a new edit number
version.c: Makefile
	echo 'VARLIST="PROG1 PROG2"' > gnuvers.conf
	echo 'PROG1='$(GPCVERSION) >>  gnuvers.conf
	echo 'PROG2='$(gccversion) >> gnuvers.conf
	sh $(srcdir)/gnuvers.sh gnuvers.conf $(srcdir)/Version.c

gcc.o: gcc.c $(gccdir)/$(CONFIG_H) $(gccdir)/multilib.h $(gccdir)/config.status
	$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) \
  -DSTANDARD_STARTFILE_PREFIX=\"$(libdir)/\" \
  -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc-lib/\" \
  -DDEFAULT_TARGET_VERSION=\"$(version)\" \
  -DDEFAULT_TARGET_MACHINE=\"$(target)\" \
  -DTOOLDIR_BASE_PREFIX=\"$(exec_prefix)/\" \
  $(MAYBE_TARGET_DEFAULT) \
  -c `echo $(srcdir)/gcc.c | sed 's,^\./,,'`

#
#  @@@ The necessary$ variables are not initialized!!!!!
#
gpc-cccp.o: gpc-cccp.c
gpc-cccp.o: $(gccdir)/$(CONFIG_H) $(gccsrc)/pcp.h $(gccsrc)/version.c $(gccdir)/config.status
	$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) \
	  -DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
	  -DGPLUSPLUS_INCLUDE_DIR=\"$(gxx_include_dir)\" \
	  -DLOCAL_INCLUDE_DIR=\"$(includedir)\" \
	  -DCROSS_INCLUDE_DIR=\"$(libsubdir)/sys-include\" \
	  -DTOOL_INCLUDE_DIR=\"$(tooldir)/include\" \
	  -c `echo $(srcdir)/gpc-cccp.c | sed 's,^\./,,'`

gpc-cpp: gpc-cccp.o $(gccdir)/cexp.o $(gccdir)/version.o $(LIBDEPS)
	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o gpc-cpp gpc-cccp.o $(gccdir)/cexp.o $(gccdir)/version.o $(LIBS)

gpc1: gpc-gperf.c $(GPC_OBJS) $(BC_OBJS)
	$(CC) $(CFLAGS) $(LDFLAGS) -o gpc1new $(GPC_OBJS) $(BC_OBJS) $(LIBS)
	rm -f gpc1
	mv gpc1new gpc1

# Generate this to the source directory
$(srcdir)/gpc-gperf.c: gpc.gperf
	$(GPERF) $(srcdir)/gpc.gperf > $(srcdir)/gpc-gperf.c

# Circular dependency
#gpc-gperf.c: $(srcdir)/gpc-gperf.c

rts/Makefile: $(srcdir)/rts/Makefile
	-if [ ! -d rts ]; then mkdir rts; else; true; fi
	cp $(srcdir)/rts/Makefile rts/Makefile	
	-ln -s $(srcdir) srcdir
	-ln -s $(gccsrc) gccsrc
	-ln -s $(gccdir) gccdir

# The Pascal runtime library files
#
rts=$(srcdir)/rts

RTSFILES=$(rts)/rts.h       $(rts)/rts-fdr.h     $(rts)/rts-hdr.h \
	$(rts)/rts-types.h  $(rts)/rts-set.h     $(rts)/Version.c     \
	$(rts)/rts-heap.c   $(rts)/rts-math.c    $(rts)/rts-zmath.c   \
	$(rts)/rts-read.c   $(rts)/rts-set.c     $(rts)/rts-setup.c   \
	$(rts)/rts-times.c  $(rts)/rts-write.c   $(rts)/rts-error.c   \
	$(rts)/rts-file.c   $(rts)/rts-misc.c    $(rts)/rts-random.c  \
	$(rts)/rts-rt0.c    $(rts)/rts-string.c  		      \
	$(rts)/rts-rdsub.c  $(rts)/rts-bind.c

library:
	cd rts ; $(MAKE) CC="$(RTS_GCC)" RTSFLAGS="$(COMMON_CFLAGS) $(MY_LIBFLAGS)"

library-clean:
	cd rts ; $(MAKE) clean

lint-gpc:
	$(LINT) $(LINTFLAGS) $(LDFLAGS) $(INCLUDES) $(GPC_SRC) $(SRC) $(LINTLIBS)

# Pascal language specific files
gpc-parse.o : $(srcdir)/gpc-parse.c gpc-parse.h

$(srcdir)/gpc-parse.c: gpc-parse.y
	$(BISON) $(BISONFLAGS) -o tmp-gpc-parse.c $(srcdir)/gpc-parse.y
	-sh $(gccsrc)/move-if-change tmp-gpc-parse.h $(srcdir)/gpc-parse.h
	mv tmp-gpc-parse.c $(srcdir)/gpc-parse.c

gpc-common.o: gpc-common.c gpc-parse.h
gpc-lex.o: gpc-lex.c gpc-gperf.c gpc-parse.h
gpc-util.o: gpc-util.c $(srcdir)/rts/rts-types.h gpc-parse.h 

clean:
	-rm -f *.s *.s[0-9] *.co *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop
	-rm -f core .stampdir
	-rm -f gpc1 gpc gpc-cpp

# Copy the files into directories where they will be run.
install: install-cross

.stampdir: version.c Makefile

# Create the installation directory.
install-dir: .stampdir
	-mkdir $(libdir)
	-mkdir $(libdir)/gcc-lib
	-mkdir $(libdir)/gcc-lib/$(target)
	-mkdir $(libdir)/gcc-lib/$(target)/$(gccversion)
	-mkdir $(bindir)
	touch .stampdir

# Install the compiler executables built during cross compilation.
install-gpc1: gpc1
	$(INSTALL_PROGRAM) gpc1 $(libsubdir)/gpc1

install-gpc-cpp: gpc-cpp
	$(INSTALL_PROGRAM) gpc-cpp $(libsubdir)/gpc-cpp

copy-gpc1:
	$(INSTALL_PROGRAM) gpc1 $(libsubdir)/gpc1

install-gpc: gpc
	$(INSTALL_PROGRAM) gpc $(bindir)/gpc

install-cross: native install-dir install-lib install-gpc1
install-cross: install-gpc install-gpc-cpp

install-lib: library
	-if [ -f rts/libgpc.a ]; then $(INSTALL_PROGRAM) rts/libgpc.a $(libsubdir)/libgpc.a ; else true; fi
	-if [ -f $(libsubdir)/libgpc.a ]; then cd $(libsubdir); $(RANLIB) libgpc.a ; else true; fi

# gpc tags file
#
TAGS: $(TAGS_FILES)
	etags $(TAGS_FILES)

#Ignore whether these exist.
.PHONY: clean TAGS install backup ftp test

#
# The following tests assume you have installed the
# Pascal Validation Suite to $(pvsdir)
#
pvs-link:
	-rm pvs pvsc
	-ln -s $(pvsdir) pvs
	-ln -s $(pvsdir)/CONFORMANCE pvsc

pvs-test: pvs-link
	cd pvsc; ./run

#
# Create a TAR copy of the GPC sources
# Run gpcdist from the generated makefile.
#
gpcdist:
	V=$(gccversion) ; echo $(TAR_FILES) | sed -e "s,$(srcdir),$$V,g" > /tmp/gpc.files; \
	cd $(srcdir)/.. && $(TAR) gpc-$(GPCVERSION)-$$V.tar.gz `cat /tmp/gpc.files`
	rm -f /tmp/gpc.files

# take diffs of language independent files
ind-diff:
	-mkdir DIFF
	-for i in stor-layout.c dbxout.c expr.c fold-const.c optabs.c convert.c function.c toplev.c ; do \
		$(DIFF) $(gccsrc)/$$i $(srcdir)/$$i > DIFF/$${i}.diff; echo $$i; \
	done	

# take diffs of language dependent files
other-diff:
	-mkdir DIFF-OTHER
	-for i in gpc-parse.c gpc-decl.c gpc-typeck.c gpc-convert.c  \
		  gpc-common.c gpc-lang.c ; do   \
	   $(DIFF) $(gccsrc)/`echo $$i | sed -e "s/gpc-/c-/"` $(srcdir)/$$i > DIFF-OTHER/$${i}.diff; echo $$i; \
	done
