#========================================================================
# This is the toplevel Makefile for the wulfware project.  It has
# some very specialized targets:
#
# make          alone should build the entire application
# make install  should build and install the entire application
# make installweb installs to website for download
# make installrepo installs to yum repo
#
# make tgz      makes $(TGZ) of entire tree for standalone or rpm build
# make rpm      makes $(RPM) packages built by wulfware.spec
# make svn      does a svn commit and creates the timestamp $(SVNTIME)
# make sync     does a svn commit and syncs to list of svn-tree hosts
#
# make clean    cleans the source directories
#========================================================================
# This is the project name
PROJECT = wulfware
# These are the toplevel packages built by this project
LIBRARY = libwulf
LIBTIME = libwulf.time
PROGRAM0 = xmlsysd
P0TIME = xmlsysd.time
PROGRAM1 = wulfstat
P1TIME = wulfstat.time
PROGRAM2 = wulflogger
P2TIME = wulflogger.time
PROGRAM3 = wulf2html
P3TIME = wulf2html.time
MANUALS = wulfware-doc
MANTIME = wulfware-doc.time

#========================================================================
# This is essential.  The rpmbuild overrides it, but we have to make
# build "work" when executed only in the source tree directory itself.
# This isn't easy, since the dependences are more than a bit scattered.
# We therefore point to the directory one level up, where we should
# find a ./lib, ./include, ./share and ./bin directory tree from which
# the various wulfware files will actually be assembled into an rpm
# with PREFIX=/usr (for example).
#========================================================================
BUILDROOT=../buildroot
PREFIX=$(BUILDROOT)/usr

# The destination on a remote webserver, used as:
#    $(HOME)/public_html/$(WDIR)
# on that server, and the name of an ssh-accessible login server
# that contains the public_html path.
WLOGIN = login.phy.duke.edu
WDIR = Beowulf

SVNTREE = $(HOME)/Src/svn-tree
SVNPATH = $(SVNTREE)/$(PROJECT)
SVNTIME = $(PROJECT:=.svn.time)

#========================================================================
# This is revision information that MUST be set here and ONLY here.  
# It will automagically set the related information in $(SPEC) and the
# subsidiary Makefiles in the source subdirectories.
#========================================================================
VERSION_MAJOR=2
VERSION_MINOR=5.0
RELEASE=1

ABS = $(PROJECT).abs
PHP = $(PROJECT).php

# RPM/tarball target objects.  We need rules for all of these.
PROJECTDIR = $(PROJECT)-$(VERSION_MAJOR).$(VERSION_MINOR)
TAR = $(PROJECTDIR).tar
TGZ = $(PROJECTDIR).tgz
SPEC = $(PROJECT).spec

#========================================================================
# List of variants one can make.  all is the default.  We always
# presume the simplest of dependencies and remake if includes change
# for example.
#========================================================================
all: $(LIBTIME)

# This is not, actually, a particularly useful toplevel target.  To
# work correctly it also would require a full parsing of all
# lower level dependencies.  I'm leaving it in for the moment just
# to have a default target at the toplevel that CAN be used to test.
$(LIBTIME):
	(cd $(LIBRARY); \
	make)

$(P0TIME):
	(cd $(PROGRAM0); \
	make)

$(P1TIME):
	(cd $(PROGRAM1); \
	make)

$(P2TIME):
	(cd $(PROGRAM2); \
	make)

$(P3TIME):
	(cd $(PROGRAM3); \
	make)

$(SPEC): Makefile
	# Version information is set ONLY in the toplevel Makefile.
	cat $(SPEC) | \
	sed -e 's/^\(Version:\) \(.*\)/\1 $(VERSION_MAJOR).$(VERSION_MINOR)/' \
	    -e 's/^\(Release:\) \(.*\)/\1 $(RELEASE)/' > /tmp/$(SPEC).$$
	mv /tmp/$(SPEC).$$ $(SPEC)
	# While we're at it, update program and library Makefiles
	cat $(LIBRARY)/Makefile | \
	sed -e 's/^\(VERSION_MAJOR=\)\(.*\)/\1$(VERSION_MAJOR)/' \
	    -e 's/^\(VERSION_MINOR=\)\(.*\)/\1$(VERSION_MINOR)/' \
	    -e 's/^\(RELEASE=\)\(.*\)/\1$(RELEASE)/' > /tmp/Makefile.$$
	mv /tmp/Makefile.$$ $(LIBRARY)/Makefile
	cat $(PROGRAM0)/Makefile | \
	sed -e 's/^\(VERSION_MAJOR=\)\(.*\)/\1$(VERSION_MAJOR)/' \
	    -e 's/^\(VERSION_MINOR=\)\(.*\)/\1$(VERSION_MINOR)/' \
	    -e 's/^\(RELEASE=\)\(.*\)/\1$(RELEASE)/' > /tmp/Makefile.$$
	mv /tmp/Makefile.$$ $(PROGRAM0)/Makefile
	cat $(PROGRAM1)/Makefile | \
	sed -e 's/^\(VERSION_MAJOR=\)\(.*\)/\1$(VERSION_MAJOR)/' \
	    -e 's/^\(VERSION_MINOR=\)\(.*\)/\1$(VERSION_MINOR)/' \
	    -e 's/^\(RELEASE=\)\(.*\)/\1$(RELEASE)/' > /tmp/Makefile.$$
	mv /tmp/Makefile.$$ $(PROGRAM1)/Makefile
	cat $(PROGRAM2)/Makefile | \
	sed -e 's/^\(VERSION_MAJOR=\)\(.*\)/\1$(VERSION_MAJOR)/' \
	    -e 's/^\(VERSION_MINOR=\)\(.*\)/\1$(VERSION_MINOR)/' \
	    -e 's/^\(RELEASE=\)\(.*\)/\1$(RELEASE)/' > /tmp/Makefile.$$
	mv /tmp/Makefile.$$ $(PROGRAM2)/Makefile
	cat $(PROGRAM3)/Makefile | \
	sed -e 's/^\(VERSION_MAJOR=\)\(.*\)/\1$(VERSION_MAJOR)/' \
	    -e 's/^\(VERSION_MINOR=\)\(.*\)/\1$(VERSION_MINOR)/' \
	    -e 's/^\(RELEASE=\)\(.*\)/\1$(RELEASE)/' > /tmp/Makefile.$$
	mv /tmp/Makefile.$$ $(PROGRAM3)/Makefile

$(ABS): Makefile
	cat $(ABS) | \
	sed -e 's/^\(<center><H2>Version \)\(.*\)/\1$(VERSION_MAJOR).$(VERSION_MINOR)<\/H2><\/center>/' > /tmp/$(ABS).$$
	mv /tmp/$(ABS).$$ $(ABS)

#========================================================================
# This is a required target for both its own sake and to support the
# rpm build.  It has to run unconditionally when called.  Note that we
# make PRECISELY what we need in terms of the source directories,
# excluding all restricted material and irrelevant data.
#========================================================================
tgz: Makefile COPYING Copyright NOTES README $(SPEC) $(ABS) $(PHP)
	( rm -rf $(TAR) $(TGZ) $(PROJECTDIR); \
	mkdir -p $(PROJECTDIR); \
	cd $(LIBRARY); \
	make clean; \
	cd ..; \
	cp -r $(LIBRARY) $(PROJECTDIR); \
	cd $(PROGRAM0); \
	make clean; \
	cd ..; \
	cp -r $(PROGRAM0) $(PROJECTDIR); \
	cd $(PROGRAM1); \
	make clean; \
	cd ..; \
	cp -r $(PROGRAM1) $(PROJECTDIR); \
	cd $(PROGRAM2); \
	make clean; \
	cd ..; \
	cp -r $(PROGRAM2) $(PROJECTDIR); \
	cd $(PROGRAM3); \
	make clean; \
	cd ..; \
	cp -r $(PROGRAM3) $(PROJECTDIR); \
	cp -r include $(PROJECTDIR); \
	mkdir -p $(PROJECTDIR)/lib; \
	cp $(SPEC) $(PROJECTDIR); \
	cp $(ABS) $(PROJECTDIR); \
	cp $(PHP) $(PROJECTDIR); \
	cp Makefile $(PROJECTDIR); \
	cp Copyright $(PROJECTDIR); \
	cp COPYING $(PROJECTDIR); \
	cp README $(PROJECTDIR); \
	cp NOTES $(PROJECTDIR); \
	tar -cvpf $(TAR) \
            --exclude=.svn \
	    --exclude=Cruft \
	    --exclude=Exclude \
            --exclude=*.tar \
            --exclude=*.tgz \
            --exclude=*.rpm \
            ./$(PROJECTDIR); \
	gzip $(TAR); \
	mv $(TAR).gz $(TGZ); \
	rm -rf $(PROJECTDIR))

#========================================================================
# rpm target special stuff
#
# To work in userspace, add the following:
# %_topdir	/home/rgb/Src/redhat
# to your personal $(HOME)/.rpmmacros after building
# yourself a private copy of the /usr/src/redhat directory structure.
#
# RPM_TOPDIR=/usr/src/redhat
RPM_TOPDIR=$(HOME)/Src/rpm_tree

# This is needed to get the right library and binary rpm.
ARCH=`uname -i`
# ARCH=i386
# These are the three rpms automagically built by the spec
SRPM = $(PROJECT)-$(VERSION_MAJOR).$(VERSION_MINOR)-$(RELEASE).src.rpm
LIBWULF_RPM = libwulf-$(VERSION_MAJOR).$(VERSION_MINOR)-$(RELEASE).$(ARCH).rpm
XMLSYSD_RPM = xmlsysd-$(VERSION_MAJOR).$(VERSION_MINOR)-$(RELEASE).$(ARCH).rpm
WULFSTAT_RPM = wulfstat-$(VERSION_MAJOR).$(VERSION_MINOR)-$(RELEASE).$(ARCH).rpm
WULFLOGGER_RPM = wulflogger-$(VERSION_MAJOR).$(VERSION_MINOR)-$(RELEASE).$(ARCH).rpm
WULF2HTML_RPM = wulf2html-$(VERSION_MAJOR).$(VERSION_MINOR)-$(RELEASE).$(ARCH).rpm
$(TGZ): tgz
$(SRPM): rpm
$(LIBWULF_RPM): rpm
$(XMLSYSD_RPM): rpm
$(WULFSTAT_RPM): rpm
$(WULFLOGGER_RPM): rpm
$(WULF2HTML_RPM): rpm

#========================================================================
# One stop shop.  Basically we build this every time, we hope.
rpm:	Makefile $(TGZ) $(SPEC)
	cp $(TGZ) $(RPM_TOPDIR)/SOURCES
	cp $(SPEC) $(RPM_TOPDIR)/SPECS
	rpmbuild -ba --target=$(ARCH) $(RPM_TOPDIR)/SPECS/$(SPEC)
	cp $(RPM_TOPDIR)/SRPMS/$(SRPM) .
	cp $(RPM_TOPDIR)/RPMS/$(ARCH)/$(LIBWULF_RPM) .
	cp $(RPM_TOPDIR)/RPMS/$(ARCH)/$(XMLSYSD_RPM) .
	cp $(RPM_TOPDIR)/RPMS/$(ARCH)/$(WULFSTAT_RPM) .
	cp $(RPM_TOPDIR)/RPMS/$(ARCH)/$(WULFLOGGER_RPM) .
	cp $(RPM_TOPDIR)/RPMS/$(ARCH)/$(WULF2HTML_RPM) .

svn:
	echo "New Checkin `date`" >> $(SVNTIME)	# Will force a commit and increment revision
	svn commit .
	cat $(SVNTIME) | \
	sed -e '/^New Checkin/d' >> $(SVNTIME).tmp
	mv $(SVNTIME).tmp $(SVNTIME)

sync:
	echo "New Checkin `date`" >> $(SVNTIME)	# Will force a commit and increment revision
	svn commit .		# Do the commit
	rsync -avz --delete $(SVNPATH) login.phy.duke.edu:/home/einstein/prof/rgb/Src/svn-tree
	rsync -avz --delete $(SVNPATH) 209.42.212.5:$(SVNTREE)
	cat $(SVNTIME) | \
	sed -e '/^New Checkin/d' >> $(SVNTIME).tmp
	mv $(SVNTIME).tmp $(SVNTIME)

#========================================================================
#  A standard cleanup target
#========================================================================
clean : 
	- (cd $(LIBRARY); \
	$(MAKE) clean; \
	cd ..; \
	cd $(PROGRAM0); \
	$(MAKE) clean; \
	cd ..; \
	cd $(PROGRAM1); \
	$(MAKE) clean; \
	cd ..; \
	cd $(PROGRAM2); \
	$(MAKE) clean; \
	cd ..; \
	cd $(PROGRAM3); \
	$(MAKE) clean;)

#========================================================================
# We need two toplevel targets that have to be mirrored in $(SPEC).
#========================================================================
install:
	(make clean;\
	make installlib;\
	make installp0;\
	make installp1;\
	make installp2;\
	make installp3;\
	)

installlib:
	(cd $(LIBRARY);\
	make BUILDROOT=$(BUILDROOT) PREFIX=$(PREFIX) install)

installp0:
	(cd $(PROGRAM0);\
	make PREFIX=$(PREFIX) install)

installp1:
	(cd $(PROGRAM1);\
	make PREFIX=$(PREFIX) install)

installp2:
	(cd $(PROGRAM2);\
	make PREFIX=$(PREFIX) install)

installp3:
	(cd $(PROGRAM3);\
	make PREFIX=$(PREFIX) install)

installweb : $(TGZ) $(LIBWULF_RPM) $(XMLSYSD_RPM) $(WULFSTAT_RPM) \
             $(WULFLOGGER_RPM) $(WULF2HTML) $(SRPM) $(ABS) $(PHP)
	(ssh $(WLOGIN) mkdir -p public_html/$(WDIR)/$(PROJECT);\
	rsync -avz $(TGZ) $(WLOGIN):public_html/$(WDIR)/$(PROJECT)/; \
	rsync -avz $(SRPM) $(WLOGIN):public_html/$(WDIR)/$(PROJECT)/; \
	rsync -avz $(LIBWULF_RPM) $(WLOGIN):public_html/$(WDIR)/$(PROJECT)/; \
	rsync -avz $(XMLSYSD_RPM) $(WLOGIN):public_html/$(WDIR)/$(PROJECT)/; \
	rsync -avz $(WULFSTAT_RPM) $(WLOGIN):public_html/$(WDIR)/$(PROJECT)/; \
	rsync -avz $(WULFLOGGER_RPM) $(WLOGIN):public_html/$(WDIR)/$(PROJECT)/; \
	rsync -avz $(WULF2HTML_RPM) $(WLOGIN):public_html/$(WDIR)/$(PROJECT)/; \
	rsync -avz $(ABS) $(WLOGIN):public_html/$(WDIR)/$(PROJECT)/; \
	rsync -avz $(PHP) $(WLOGIN):public_html/$(WDIR)/)

REPOSERVER = uriel
REPOPATH = /var/www/html/fc/6/local/
installrepo : $(TGZ) $(LIBWULF_RPM) $(XMLSYSD_RPM) $(WULFSTAT_RPM) \
             $(WULFLOGGER_RPM) $(WULF2HTML)
	(ssh $(REPOSERVER) mkdir -p $(REPOPATH);\
	rsync -avz $(TGZ) root@$(REPOSERVER):$(REPOPATH);\
	rsync -avz $(LIBWULF_RPM) root@$(REPOSERVER):$(REPOPATH)/SRPM;\
	ssh $(REPOSERVER) mkdir -p $(REPOPATH)/$(ARCH);\
	rsync -avz $(XMLSYSD_RPM) root@$(REPOSERVER):$(REPOPATH)/$(ARCH);\
	rsync -avz $(WULFSTAT_RPM) root@$(REPOSERVER):$(REPOPATH)/$(ARCH);\
	rsync -avz $(WULFLOGGER_RPM) root@$(REPOSERVER):$(REPOPATH)/$(ARCH);\
	rsync -avz $(WULF2HTML_RPM) root@$(REPOSERVER):$(REPOPATH)/$(ARCH)\;
	ssh root@$(REPOSERVER) "cd $(REPOPATH)/$(ARCH);createrepo .")

#========================================================================
# We give all generic rules below.  Currently we only need a rule for 
# objects.
#========================================================================
%.o:%.c $(INCLUDES)
	$(CC) -c $(CFLAGS) $<

