# Makefile for etsh
#
# @(#)$Id: Makefile,v 1.6 2018/12/27 04:26:45 jneitzel Exp $
#
# Begin CONFIGURATION
#
# See the INSTALL file for build and install instructions.
#

#
# required includes
include	./Makefile.config
include	./mkconfig.tmp
#

#
# Choose where and how to install the binaries and manual pages.
#
DESTDIR?=
PREFIX?=	/usr/local
BINDIR?=	$(PREFIX)/bin
LIBEXECDIR?=	$(PREFIX)/libexec/$(ETSH_VERSION)
LIBEXECDIRETSH?=$(PREFIX)/libexec/$(ETSH_VERSION)/etsh
LIBEXECDIRTSH?=	$(PREFIX)/libexec/$(ETSH_VERSION)/tsh
DOCDIR?=	$(PREFIX)/share/doc/etsh
EXPDIR?=	$(PREFIX)/share/examples/etsh
MANDIR?=	$(PREFIX)/man/man1
SYSCONFDIR?=	$(PREFIX)/etc
#BINGRP=		-g bin
BINMODE=	-m 0555
#MANGRP=		-g bin
MANMODE=	-m 0444

# Project documentation files to be installed into DOCDIR
DOCFILES?=README PROJECT NOTES LICENSE DEDICATIONS AUTHORS

# Build utilities (SHELL must be POSIX-compliant)
CC?=
INSTALL?=/usr/bin/install
SHELL=   /bin/sh

# Preprocessor, compiler, and linker flags
#
#	If the compiler gives errors about any of flags specified
#	by `OPTIONS' or `WARNINGS' below, comment the appropriate
#	line(s) with a `#' character to fix the compiler errors.
#	Then, try to build again by doing a `make clean ; make'.
#
#CPPFLAGS=
OPTIONS=	-std=c99 -pedantic
#OPTIONS+=	-fstack-protector-strong
WARNINGS=	-Wall -Wextra
#WARNINGS+=	-Wstack-protector
#CFLAGS+=	-g
CFLAGS+=	$(OPTIONS) $(WARNINGS)
#LDFLAGS+=	-static

#
# End CONFIGURATION
#
# !!! ================= Developer stuff below... ================= !!!
#

#
# Adjust CFLAGS for OSXCFLAGS and LDFLAGS for OSXLDFLAGS if needed.
#
OSXCFLAGS?=
CFLAGS+=	$(OSXCFLAGS)
OSXLDFLAGS?=
LDFLAGS+=	$(OSXLDFLAGS)

ETSH=	etsh
TSH=	tsh glob
UBIN=	fd2 goto if
GHEAD=	config.h defs.h
ERRSRC=	sh_err.h sh_err.c
LIBSRC=	lib.h lib.c
PEXSRC=	pexec.h pexec.c
SIGSRC=	sasignal.h sasignal.c
INTSRC=	strtoint.h strtoint.c
OBJ=	sh_err.o fd2.o glob.o goto.o if.o lib.o etsh.o pexec.o sasignal.o tsh.o strtoint.o util.o v.o
ETSHMAN=etsh.1.out
TSHMAN=	tsh.1.out glob.1.out
UMAN=	fd2.1.out goto.1.out if.1.out
MANALL=	$(ETSHMAN) $(TSHMAN) $(UMAN)
SEDSUB=	-e 's|@ETSH_DATE@|$(ETSH_DATE)|' \
	-e 's|@ETSH_VERSION@|$(ETSH_VERSION)|' \
	-e 's|@LIBEXECDIRETSH@|$(LIBEXECDIRETSH)|' \
	-e 's|@LIBEXECDIRTSH@|$(LIBEXECDIRTSH)|' \
	-e 's|@EBN@|$(EBN)|g' -e 's|@EBN1@|$(EBN1)|' -e 's|@EBNC@|$(EBNC)|' \
	-e 's|@TBN@|$(TBN)|' -e 's|@TBN1@|$(TBN1)|' -e 's|@TBNC@|$(TBNC)|' \
	-e 's|@SYSCONFDIR@|$(SYSCONFDIR)|'

DEFS=	-DETSH_BINARY_NAME='"$(EBN)"' -DETSH_VERSION='"$(ETSH_VERSION)"' -DETSH_URL='"$(ETSH_URL)"' -DETSH_EMAIL='"$(ETSH_EMAIL)"' -DLIBEXECDIRETSH='"$(LIBEXECDIRETSH)"' -DLIBEXECDIRTSH='"$(LIBEXECDIRTSH)"' -DSYSCONFDIR='"$(SYSCONFDIR)"' -DTSH_BINARY_NAME='"$(TBN)"'

.SUFFIXES: .1 .1.out .c .o

.1.1.out:
	sed $(SEDSUB) <$< >$@

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

#
# Build targets
#
all: etshall tshall

etshall: $(ETSH) $(ETSHMAN) $(UMAN)

tshall: $(TSH) $(TSHMAN) utils

utils: $(UBIN) $(UMAN)

man: $(MANALL)

etsh: sh.h v.c etsh.c util.c $(GHEAD) $(ERRSRC) $(LIBSRC) $(PEXSRC) $(SIGSRC) $(INTSRC)
	@$(MAKE) $@bin

tsh: sh.h v.c tsh.c $(GHEAD) $(ERRSRC) $(PEXSRC) $(SIGSRC)
	@$(MAKE) $@bin

glob: v.c glob.c $(GHEAD) $(ERRSRC) $(PEXSRC)
	@$(MAKE) $@bin

if: v.c if.c $(GHEAD) $(ERRSRC) $(PEXSRC) $(SIGSRC) $(INTSRC)
	@$(MAKE) $@bin

goto: v.c goto.c $(GHEAD) $(ERRSRC)
	@$(MAKE) $@bin

fd2: fd2.c $(GHEAD) $(ERRSRC) $(PEXSRC)
	@$(MAKE) $@bin

$(OBJ)                                                               : $(GHEAD)
fd2.o glob.o goto.o if.o lib.o etsh.o pexec.o tsh.o util.o strtoint.o: sh_err.h
fd2.o glob.o if.o etsh.o tsh.o util.o                                : pexec.h
if.o etsh.o tsh.o                                                    : sasignal.h
if.o etsh.o util.o                                                   : strtoint.h
etsh.o lib.o tsh.o util.o                                            : sh.h
sh_err.o                                                             : $(ERRSRC)
lib.o                                                                : $(LIBSRC)
pexec.o                                                              : $(PEXSRC)
sasignal.o                                                           : $(SIGSRC)
strtoint.o                                                           : $(INTSRC)

config.h: Makefile Makefile.config configure mkconfig mkconfig.tmp
	@if test ! -e config.h ; then echo 'Please run ./configure first.' >&2 ; exit 1 ; fi
	@$(SHELL) ./mkconfig "$(EBN)" "$(TBN)"

etshbin: v.o etsh.o sh_err.o lib.o util.o pexec.o sasignal.o strtoint.o
	$(CC) $(LDFLAGS) -o etsh v.o etsh.o sh_err.o lib.o util.o pexec.o sasignal.o strtoint.o $(LIBS)

tshbin: v.o tsh.o sh_err.o pexec.o sasignal.o
	$(CC) $(LDFLAGS) -o tsh v.o tsh.o sh_err.o pexec.o sasignal.o $(LIBS)

globbin: v.o glob.o sh_err.o pexec.o
	$(CC) $(LDFLAGS) -o glob v.o glob.o sh_err.o pexec.o $(LIBS)

ifbin: v.o if.o sh_err.o pexec.o sasignal.o strtoint.o
	$(CC) $(LDFLAGS) -o if v.o if.o sh_err.o pexec.o sasignal.o strtoint.o $(LIBS)

gotobin: v.o goto.o sh_err.o
	$(CC) $(LDFLAGS) -o goto v.o goto.o sh_err.o $(LIBS)

fd2bin: fd2.o sh_err.o pexec.o
	$(CC) $(LDFLAGS) -o fd2 fd2.o sh_err.o pexec.o $(LIBS)

$(MANALL): config.h

#
# ready examples for installation via the install-exp target
#
exp: config.h
	cd examples && $(SHELL) ready_rc_files "$(EBN)" "$(PREFIX)" "$(BINDIR)" "$(SYSCONFDIR)"

#
# Test targets
#
# NOTE: $(.CURDIR) for BSD make || $(CURDIR) for GNU make
#
check-pre: $(ETSH) clean-tsh
	@if test X$(.CURDIR) != X ; then $(MAKE) LIBEXECDIRTSH=$(.CURDIR) tshall ; else $(MAKE) LIBEXECDIRTSH=$(CURDIR) tshall ; fi >/dev/null 2>&1

check: check-pre
	@( cd tests && ../etsh run etsh tsh )
	@$(MAKE) check-post

check-etshall: check-etsh
check-etsh: $(ETSH)
	@( cd tests && ../etsh run etsh )

check-tshall: check-tsh
check-tsh: check-pre
	@( cd tests && ../etsh run tsh )
	@$(MAKE) check-post

check-newlog: check-pre
	@( cd tests && ../etsh run -newlog etsh tsh )
	@$(MAKE) check-post

check-post: $(ETSH) clean-tsh
	@$(MAKE) tshall >/dev/null 2>&1

#
# Install targets
#
DESTBINDIR=		$(DESTDIR)$(BINDIR)
DESTLIBEXECDIR=		$(DESTDIR)$(LIBEXECDIR)
DESTLIBEXECDIRETSH=	$(DESTDIR)$(LIBEXECDIRETSH)
DESTLIBEXECDIRTSH=	$(DESTDIR)$(LIBEXECDIRTSH)
DESTDOCDIR=		$(DESTDIR)$(DOCDIR)
DESTEXPDIR=		$(DESTDIR)$(EXPDIR)
DESTMANDIR=		$(DESTDIR)$(MANDIR)
install: install-etshall install-tshall

install-etshall: etshall install-etsh install-uman

install-tshall: tshall install-tsh install-utils

install-utils: install-ubin install-uman

install-etsh: $(ETSH) $(ETSHMAN) install-dest install-destlibexecetsh
	$(INSTALL) -c -s $(BINGRP) $(BINMODE) etsh       $(DESTBINDIR)/$(EBN)
	$(INSTALL) -c    $(MANGRP) $(MANMODE) etsh.1.out $(DESTMANDIR)/$(EBN).1

install-tsh: $(TSH) $(TSHMAN) install-dest install-destlibexectsh
	$(INSTALL) -c -s $(BINGRP) $(BINMODE) tsh        $(DESTBINDIR)/$(TBN)
	$(INSTALL) -c    $(MANGRP) $(MANMODE) tsh.1.out  $(DESTMANDIR)/$(TBN).1
	$(INSTALL) -c -s $(BINGRP) $(BINMODE) glob       $(DESTLIBEXECDIRTSH)
	$(INSTALL) -c    $(MANGRP) $(MANMODE) glob.1.out $(DESTMANDIR)/glob.1

install-ubin: $(UBIN) install-dest install-destlibexec
	$(INSTALL) -c -s $(BINGRP) $(BINMODE) fd2        $(DESTLIBEXECDIRTSH)
	$(INSTALL) -c -s $(BINGRP) $(BINMODE) goto       $(DESTLIBEXECDIRTSH)
	$(INSTALL) -c -s $(BINGRP) $(BINMODE) if         $(DESTLIBEXECDIRTSH)

install-uman: $(UMAN) install-dest
	$(INSTALL) -c    $(MANGRP) $(MANMODE) fd2.1.out  $(DESTMANDIR)/fd2.1
	$(INSTALL) -c    $(MANGRP) $(MANMODE) goto.1.out $(DESTMANDIR)/goto.1
	$(INSTALL) -c    $(MANGRP) $(MANMODE) if.1.out   $(DESTMANDIR)/if.1

install-dest:
	test -d $(DESTBINDIR) || { umask 0022 && mkdir -p $(DESTBINDIR) ; }
	test -d $(DESTMANDIR) || { umask 0022 && mkdir -p $(DESTMANDIR) ; }

install-destlibexec:
	test -d $(DESTLIBEXECDIR) || { umask 0022 && mkdir -p $(DESTLIBEXECDIR) ; }
	$(INSTALL) -c $(MANGRP) $(MANMODE) README.libexec $(DESTLIBEXECDIR)/README

install-destlibexecetsh: install-destlibexec
	test -d $(DESTLIBEXECDIRETSH) || { umask 0022 && mkdir -p $(DESTLIBEXECDIRETSH) ; }
	$(INSTALL) -c $(MANGRP) $(MANMODE) libexec.etsh/README $(DESTLIBEXECDIRETSH)
	$(INSTALL) -c $(MANGRP) $(MANMODE) libexec.etsh/SetP $(DESTLIBEXECDIRETSH)
	$(INSTALL) -c $(MANGRP) $(MANMODE) libexec.etsh/SetTandCTTY $(DESTLIBEXECDIRETSH)
	$(INSTALL) -c $(MANGRP) $(MANMODE) libexec.etsh/SetV $(DESTLIBEXECDIRETSH)
	$(INSTALL) -c $(BINGRP) $(BINMODE) libexec.etsh/etshdir $(DESTLIBEXECDIRETSH)
	$(INSTALL) -c $(BINGRP) $(BINMODE) libexec.etsh/history $(DESTLIBEXECDIRETSH)
	$(INSTALL) -c $(MANGRP) $(MANMODE) libexec.etsh/history.help $(DESTLIBEXECDIRETSH)
	@sed 's,@PREFIX@,$(PREFIX), ; s,@LIBEXECDIRETSH@,$(LIBEXECDIRETSH), ; s,@ETSH_VERSION@,$(ETSH_VERSION),' libexec.etsh/pev >libexec.etsh/pev.out
	$(INSTALL) -c $(BINGRP) $(BINMODE) libexec.etsh/pev.out $(DESTLIBEXECDIRETSH)/pev

install-destlibexectsh: install-destlibexec
	test -d $(DESTLIBEXECDIRTSH) || { umask 0022 && mkdir -p $(DESTLIBEXECDIRTSH) ; }
	$(INSTALL) -c $(MANGRP) $(MANMODE) README.libexec.tsh $(DESTLIBEXECDIRTSH)/README

#
# Install DOCFILES into DESTDOCDIR.
#
install-doc:
	test -d $(DESTDOCDIR) || { umask 0022 && mkdir -p    $(DESTDOCDIR) ; }
	$(INSTALL) -c    $(MANGRP) $(MANMODE) $(DOCFILES) $(DESTDOCDIR)

#
# Notice that doing a:
#
#	make [variable=value ...] EXPDIR=value install-exp
#
# is a simple way to install your example .etsh* and etsh* files into
# a directory represented by the value you use for EXPDIR, wherever
# you might want it to be.
#
install-exp: exp
	test -d $(DESTEXPDIR) || { umask 0022 && mkdir -p $(DESTEXPDIR) ; }
	$(INSTALL) -c    $(MANGRP) $(MANMODE) exp/.$(EBN)* exp/$(EBN)* $(DESTEXPDIR)

#
# Cleanup targets
#
clean-tsh: clean-obj
	@rm -f $(TSH) $(UBIN)
clean-man:
	@rm -f $(MANALL)
clean-obj:
	@rm -f $(OBJ)
clean: clean-tsh clean-man clean-obj
	@rm -rf exp
	@rm -f libexec.etsh/pev.out
	@rm -f $(ETSH) mkconfig.tmp config.h
	@touch mkconfig.tmp
