#
# Build darcs
#
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
ifneq (config,$(MAKECMDGOALS))
include autoconf.mk
endif
endif

ifneq (,$(RTSFLAGS))
GHCFLAGS += +RTS $(RTSFLAGS) -RTS
endif

GHCFLAGS += -Wall -Werror -I.
GHCFLAGS_Record.o = $(filter-out -auto-all,$(GHCFLAGS))
GHCFLAGS_SelectChanges.o = $(filter-out -auto-all,$(GHCFLAGS))
GHCFLAGS_SHA1.o = $(GHCFLAGS) -no-auto-all -funfolding-use-threshold20
GHCFLAGS_Context.o = $(filter-out -cpp,$(GHCFLAGS))

COMMON_FILES := Autoconf.lhs \
	CheckFileSystem.lhs ColourPrinter.lhs Compat.hs Curl.hs DarcsIO.lhs	\
	Pristine.lhs DarcsArguments.lhs DarcsFlags.lhs DarcsUtils.lhs	\
	CommandLine.lhs DarcsCommandsAux.lhs \
	DateMatcher.lhs Depends.lhs Diff.lhs Exec.lhs External.hs	\
	FastPackedString.hs FileName.lhs FilePathMonad.lhs	\
	FilePathUtils.hs IsoDate.lhs Lcs.lhs Lock.lhs Map.hs	\
	Match.lhs Motd.lhs Patch.lhs PatchApply.lhs PatchBundle.lhs	\
	PatchCheck.lhs PatchChoices.lhs PatchCommute.lhs PatchCore.lhs	\
	PatchInfo.lhs PatchMatch.lhs PatchMatchData.lhs			\
	PatchRead.lhs PatchReadMonads.hs \
	PatchSet.lhs PatchShow.lhs PatchViewing.lhs	\
	Population.lhs PopulationData.lhs	\
	PrintPatch.lhs Printer.lhs RawMode.hs RegChars.lhs \
	RepoFormat.lhs RepoPrefs.lhs		\
	DarcsRepo.lhs Repository.lhs                      \
	Resolution.lhs SHA1.lhs \
	SignalHandler.lhs SlurpDirectory.lhs Stringalike.hs Test.lhs \
	ThisVersion.lhs \
        UTF8.lhs Workaround.hs FileSystem.hs Global.lhs \
        $(GIT_SRCS)

DARCS_FILES := $(COMMON_FILES) Add.lhs AmendRecord.lhs	\
	Annotate.lhs Apply.lhs		\
	ArgumentDefaults.lhs Changes.lhs Check.lhs Context.hs		\
	DarcsCommands.lhs DarcsURL.hs DiffCommand.lhs Dist.lhs		\
	Email.hs Get.lhs GuiUtils.lhs Help.lhs Init.lhs 		\
	MainGui.lhs Mv.lhs 	 	\
	Optimize.lhs 		\
	Pull.lhs Push.lhs Put.lhs 		\
	Query.lhs QueryManifest.lhs QueryTags.lhs \
	Record.lhs RemoteApply.lhs	\
	Remove.lhs Repair.lhs Replace.lhs	\
	Resolve.lhs Revert.lhs Rollback.lhs	\
	SelectChanges.lhs Send.lhs SetPref.lhs Tag.lhs TheCommands.lhs	\
	TouchesFiles.lhs TrackDown.lhs Unrecord.lhs Unrevert.lhs	\
	WhatsNew.lhs

UNIT_FILES := $(DARCS_FILES) PatchTest.lhs

C_OBJS := c_compat.o maybe_relink.o atomic_create.o fpstring.o umask.o \
          $(GIT_C_OBJS)

ifeq ($(SYS), windows)
GHCFLAGS += -iwin32 -Iwin32 -DWIN32
DARCS_FILES += win32/System/Posix.hs win32/System/Posix/Files.hs \
               win32/System/Posix/IO.hs win32/CtrlC.hs
C_OBJS += win32/CtrlC_stub.o win32/CtrlC.o
UNIT_FILES += win32/System/Posix.hs win32/System/Posix/Files.hs \
              win32/System/Posix/IO.hs 
endif

ifeq ($(HAVE_CURSES),True)
GHCFLAGS += -DHAVE_CURSES
endif

ifeq ($(HAVE_MAPI),True)
C_OBJS += win32/send_email.o
CPPFLAGS += -Iwin32
GHCFLAGS += -DHAVE_MAPI
endif

ifeq ($(HAVE_LIBCURL),True)
C_OBJS += hscurl.o
GHCFLAGS += -DHAVE_CURL
endif

DARCS_OBJS	:= $(patsubst %.hs,%.o,$(patsubst %.lhs,%.o,$(DARCS_FILES)))
UNIT_OBJS	:= $(patsubst %.hs,%.o,$(patsubst %.lhs,%.o,$(UNIT_FILES)))

ifneq (,$(findstring HAVEWX,$(GHCFLAGS)))
ifeq ($(shell uname),Darwin)
USE_REZ:=1
else
endif
endif

ifeq ($(USE_REZ),1)
# Resource fork stuff to make the GUI work under MacOS X.  
REZ_CMD:=/Developer/Tools/Rez
REZ_FLAGS:=-t APPL Carbon.r
else
REZ_CMD:=:
endif


.PHONY:		all clean distclean maintainer-clean dist deb test check install \
		installserver installdocs installbin windowsinstaller \
		website slowtest

config: configure autoconf.mk

installbin:	all
	test -d $(DESTDIR)$(bindir) || $(INSTALL) -d $(DESTDIR)$(bindir)
	$(INSTALL) darcs $(DESTDIR)$(bindir)
	$(REZ_CMD) $(REZ_FLAGS) -o $(DESTDIR)$(bindir)/darcs 

	test -d $(DESTDIR)$(sysconfdir)/bash_completion.d || \
		$(INSTALL) -d $(DESTDIR)$(sysconfdir)/bash_completion.d
	$(INSTALL_DATA) darcs_completion $(DESTDIR)$(sysconfdir)/bash_completion.d/darcs

	test -d $(DESTDIR)$(mandir)/man1 || \
		$(INSTALL) -d $(DESTDIR)$(mandir)/man1
	$(INSTALL_DATA) darcs.1 $(DESTDIR)$(mandir)/man1/

installdocs:	manual/darcs.ps manual/index.html
	test -d $(DESTDIR)$(datadir)/doc/darcs/manual || \
		$(INSTALL) -d $(DESTDIR)$(datadir)/doc/darcs/manual
	$(INSTALL_DATA) manual/* $(DESTDIR)$(datadir)/doc/darcs/manual

	test -d $(DESTDIR)$(datadir)/doc/darcs/examples || \
		$(INSTALL) -d $(DESTDIR)$(datadir)/doc/darcs/examples
	$(INSTALL_DATA) zsh_completion_new $(DESTDIR)$(datadir)/doc/darcs/examples/
	$(INSTALL_DATA) zsh_completion_old $(DESTDIR)$(datadir)/doc/darcs/examples/

installserver:	cgi/darcs.cgi
	test -d $(DESTDIR)$(libexecdir)/cgi-bin || \
		$(INSTALL) -d $(DESTDIR)$(libexecdir)/cgi-bin

	test -d $(DESTDIR)$(sysconfdir)/darcs || \
		$(INSTALL) -d $(DESTDIR)$(sysconfdir)/darcs
	test -e $(DESTDIR)$(sysconfdir)/darcs/cgi.conf || \
	    $(INSTALL_DATA) cgi/cgi.conf $(DESTDIR)$(sysconfdir)/darcs/cgi.conf
	$(INSTALL) cgi/darcs.cgi $(DESTDIR)$(libexecdir)/cgi-bin/darcs.cgi
	test -d $(DESTDIR)$(datadir)/darcs || \
		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs
	test -d $(DESTDIR)$(datadir)/darcs/xslt || \
		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs/xslt
	$(INSTALL_DATA) cgi/xslt/*.xslt $(DESTDIR)$(datadir)/darcs/xslt/
	$(INSTALL_DATA) cgi/xslt/styles.css $(DESTDIR)$(datadir)/darcs/xslt/styles.css

# Debian policy doesn't allow symlinks as configuration files.
#	test -e $(DESTDIR)$(sysconfdir)/darcs/styles.css || \
#	    ln -s $(datadir)/darcs/xslt/styles.css \
#		$(DESTDIR)$(sysconfdir)/darcs/styles.css
	$(INSTALL) -m 644 cgi/xslt/styles.css $(DESTDIR)$(sysconfdir)/darcs/styles.css

USE_REZ:=1


PREDIST_COPY_FILES := \
	ChangeLog \
	AUTHORS \
	RELEASE_STATE \
	Context.hs

dist: darcs $(PREDIST_COPY_FILES)
	REPO_PATH="$$PWD" ./darcs dist --dist-name darcs-$(DARCS_VERSION)
	ln -sf darcs-$(DARCS_VERSION).tar.gz darcs-latest.tar.gz

predist_copy:
	for F in $(PREDIST_COPY_FILES); do \
	    cp -v "$$REPO_PATH/$$F" .; \
	done

predist: predist_copy manual/darcs.ps darcs.1 manual/index.html distclean
	rm -fr debian

deb:		darcs
	rm -rf /tmp/darcs-deb_temp && \
	./darcs dist --dist-name darcs-deb_temp && \
	mv darcs-deb_temp.tar.gz /tmp && \
	cd /tmp && tar zxf darcs-deb_temp.tar.gz && \
	cd darcs-deb_temp && debuild && \
	rm -rf /tmp/darcs-deb_temp

windowsinstaller:	darcs manual/index.html darcs.nsi
	echo "!define VERSION $(DARCS_VERSION)" > version.nsi
	"$(MAKENSIS)" version.nsi darcs.nsi
	rm -f version.nsi

darcs:		$(DARCS_OBJS) darcs.lhs $(C_OBJS) rts.o
	@echo Linking $@ ...
	@rm -f Main.o Main.hi
	@$(GHC) $(GHCFLAGS) $(OPTLLDFLAGS) -o $@ $^
# Note: this is for developers to test the darcs they 
# compiled but did not install.  We have execute the same 
# command in the install target for end users.
	$(REZ_CMD) $(REZ_FLAGS) -o $@

ghci: $(DARCS_FILES) $(C_OBJS)
	ghci $(filter-out -Wall,$(GHCFLAGS)) $(OPTLLDFLAGS) darcs.lhs $(C_OBJS)
.PHONY: ghci

darcsman:		darcsman.hs $(C_OBJS) $(DARCS_OBJS)
list_authors:	list_authors.hs $(C_OBJS) $(DARCS_OBJS)
make_changelog:	make_changelog.hs $(C_OBJS) $(DARCS_OBJS)
unit:			unit.lhs $(UNIT_OBJS) rts.o $(C_OBJS)
preproc:		preproc.hs $(C_OBJS) $(DARCS_OBJS)

wxDarcs:	darcs
	cp $< $@
	$(REZ_CMD) $(REZ_FLAGS) -o $@

ifdef USE_REZ
wxDarcs.app:	wxDarcs osx/copyFrameworks osx/Info.plist osx/wxmac.icns
	chmod u+x osx/copyFrameworks
	mkdir -p _$@/Contents/MacOS
	mkdir -p _$@/Contents/Resources
	cp $< _$@/Contents/MacOS
	osx/copyFrameworks _$@ $<
	echo -n "APPL????" > _$@/Contents/PkgInfo
	cp osx/Info.plist _$@/Contents
	cp osx/wxmac.icns _$@/Contents/Resources
	/Developer/Tools/SetFile -a C _$@/Contents
	mv _$@ $@

wxDarcs.dmg:	wxDarcs.app  osx/createDmg
	chmod u+x osx/createDmg
	osx/createDmg 30m Darcs $< $@
endif

TEXSOURCES := preproc darcs.lhs features.tex \
	switching.tex configuring_darcs.tex gpl.tex \
	$(DARCS_FILES) building_darcs.tex \
	best_practices.tex
darcs.tex: $(TEXSOURCES)
	./preproc darcs.lhs $(PREPROCHTML) > darcs.tex
darcs_print.tex: $(TEXSOURCES)
	./preproc darcs.lhs > darcs_print.tex

website: darcs-stable.tar.gz manual/darcs.ps manual/index.html manual/bigpage.html \
	darcs index.html

manual/index.html: darcs.tex gpl.tex darcs.css
	$(MAKEMANUAL)
	cp -f darcs.css manual/darcs.css

manual/bigpage.html: darcs.tex gpl.tex darcs.css
	ln -sf darcs.tex bigpage.tex
	latex2html -split 0 -external_file darcs -prefix big \
		-no_auto_link -dir manual bigpage.tex
	rm bigpage.tex
	cp -f darcs.css manual/bigpage.css

index.html:	index.html.in config.status
	sed "s/VERSION/$(DARCS_VERSION)/g" $< > $@

manual/darcs.ps:	darcs_print.ps
	cp darcs_print.ps manual/darcs.ps

darcs.1:	darcsman
	./darcsman > darcs.1

AUTHORS:	list_authors
	./list_authors > AUTHORS

ChangeLog: make_changelog changelog.in/ChangeLog.old $(wildcard changelog.in/entries/*)
	( \
	  set -e; \
	  echo; \
	  ./make_changelog $(wildcard changelog.in/entries/*); \
	  echo; \
	  sed -n '/^darcs (1\.0\.2)$$/,$$p' changelog.in/ChangeLog.old; \
	) > $@.tmp
	mv $@.tmp $@

slowtest:	test test_unit

test check:    test_scripts

TEST_FILTER_FILE := tests_to_run
PERL_HARNESS := perl perl_harness
SHELL_HARNESS := perl shell_harness

test_scripts:     darcs
	@cd tests && rm -rf .darcs; \
	 if [ -r $(TEST_FILTER_FILE) ];\
	 then grep "\.pl" $(TEST_FILTER_FILE) | grep -v '^#' | xargs $(PERL_HARNESS) && \
              grep "\.sh" $(TEST_FILTER_FILE) | grep -v '^#' | xargs $(SHELL_HARNESS); \
	 else $(PERL_HARNESS) *.pl && $(SHELL_HARNESS) *.sh; fi

test_scripts_hashed:     darcs
	@cd tests && \
	 rm -rf .darcs; \
	 mkdir .darcs; \
	 echo ALL --hashed-inventory >> .darcs/defaults; \
	 if [ -r $(TEST_FILTER_FILE) ];\
	 then grep "\.sh" $(TEST_FILTER_FILE) | grep -v '^#' | xargs $(SHELL_HARNESS); \
              grep "\.pl" $(TEST_FILTER_FILE) | grep -v '^#' | xargs $(PERL_HARNESS); \
	 else $(SHELL_HARNESS) *.sh && $(PERL_HARNESS) *.pl; fi

test_scripts_both:     darcs
	@cd tests && \
	 rm -rf .darcs; \
	 mkdir .darcs; \
	 echo ALL --hashed-inventory >> .darcs/defaults; \
	 echo ALL --old-fashioned-inventory >> .darcs/defaults; \
	 if [ -r $(TEST_FILTER_FILE) ];\
	 then grep "\.sh" $(TEST_FILTER_FILE) | grep -v '^#' | xargs $(SHELL_HARNESS); \
              grep "\.pl" $(TEST_FILTER_FILE) | grep -v '^#' | xargs $(PERL_HARNESS); \
	 else $(SHELL_HARNESS) *.sh && $(PERL_HARNESS) *.pl; fi

test_unit:     darcs unit
	./unit

clean:
	rm -f *.o *.hi unit diff darcs darcs_cgi
	rm -f stringify
	rm -f darcs.tex darcs.dvi darcs.aux
	rm -f darcs_print.tex darcs_print.log darcs_print.aux darcs_print.toc
	rm -f preproc darcsman
	rm -rf tests/temp* darcs.log darcs.toc
	rm -f conftest* .depend.bak
	rm -f win32/*.o win32/*.hi
	rm -f win32/System/*.o win32/System/*.hi
	rm -f win32/System/Posix/IO.hs win32/System/Posix/Files.hs
	rm -f version.nsi
	rm -f list_authors make_changelog
	#only remove Context.hs if we have a darcs inventory to rebuild it from
	if test -f _darcs/inventory; then rm -f Context.hs; fi
	rm -f TAGS tags

distclean:	clean
	rm -rf config.status config.log autoconf.mk config.cache autom4te.cache
	rm -f manual/darcs.ps manual/darcs.pdf Autoconf.lhs Workaround.hs darcs.idv
	rm -f ThisVersion.lhs cgi/README cgi/darcs.cgi cgi/cgi.conf
	rm -f config.command

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 configure darcs.1 .depend AUTHORS ChangeLog
	rm -f Context.hs
	rm -f manual/*.html manual/darcs*.??? manual/darcs.lg
	rm -f manual/darcs.xref c_context.c darcs_print.ps
	rm -rf tests/test_output

configure:		configure.ac aclocal.m4
	autoconf

autoconf.mk Autoconf.lhs cgi/darcs.cgi : \
   config.status autoconf.mk.in Autoconf.lhs.in cgi/darcs.cgi.in
	./config.status

config.status:	configure
	@if test -x config.status; then					\
	  ./config.status --recheck;					\
	else								\
	  echo >&2 "Please run ./configure to setup the build system.";	\
	  exit 1;							\
	fi

.depend:	$(DARCS_FILES) $(UNIT_FILES)
	@echo Rebuild dependencies ...
	@$(GHC) $(GHCFLAGS) -M -optdep-f -optdep.depend $^

.depend:	autoconf.mk

ifeq (,$(findstring clean,$(MAKECMDGOALS)))
ifneq (config,$(MAKECMDGOALS))
include .depend
endif
endif

ETAGS = hasktags -e
CTAGS = hasktags -c
# This follows what autoconf does.
# Fixme: Generate correct list of .c files and depend on that.
.PHONY: CTAGS ctags tags
tags: TAGS
TAGS: $(DARCS_FILES)
	$(ETAGS) $(DARCS_FILES) && etags -a *.c
ctags: CTAGS
CTAGS: $(DARCS_FILES)
	$(CTAGS) $(DARCS_FILES) && ctags -a *.c
