# Makefile for GP
#
# Copyright (C) 2000-2006 Free Software Foundation, Inc.
#
# Author: Frank Heckenbach <frank@pascal.gnu.de>
#
# 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, version 2.
#
# 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; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

V08=n# @@ V08 doesn't work yet
ifeq ($(V08),n)
  VERSION=0.61
  VERSION_FLAGS=
  VERSION_OBJECTS=
  VERSION_GENERATED_FILES=
  SD_EXCL=[ "$$f" = cfg-parse.y ] || \
          [ "$$f" = cfg.pas ] || \
          [ "$$f" = init.gp ] || \
          [ "$$f" = list.inc ] || \
          [ "$$f" = pascal-lex.l ] || \
          [ "$$f" = cfg-lex.c ] ||
else
  VERSION=0.80
  VERSION_FLAGS=-DV08
  VERSION_OBJECTS=cfg.o
  VERSION_GENERATED_FILES=$(real_srcdir)/pascal-lex.c \
                          $(real_srcdir)/cfg-parse.c \
                          $(real_srcdir)/cfg-parse.h
  SD_EXCL=
endif

SHELL=/bin/sh
CFLAGS=-O3 -g -W -Wall -Wunused -Werror $(VERSION_FLAGS)
PC=$(TARGET)gpc
CC=$(PC)
PFLAGS=$(CFLAGS) -Wfloat-equal --no-automake
LDFLAGS=
LEX=flex
LFLAGS=-p --nounput
BISON=bison
BISONFLAGS=
MAKEINFO=makeinfo
INSTALL=install
INSTALLFLAGS=#-o root -g bin
INSTALL_DIR=$(INSTALL) $(INSTALLFLAGS) -d -m 755
INSTALL_PROGRAM=$(INSTALL) $(INSTALLFLAGS) -m 755
INSTALL_DATA=$(INSTALL) $(INSTALLFLAGS) -m 644
TAR=tar
TARSRCFLAGS=-ch --use-compress-program=bzip2 --owner=root --group=root --mode=u+rw,go+r-w -f
TARBINFLAGS=-c --use-compress-program=bzip2 --owner=root --group=root --mode=u+rw,go+r-w -f
TAREXT=.tar.bz2
EXEEXT=
DIR_SEPARATOR=/

srcdir=.
prefix=/usr/local
exec_prefix=$(prefix)
bindir=$(exec_prefix)/bin
infodir=$(prefix)/info
mandir=$(prefix)/man
man1dir=$(mandir)/man1

default: all

sinclude Makefile.cfg

# Heuristic to detect DJGPP. Platform detection doesn't work there
# because GPC's platform directory is cut to 8 characters (usually
# `djgpp' rather than `i386-pc-msdosdjgpp').
SHELLTYPE=sh
ifneq ($(COMSPEC),)
  ifneq ($(DJGPP),)
    PLATFORM=i386-pc-msdosdjgpp
  endif
  ifeq ($(SHELL),)
    SHELLTYPE=command.com
  endif
  ifeq ($(SHELL),$(COMSPEC))
    SHELLTYPE=command.com
  endif
endif

ifeq ($(PLATFORM),)
  PLATFORM:=$(shell $(PC) -dumpmachine)
  ifeq ($(PLATFORM),)
    DUMMY:=$(shell echo "$(PC) not found, or could not determine the platform" >&2; kill $$PPID $$$$; echo "Don't know how to die, please kill me." >&2; while true; do sleep 1000; done)
  endif
endif

# Handle Dos differences
ifeq ($(findstring $(PLATFORM),djgpp i386-pc-go32 i386-pc-msdosdjgpp mingw32 i386-pc-mingw32 i486-pc-mingw32 i586-pc-mingw32 i686-pc-mingw32),)
  TARGET_DOS=n
else
  TARGET_DOS=y
endif

ifeq ($(TARGET_DOS),y)
  VERSION:=$(subst .,-,$(VERSION))
  INSTALL=cp
  INSTALLFLAGS=
  INSTALL_DIR=mkdir -p
  INSTALL_PROGRAM=cp
  INSTALL_DATA=cp
  TAR=zip
  TARSRCFLAGS=-q -r
  TARBINFLAGS=-q -r
  TAREXT=.zip
  EXEEXT=.exe
  DIR_SEPARATOR=$(strip \)# `strip' is just to prevent `\' from quoting the newline here ... :-/
  prefix=$(DJDIR)
  real_srcdir=$(srcdir)
else
  real_srcdir:=$(shell cd $(srcdir); pwd)
endif

ALL_CFLAGS=$(CFLAGS) -I $(real_srcdir)
ALL_PFLAGS=$(PFLAGS) $(PFLAGS2) --unit-path=$(real_srcdir)
PROGS=gp$(EXEEXT)
INFO=$(real_srcdir)/gp.info
DVI=$(real_srcdir)/gp.dvi
PS=$(real_srcdir)/gp.ps
PDF=$(real_srcdir)/gp.pdf
HTML=$(real_srcdir)/gp.html
MAN1=$(real_srcdir)/gp.1
MAN=$(MAN1)
OBJECTS=gpc.o pipes.o pipesc.o stringutils.o fileutils.o md5.o gp-parse.o gp.o $(VERSION_OBJECTS)
NAMEWITHVERSION=gp-$(VERSION)
SRCDIST=$(NAMEWITHVERSION)$(TAREXT)
BINDIST=$(NAMEWITHVERSION)-$(PLATFORM)$(TAREXT)
GENERATED_FILES=$(VERSION_GENERATED_FILES) \
                $(real_srcdir)/gp-parse.c \
                $(real_srcdir)/INSTALL \
                $(real_srcdir)/README \
                $(real_srcdir)/COPYING

# Get the default unit path
GPC_UNIT_PATH:=$(subst $(DIR_SEPARATOR),/,$(shell $(PC) --print-file-name=units))
ifeq ($(GPC_UNIT_PATH),units)
  GPC_UNIT_PATH:=
endif
ifeq ($(GPC_UNIT_PATH),)
  DUMMY:=$(shell echo "$(PC) not found, or could not determine the unit path" >&2; kill $$PPID $$$$; echo "Don't know how to die, please kill me." >&2; while true; do sleep 1000; done)
endif
VPATH=$(real_srcdir) $(GPC_UNIT_PATH)

# If GPC doesn't have libgcc.a, try the one of GCC
LIBGCC_TMP:=$(dir $(subst $(DIR_SEPARATOR),/,$(shell $(PC) $(ALL_PFLAGS) -print-libgcc-file-name)))
ifeq ($(LIBGCC_TMP),./)
  LIBGCC_LDFLAGS=-L $(dir $(subst $(DIR_SEPARATOR),/,$(shell $(CC) $(ALL_CFLAGS) -print-libgcc-file-name)))
endif
ALL_LDFLAGS=$(LDFLAGS) $(LIBGCC_LDFLAGS)

.PHONY: default all generated-files check dvi ps pdf html mostlyclean clean distclean maintainer-clean extraclean readme info install install-sh install-command.com uninstall mindist fulldist dist dist1 bindist
.SUFFIXES:

all: $(PROGS) info man $(GENERATED_FILES)

generated-files: $(GENERATED_FILES)

# Don't use a pipe for sed so errors in gp are seen by make
check: $(PROGS)
	./gp$(EXEEXT) --test-parser --unit-path=$(real_srcdir) $(real_srcdir)/test-parser.pas > test-parser.tmp
	sed -e '/^[PVm]/d;s,\$(DIR_SEPARATOR),/,g;s,'`pwd`',@srcdir@,g;s,$(subst \,\\,$(subst .,\.,$(real_srcdir))),@srcdir@,g;s,^t .*,t @target@,' < test-parser.tmp > test-parser.new
	rm -f test-parser.tmp
	if diff $(real_srcdir)/test-parser.out test-parser.new; then \
	  echo "GP Parser test succeeded" >&2; \
	  rm -f test-parser.new; \
	else \
	  echo "GP Parser test failed" >&2; \
	fi

dvi: $(DVI)

ps: $(PS)

pdf: $(PDF)

html: $(HTML)

mostlyclean:
	-rm -f gp $(PROGS) $(DVI) $(PS) $(PDF) $(HTML) *.o *.gpi *.gpd core test-parser.tmp test-parser.new needed-options

clean: mostlyclean

distclean: clean
	-rm -f $(SRCDIST) $(BINDIST) Makefile.old Makefile.cfg Makefile.cfg.old

maintainer-clean: distclean
	@echo 'This command is intended for maintainers to use; it'
	@echo 'deletes files that may need special tools to rebuild.'
	-rm -f $(INFO) $(GENERATED_FILES)

extraclean: maintainer-clean

info: $(INFO)

man: $(MAN)

readme: $(real_srcdir)/README

# The Pascal source is not used, but we have to provide any.
# `-x Preprocessed-Pascal /dev/null' works as well, except on mingw.
needed-options:
	$(PC) $(UTILS_WARN) $(CFLAGS) $(PFLAGS) $(PFLAGS1) --print-needed-options "$(real_srcdir)/gp.pas" 2> "$@" || true
	if grep '^[^-]' "$@" > /dev/null; then echo "needed-options: `cat "$@"`" >&2; rm -f "$@"; false; else true; fi

$(real_srcdir)/INSTALL: $(real_srcdir)/gp.texi
	$(MAKEINFO) -DINSTALLONLY --no-header --no-split $< -o $@

$(real_srcdir)/README: $(real_srcdir)/gp.texi
	$(MAKEINFO) -DREADMEONLY --no-header --no-split $< -o $@

$(real_srcdir)/COPYING: $(real_srcdir)/copying.texi
	$(MAKEINFO) -DCOPYINGONLY --no-header --no-split $< -o $@

%.info: %.texi
	cd $(real_srcdir); $(MAKEINFO) --no-split -o $@ $<

%.dvi: %.texi
	cd $(real_srcdir); texi2dvi -b -c $< > /dev/null

%.ps: %.dvi
	dvips -q -o "$@" "$<"

%.pdf: %.texi
	cd $(real_srcdir); texi2pdf -b -c -p $< #> /dev/null

%.html: %.texi
	$(MAKEINFO) --no-split --html $<

$(real_srcdir)/gp-parse.c: gp-parse.l
	$(LEX) $(LFLAGS) -Pmp_yy -o$@ $<

$(real_srcdir)/pascal-lex.c: pascal-lex.l
	$(LEX) $(LFLAGS) -o$@ $<

$(real_srcdir)/%.c $(real_srcdir)/%.h: %.y
	$(BISON) $(BISONFLAGS) -d -o$*.c $<

%.o: %.c cpas.h
	$(CC) -c $(ALL_CFLAGS) $<

cfg-parse.o: $(real_srcdir)/cfg-parse.c cpas.h

gp-parse.o: $(real_srcdir)/gp-parse.c cpas.h lang-options.h
	$(CC) -c $(ALL_CFLAGS) $<

cfg-lex.o: cfg-lex.c $(real_srcdir)/pascal-lex.c cpas.h $(real_srcdir)/cfg-parse.h
	$(CC) -c $(ALL_CFLAGS) $<

%.o: %.pas needed-options
	$(PC) "-DRELEASE_VERSION='$(VERSION)'" -c $(ALL_PFLAGS) `cat needed-options` "$<"

pipes.o: gpc.o pipesc.o

stringutils.o: gpc.o

fileutils.o: gpc.o

cfg.o: gpc.o list.inc cfg-lex.o cfg-parse.o

gp.o: gpc.o md5.o pipes.o stringutils.o fileutils.o $(VERSION_OBJECTS) Makefile

gp$(EXEEXT): $(OBJECTS)
	$(PC) $(ALL_PFLAGS) $(ALL_LDFLAGS) `cat needed-options` -o gp $^

install: install-$(SHELLTYPE)

install-sh: all
	for dir in $(prefix) $(exec_prefix) $(bindir) $(infodir) $(mandir) $(man1dir); do \
	  if [ ! -d $(DESTDIR)$$dir ]; then $(INSTALL_DIR) $(DESTDIR)$$dir; fi; \
	done
	for file in $(PROGS); do \
	  $(INSTALL_PROGRAM) $$file $(DESTDIR)$(bindir)/`basename $$file`; \
	done
	for file in $(INFO); do \
	  $(INSTALL_DATA) $$file $(DESTDIR)$(infodir)/`basename $$file`; \
	done
	for file in $(MAN1); do \
	  $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/`basename $$file`; \
	done

install-command.com: all
	if not exist $(subst /,\,$(DESTDIR)$(prefix)/nul) mkdir $(subst /,\,$(DESTDIR)$(prefix))
	if not exist $(subst /,\,$(DESTDIR)$(exec_prefix)/nul) mkdir $(subst /,\,$(DESTDIR)$(exec_prefix))
	if not exist $(subst /,\,$(DESTDIR)$(bindir)/nul) mkdir $(subst /,\,$(DESTDIR)$(bindir))
	if not exist $(subst /,\,$(DESTDIR)$(infodir)/nul) mkdir $(subst /,\,$(DESTDIR)$(infodir))
	if not exist $(subst /,\,$(DESTDIR)$(mandir)/nul) mkdir $(subst /,\,$(DESTDIR)$(mandir))
	if not exist $(subst /,\,$(DESTDIR)$(man1dir)/nul) mkdir $(subst /,\,$(DESTDIR)$(man1dir))
	copy /b $(subst /,\,$(PROGS)) $(subst /,\,$(DESTDIR)$(bindir))
	copy /b $(subst /,\,$(INFO)) $(subst /,\,$(DESTDIR)$(infodir))
	copy /b $(subst /,\,$(MAN1)) $(subst /,\,$(DESTDIR)$(man1dir))

uninstall:
	for file in $(PROGS); do \
	  rm -f $(DESTDIR)$(bindir)/`basename $$file`; \
	done
	for file in $(INFO); do \
	  rm -f $(DESTDIR)$(infodir)/`basename $$file`; \
	done
	for file in $(MAN1); do \
	  rm -f $(DESTDIR)$(man1dir)/`basename $$file`; \
	done
	for dir in $(bindir) $(infodir) $(man1dir) $(mandir) $(exec_prefix) $(prefix); do \
	  rmdir $(DESTDIR)$$dir 2> /dev/null || true; \
	done

dist: fulldist

fulldist: info man generated-files dist1

mindist: extraclean dist1

dist1:
	-rm -rf "$(NAMEWITHVERSION)"
	cd $(real_srcdir); $(MAKE) distclean
	distfiles=`cd $(real_srcdir); echo *`; \
	mkdir "$(NAMEWITHVERSION)"; \
	for f in $$distfiles; do \
	  $(SD_EXCL) ln $(real_srcdir)/$$f $(NAMEWITHVERSION)/$$f || \
	    { echo copying $$f; \cp -a $(real_srcdir)/$$f $(NAMEWITHVERSION)/$$f; } \
	done
	$(TAR) $(TARSRCFLAGS) $(SRCDIST) $(NAMEWITHVERSION)
	-rm -rf $(NAMEWITHVERSION)

bindist: all $(GENERATED_FILES)
	tmp_base="`pwd`/tmp" && \
	rm -rf "$$tmp_base" && \
	$(MAKE) install DESTDIR="$$tmp_base/" && \
	$(INSTALL_DIR) "$$tmp_base/$(prefix)/share/doc/gp" && \
	$(INSTALL_DATA) "$(real_srcdir)/README" "$$tmp_base/$(prefix)/share/doc/gp/README" && \
	$(INSTALL_DATA) "$(real_srcdir)/COPYING" "$$tmp_base/$(prefix)/share/doc/gp/COPYING" && \
	(cd "$$tmp_base" && $(TAR) $(TARBINFLAGS) ../"$(BINDIST)" *)
	rm -rf tmp
