/* This -*- C -*- file (cpp-Makefile) is run through the C preprocessor
   to produce bash-Makefile which is machine specific.

   If you have Gcc and/or Bison, you might wish to mention that right
   below here.

   Since this is to become a Makefile, blank lines which appear outside
   of comments may not contain a TAB character.
*/

/* **************************************************************** */
/*								    */
/*			Which compiler are you using?		    */
/*								    */
/* **************************************************************** */

/* Define HAVE_GCC if you have the GNU C compiler. */
#define HAVE_GCC 

/* Define HAVE_FIXED_INCLUDES if you are using GCC with the fixed
   header files. */
#if defined (HAVE_GCC) && !defined (HAVE_FIXED_INCLUDES)
#define HAVE_FIXED_INCLUDES 
#endif /* HAVE_GCC && !HAVE_FIXED_INCLUDES */

/* Define HAVE_BISON if you have the GNU replacement for Yacc. */
#define HAVE_BISON

/* Where are you installing the shell? */
#ifdef M_DESTDIR
DESTDIR = M_DESTDIR
#else
DESTDIR = /usr/gnu/bin
#endif /* M_DESTDIR */

/* This includes the appropriate description for the machine that you are
   using (we hope).  If the compilation doesn't work correctly, then you
   will have to edit the file `machines.h' to include a description for the
   machine that your Cpp uniquely identifies this as.  For example, Sun 4's
   are recognized by the Cpp identifier `sparc', Vax is recognized with `vax',
   etc. */
#include "machines.h"

/**/# Here is a rule for making .o files from .c files that does not
/**/# force the type of the machine (like -M_MACHINE) into the flags.
.c.o:
	$(CC) -c $(CFLAGS) $(CPPFLAGS) $*.c

#if defined (HAVE_BISON)
BISON = bison -y
#else
BISON = yacc
#endif

/* If the person blithely typed "make CC=gcc", then make that work. */
#if defined (__GNUC__) && !defined (HAVE_GCC)
#define HAVE_GCC
#endif

#if defined (HAVE_GCC)
#if !defined (HAVE_FIXED_INCLUDES)
/* This is gauranteed to work, even if you have the fixed includes!
   (Unless, of course, you have the fixed include files installed in
   /usr/include.  Then it will break. ) */
CC = gcc -traditional -I/usr/include
#else
CC = gcc
#endif /* !HAVE_FIXED_INCLUDES */
#else
CC = CPP_CC
#endif /* HAVE_GCC */

/**/# Of course, you cannot do this the first time through...
/**/#SHELL=/usr/gnu/bin/bash
SHELL=/bin/sh

#if defined (BASH_MAINTAINER)
MAINTAINER = BASH_MAINTAINER
#else
MAINTAINER = CPP_MAINTAINER
#endif /* BASH_MAINTAINER */

MACHINE = M_MACHINE
OS = M_OS

/**/# You only need this if you are hacking the shell in a location
/**/# that does not do enough backups, or does a poor job.  In that
/**/# case, BACKUP_DIR should be the name of a directory on another
/**/# device (i.e. different than the one you are building the shell
/**/# on), and you should do "make backup" at least once a day.
#if defined (sony)
BACKUP_DIR=/fd
#else
BACKUP_DIR = /usr/gnu/backup-link
#endif /* sony */

/**/# PROFILE_FLAGS is either -pg, to generate profiling info for use
/**/# with gprof, or nothing (the default).
PROFILE_FLAGS=

#if defined (HAVE_SETLINEBUF)
LINEBUF = -D"HAVE_SETLINEBUF"
#endif

#if defined (HAVE_VPRINTF)
VPRINTF = -D"HAVE_VPRINTF"
#endif /* HAVE_VPRINTF */

#if defined (SYSDEP_CFLAGS)
SYSDEP = SYSDEP_CFLAGS
#endif /* SYSDEP_CFLAGS */

SYSTEM_FLAGS = $(LINEBUF) $(VPRINTF) -D$(MACHINE) -D$(OS) $(SYSDEP)
DEBUG_FLAGS = $(PROFILE_FLAGS) -g
LDFLAGS	= $(DEBUG_FLAGS)
CFLAGS	= $(DEBUG_FLAGS) $(SYSTEM_FLAGS)
CPPFLAGS= -I$(LIBSRC)

/**/# These are required for sending bug reports.
SYSTEM_NAME = $(MACHINE)
OS_NAME = $(OS)

/**/# The name of this program.
PROGRAM = bash

/**/# The type of machine Bash is being compiled on.
HOSTTYPE_DECL = -DHOSTTYPE='$(SYSTEM_NAME)'

/**/# The default primary and secondary prompts.
PPROMPT = '"${PROGRAM}\\$$ "'
SPROMPT = '"${PROGRAM}>"'

/**/# The group of configuration flags.  These are for shell.c
CFG_FLAGS = -DMAINTAINER='"$(MAINTAINER)"' -DPPROMPT=$(PPROMPT)\
	    -DSPROMPT=$(SPROMPT) -DOS_NAME='"$(OS_NAME)"' \
	    -DSYSTEM_NAME='$(SYSTEM_NAME)' $(SIGLIST_FLAG)

/**/# The directory which contains the source for malloc.  The name must
/**/# end in a slash, as in "./alloc-files/".
ALLOC_DIR = ./alloc-files/

/**/# Our malloc.
#ifdef USE_GNU_MALLOC
MALLOC = $(ALLOC_DIR)malloc.o
MALLOC_FLAGS = -Drcheck -Dbotch=programming_error
#endif /* USE_GNU_MALLOC */

#if !defined (HAVE_ALLOCA)
ALLOCA = $(ALLOC_DIR)alloca.o

#if defined (ALLOCA_ASM)
ALLOCA_SOURCE = $(ALLOC_DIR)ALLOCA_ASM
#else
ALLOCA_SOURCE = $(ALLOC_DIR)alloca.c
#endif /* ALLOCA_ASM */

#endif /* !HAVE_ALLOCA */


ALLOC_HEADERS = $(ALLOC_DIR)getpagesize.h
ALLOC_FILES = $(ALLOC_DIR)malloc.c $(ALLOC_DIR)alloca.c \
	      $(ALLOC_DIR)i386-alloca.s $(ALLOC_DIR)x386-alloca.s

/**/# If your system does not have sys_siglist, then define SIGLIST
/**/# as siglist.o
#if !defined (HAVE_SIGLIST)
SIGLIST = siglist.o
SIGLIST_FLAG=-DINITIALIZE_SIGLIST
#endif /* HAVE_SIGLIST */

RM = rm -f
AR = ar
RANLIB = ranlib

/**/# Support libraries required.  Termcap and Readline.
/**/# We would like to use the GNU termcap library.
#if defined (USE_GNU_TERMCAP)
#define TERMSRC_DEP
TERMCAP = $(TLIBSRC)/libtermcap.a
TERMLIB = -L$(TLIBSRC) -ltermcap
#else
TERMLIB = -ltermcap
#endif

READLINE= ./readline/libreadline.a

/**/# Locally required libraries.
#if defined (REQUIRED_LIBRARIES)
LOCAL_LIBS = REQUIRED_LIBRARIES
#endif

/**/# The source code for the support libraries.
LIBSRC = ./
HISTORY_SOURCE	= $(LIBSRC)readline/history.c $(LIBSRC)readline/history.h
RLIBSRC = $(LIBSRC)readline/
READLINE_SOURCE	= $(RLIBSRC)readline.c $(RLIBSRC)readline.h\
		  $(RLIBSRC)chardefs.h $(RLIBSRC)keymaps.h\
		  $(RLIBSRC)funmap.c $(RLIBSRC)emacs_keymap.c\
		  $(RLIBSRC)vi_keymap.c $(RLIBSRC)keymaps.c\
		  $(RLIBSRC)vi_mode.c $(HISTORY_SOURCE)
#if defined (USE_GNU_TERMCAP)
TLIBSRC = $(LIBSRC)termcap/
TERMCAP_SOURCE	= $(TLIBSRC)termcap.c
TERMCAP_DOC	= $(TLIBSRC)termcap.texinfo
#endif

READLINE_DOC	= $(RLIBSRC)readline.texinfo\
		  $(RLIBSRC)inc-readline.texinfo
HISTORY_DOC	= $(RLIBSRC)history.texinfo\
		  $(RLIBSRC)inc-history.texinfo

LIBRARY_SOURCE	= $(READLINE_SOURCE) $(TERMCAP_SOURCE)
LIBRARY_DOC	= $(READLINE_DOC) $(HISTORY_DOC) $(TERMCAP_DOC)
LIBRARY_SUPPORT	= $(RLIBSRC)Makefile $(RLIBSRC)ChangeLog
LIBRARY_TAR	= $(LIBRARY_SOURCE) $(LIBRARY_DOC) $(LIBRARY_SUPPORT)

/**/# The order is important.  Most dependent first.
LIBRARIES = $(READLINE) $(TERMLIB)
#ifdef TERMSRC_DEP
LIBDEP = $(READLINE) $(TERMLIB)
#else
LIBDEP = $(READLINE)
#endif

CSOURCES = shell.c parse.y general.c make_cmd.c print_cmd.c\
	   dispose_cmd.c execute_cmd.c variables.c builtins.c\
	   copy_cmd.c flags.c subst.c glob.c hash.c mailcheck.c\
	   test.c trap.c jobs.c nojobs.c $(ALLOC_FILES) braces.c\
	   unwind_prot.c siglist.c bashline.c ulimit.c version.c

HSOURCES = shell.h flags.h trap.h hash.h jobs.h builtins.h alias.c \
	   alias.h general.h variables.h config.h $(ALLOC_HEADERS) \
	   version.h quit.h ndir.h machines.h

SOURCES  = $(CSOURCES) $(HSOURCES)

OBJECTS  = shell.o y.tab.o general.o make_cmd.o print_cmd.o\
	   dispose_cmd.o execute_cmd.o variables.o builtins.o copy_cmd.o\
	   flags.o jobs.o subst.o glob.o hash.o mailcheck.o test.o\
	   trap.o alias.o $(MALLOC) $(ALLOCA) braces.o unwind_prot.o\
	   $(SIGLIST) bashline.o ulimit.o version.o

/**/# Documentation for the shell.
DOCDIR = ./documentation/
BASHDOCS = $(DOCDIR)*.texinfo $(DOCDIR)texinfo.tex README FEATURES INSTALL
DOCUMENTATION = $(BASHDOCS) $(LIBRARY_DOC)

/**/# Some example files
/* This has to be written funny to avoid looking like a comment starter. */
EXAMPLES = examples/[a-zA-Z]*

SUPPORT = COPYING Makefile cpp-Makefile makeargs.sh newversion.c make-tarfile \
	mail-shell inform ChangeLog .distribution $(EXAMPLES)

/**/# BAGGAGE consists of things that you want to keep with the shell for some
/**/# reason, but do not actually use; old source code, etc.
BAGGAGE = longest_signal_desc.c

/**/# Things that the world at large needs.
THINGS_TO_TAR = $(SOURCES) $(LIBRARY_TAR) $(BASHDOCS) $(SUPPORT) $(BAGGAGE)

/**/# Things that maintainers need, but no one else.
MAINTAINENCE = shell-mail bash-distribution-list

$(PROGRAM):	.build $(OBJECTS) $(LIBDEP) bash-Makefile
	$(CC) $(LDFLAGS) -o $(PROGRAM) $(OBJECTS) \
		$(LIBRARIES) $(LOCAL_LIBS) $(TERMLIB)
	$(RM) -f .make

.build:		.make newversion.aux
	if ./newversion.aux -build; then mv -f newversion.h version.h; fi

.make:
	@echo
	@echo "   ***************************************************"
	@echo "   *                                                 *"
	@echo "   *   Making Bash for a $(MACHINE) running $(OS)."
	@echo "   *                                                 *"
	@echo "   ***************************************************"
	@echo
	@echo "$(PROGRAM) last made for a $(MACHINE) running $(OS)" >.machine
	touch .make

version.h:	newversion.aux
	if ./newversion.aux -build; then mv -f newversion.h version.h; fi

shell.h:	general.h variables.h config.h
		touch shell.h

y.tab.c:	parse.y shell.h
		-if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi
		$(BISON) -d parse.y
		-if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; fi

$(READLINE):	$(READLINE_SOURCE)
		(cd $(RLIBSRC); $(MAKE) $(MFLAGS) CC='$(CC)' CFLAGS='$(CFLAGS)')

#if defined (USE_GNU_TERMCAP)
$(TERMCAP):	$(TERMCAP_SOURCE)
		(cd $(TLIBSRC); $(MAKE) $(MFLAGS) CC='$(CC)'\
			CFLAGS='$(CFLAGS) -I.')
#endif

shell.o:	shell.h flags.h shell.c
		$(CC) $(CFG_FLAGS) $(CFLAGS) $(CPPFLAGS) -c shell.c

braces.o:	braces.c
		$(CC) $(CFLAGS) -DSHELL -c braces.c

keymaps.c:	emacs_keymap.c vi_keymap.c
		touch keymaps.c

#if defined (USE_GNU_MALLOC)
$(MALLOC):	$(ALLOC_FILES)
		$(CC) -I$(ALLOC_DIR) $(CFLAGS) $(MALLOC_FLAGS) -c $*.c
#if !defined (__GNUC__)
		@-mv `basename $*`.o $(MALLOC) 2>/dev/null
#endif
#endif /* USE_GNU_MALLOC */

#if !defined (HAVE_ALLOCA)
#if !defined (__GNUC__)
$(ALLOCA):	$(ALLOCA_SOURCE)
		$(CC) -I$(ALLOC_DIR) $(CFLAGS) -c $(ALLOCA_SOURCE)
		@-mv `basename $*`.o $(ALLOCA) 2>&1 >/dev/null
#else /* GCC */
$(ALLOCA):	$(ALLOCA_SOURCE)
		$(CC) -I$(ALLOC_DIR) $(CFLAGS) -o $(ALLOCA) -c $(ALLOCA_SOURCE)
#endif
#endif /* HAVE_ALLOCA */

bashline.o:	bashline.c config.h $(RLIBSRC)readline.h variables.h builtins.h
jobs.o:		jobs.c nojobs.c jobs.h config.h
version.o:	version.h version.c .build
general.o:	general.c shell.h
y.tab.h:	y.tab.c
alias.o:	alias.h alias.c
subst.o:	subst.c shell.h
make_cmd.o:	shell.h config.h make_cmd.c
print_cmd.o:	shell.h y.tab.h print_cmd.c
execute_cmd.o:	shell.h y.tab.h builtins.h flags.h config.h execute_cmd.c
dispose_cmd.o:	shell.h dispose_cmd.c
copy_cmd.o:	shell.h copy_cmd.c
builtins.o:	shell.h flags.h trap.h builtins.h jobs.h config.h builtins.c
flags.o:	flags.h flags.c config.h
hash.o:		hash.h hash.c
trap.o:		shell.h trap.h config.h trap.c
variables.o:	variables.h flags.h variables.c
	$(CC) -c $(CFLAGS) $(HOSTTYPE_DECL) variables.c

$(PROGRAM).tar: $(THINGS_TO_TAR) .distribution
	make-tarfile $(PROGRAM) `cat .distribution` $(THINGS_TO_TAR)

$(PROGRAM).tar.Z:	$(PROGRAM).tar
		compress -f $(PROGRAM).tar

carryall:	$(THINGS_TO_TAR) .distribution $(MAINTAINENCE)
		make-tarfile $(PROGRAM) `cat .distribution` \
		 $(THINGS_TO_TAR) $(MAINTAINENCE)
		@echo mv $(PROGRAM).tar carryall-`cat .distribution`.tar
		@mv $(PROGRAM).tar carryall-`cat .distribution`.tar
		@echo compress -f carryall-`cat .distribution`.tar
		@compress -f carryall-`cat .distribution`.tar

clone:
	mkdir clone; \
	(cd clone; for i in $(THINGS_TO_TAR); \
	  do file=`basename $$i`; \
	   dir=`echo $$i | sed "s/$$file\$$//" | sed 's@\(.*\)/\$$@\1@'`; \
	   if [ "$$dir" = "" ]; then dir="."; fi; \
	   if [ "$$dir" != "." ]; then \
	      if [ ! -d "$$dir" ]; then mkdir "$$dir"; fi; \
	      if [ "$$file" = Makefile ]; \
		then cp ../$$i $$i; \
	       else ln -s ../../$$i $$i; \
	      fi; \
	   else if [ "$$file" = Makefile ]; then cp ../$$i $$i; \
		 else ln -s ../$$i $$i; fi; \
	   fi; \
	  done)

/**/# Make "backup" be a link to a directory on another device.
#if defined (sony)
backup:		$(PROGRAM).tar.Z
		tar -cf /dev/rfd0a $(PROGRAM).tar.Z
#else
backup:		$(PROGRAM).tar.Z
		if [ ! -f backup ]; then ln -s $(BACKUP_DIR) backup; fi
		cp $(PROGRAM).tar.Z backup/$(PROGRAM).tar.Z
#endif /* sony */

install:	$(PROGRAM)
		if [ -f $(DESTDIR)/$(PROGRAM) ]; \
		then mv $(DESTDIR)/$(PROGRAM) $(DESTDIR)/$(PROGRAM).old; \
		fi
		cp $(PROGRAM) $(DESTDIR)/$(PROGRAM)
		rm -f installed-$(PROGRAM)
		ln -s $(DESTDIR)/$(PROGRAM) installed-$(PROGRAM)

mailable:	distribution
		/bin/rm -rf uuencoded
		mkdir uuencoded
		$(SHELL) -c 'f=$(PROGRAM)-`cat .distribution`.tar.Z;uuencode $$f $$f | split -800 - uuencoded/$$f.uu.'

.distribution:	newversion.aux
		./newversion.aux -dist `$(PROGRAM) -c 'echo $$BASH_VERSION'`

distribution:	$(PROGRAM).tar.Z .distribution
		@echo cp $(PROGRAM).tar.Z $(PROGRAM)-`cat .distribution`.tar.Z
		@cp $(PROGRAM).tar.Z $(PROGRAM)-`cat .distribution`.tar.Z

newversion.aux:	newversion.c
		$(CC) -g -o newversion.aux newversion.c 

newversion:	newversion.aux
		rm -f .build
		./newversion.aux -dist
		mv -f newversion.h version.h
		make $(PROGRAM)

documentation:
		(cd $(DOCDIR); makeinfo *.texinfo)

tags:		$(SOURCES) $(LIBRARY_SOURCE)
		etags $(SOURCES) $(LIBRARY_SOURCE)

clean:
		$(RM) $(OBJECTS) $(PROGRAM) y.tab.c y.tab.h newversion.aux
		$(RM) .make bash-Makefile
		(cd $(RLIBSRC); $(RM) *.o *.a)

dist-clean:
	$(RM) $(OBJECTS) $(PROGRAM) y.tab.c newversion.aux
	$(RM) -rf uuencoded
