# Makefile for the Sherlock Search System
# (c) 1997--2004 Martin Mares <mj@ucw.cz>

TOPDIR:=$(shell pwd)

CFLAGS=$(CLANG) $(COPT) $(CDEBUG) $(CWARNS) -I. -Iobj
LDFLAGS=$(LOPT)

DIRS=
PROGS=
CONFIGS=accept filter sherlock local trace url-equiv
TESTS=

# Various files whose type does not fit into PROGS
DATAFILES=

.PHONY: all clean distclean runtree programs datafiles force tags config dust

all: runtree programs datafiles extras config

include sherlock/config.mk
-include custom/config.mk

custom/config.mk:
	@echo 'You need to link "custom" to the right directory.'
	@exit 1

ifdef CONFIG_SHARED
LS=so
OS=oo
else
LS=a
OS=o
endif

# Clean needs to be a double-colon rule since we want sub-makefiles to be able
# to define their own cleanup actions.
dust::
	rm -f `find . -path "*~" -or -name "\#*\#" -or -name core`
	rm -f allocs.tmp cscope.out test*.log

clean:: dust
	rm -rf obj run/bin/* run/lib/* run/.tree-stamp
	rm -f TAGS

distclean:: clean
	rm -rf run
	rm custom

testclean::
	rm -f `find obj -name "*.test"`

# Extra directories to be created in the run/* hierarchy
EXTRA_RUNDIRS=db tmp index lock log lib/perl5/Sherlock
INSTALL_RUNDIRS=bin lib

# Extra default rules (appended to by submakefiles)
extras::

# We need to define names of libraries here, because even though variable references
# in bodies of rules can be forward, those in dependencies cannot. Also the order of
# includes is somewhat fragile because of that.
LIBSH=obj/sherlock/libsh.$(LS) obj/lib/libucw.$(LS)
LIBCHARSET=obj/charset/libcharset.$(LS)
LIBFILTER=obj/filter/libfilter.$(LS)
ifdef CONFIG_LANG
LIBLANG=obj/lang/liblang.$(LS)
endif

# Include makefiles of various subsystems.
-include custom/Makefile
include build/Makefile
include sherlock/Makefile
include lib/Makefile
include charset/Makefile
include filter/Makefile
ifdef CONFIG_LANG
include lang/Makefile
endif
include utils/Makefile
include gather/Makefile
include indexer/Makefile
ifdef CONFIG_SEARCH
include search/Makefile
endif
ifdef CONFIG_DEBUG
include debug/Makefile
endif

runtree: run/.tree-stamp $(addsuffix /.dir-stamp,$(addprefix obj/,$(DIRS)))

run/.tree-stamp: custom/config.mk
	mkdir -p run $(addprefix run/, cf $(EXTRA_RUNDIRS) $(INSTALL_RUNDIRS))
	touch run/.tree-stamp

programs: $(PROGS)
datafiles: $(DATAFILES)
tests: $(TESTS)

tags:
	etags `find . -name "*.[ch]"`

# Generate configuration files

config: $(addprefix run/cf/,$(CONFIGS))

run/cf/%: custom/cf/% custom/config.mk build/genconf
	build/genconf $< $@ custom/config.mk
run/cf/%: cf/% custom/config.mk build/genconf
	build/genconf $< $@ custom/config.mk

# Black magic with dependencies. It would be more correct to make "depend.new"
# a prerequisite for "depend", but "depend.new" often has the same timestamp
# as "depend" which would confuse make a lot and either force remaking anyway
# or (as in current versions of GNU make) erroneously skipping the remaking.

-include obj/depend

obj/depend: force
	if [ -s obj/depend.new ] ; then build/mergedeps obj/depend obj/depend.new ; >obj/depend.new ; fi

force:

# Configuration

obj/lib/autoconf.h: sherlock/config.mk custom/config.mk
	cat $^ | sed '/^#/d; /^$$/d; s/\([^=]*_[^=]*\)=\(.*\)/#define \1 \2/; /^#/!d' >obj/lib/autoconf.h.new
	mv obj/lib/autoconf.h.new obj/lib/autoconf.h

# Installation

install: all
	SH_EXTRA_RUNDIRS="$(EXTRA_RUNDIRS)" SH_INSTALL_RUNDIRS="$(INSTALL_RUNDIRS)" SH_CONFIGS="$(CONFIGS)" build/installer $(INSTALL_DIR)

# Implicit rules

%.dir-stamp:
	mkdir -p $(@D) && touch $@

%.a:
	ar rcs $@ $?

%.so:
	$(CC) $(LSHARED) $(LDFLAGS) -o $@ $^
	ln -sf $(TOPDIR)/$@ run/lib

obj/%.o: %.c obj/lib/autoconf.h
	DEPENDENCIES_OUTPUT="obj/depend.new $@" $(CC) $(CFLAGS) -c -o $@ $<

obj/%.oo: %.c obj/lib/autoconf.h
	DEPENDENCIES_OUTPUT="obj/depend.new $@" $(CC) $(CFLAGS) $(CSHARED) -c -o $@ $<

obj/%-tt.o: %.c obj/lib/autoconf.h
	DEPENDENCIES_OUTPUT="obj/depend.new $@" $(CC) $(CFLAGS) -DTEST -c -o $@ $<

obj/%-t: obj/%-tt.o $(LIBSH)
	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

obj/%.test: %.t build/tester
	build/tester $< && touch $@

BINDIR=bin

obj/%: obj/%.o
	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
	ln -sf $(TOPDIR)/$@ run/$(BINDIR)/

obj/%: %.sh custom/config.mk build/genconf
	build/genconf $< $@ custom/config.mk
	chmod +x $@
	ln -sf $(TOPDIR)/$@ run/$(BINDIR)/

obj/%: %.pl
	cp $(TOPDIR)/$^ $@
	chmod +x $@
	ln -sf $(TOPDIR)/$@ run/$(BINDIR)/

obj/%.pm: %.pm
	cp $(TOPDIR)/$^ $@
	ln -sf $(TOPDIR)/$@ run/lib/perl5/Sherlock

DATADIR=lib

$(DATAFILES): obj/%: %
	cp $(TOPDIR)/$^ $@
	ln -sf $(TOPDIR)/$@ run/$(DATADIR)/

# Don't delete intermediate targets. There shouldn't be any, but due to bugs
# in GNU Make rules with targets in not-yet-existing directories are ignored
# when searching for implicit rules and thence targets considered intermediate.
.SECONDARY:
