#!/usr/bin/make # help out emacs
#
# Top-level autosetup-filtered Makefile for libfossil. This particular
# build is for Unix platforms with GNU Make 3.81+.
all:
QUIET ?= 0
include config.make
ShakeNMake.CISH_SOURCES := $(wildcard *.c) $(wildcard $(SRC.DIR)/*.c)
# Subdir cleanup rules and deps list must come before shakenmake.make is included.
clean: clean-th1ish
distclean: distclean-th1ish
ShakeNMake.QUIET := $(BUILD_QUIETLY)
include shakenmake.make
include sqlite3.make
MAIN_MAKEFILES := $(PACKAGE.MAKEFILE) $(ShakeNMake.MAKEFILE) @AUTODEPS@

AUTOCONFIG_H := @srcdir@/include/fossil-scm/autoconfig.h
#SRCDIR := @top_srcdir@/src
SRCDIR := @srcdir@/src
FSL.SRC.BASENAMES := \
	fsl.c \
	fsl_appendf.c \
	fsl_bag.c \
	fsl_buffer.c \
	fsl_cli.c \
	fsl_content.c \
	fsl_config.c \
	fsl_cx.c \
	fsl_db.c \
	fsl_delta.c \
	fsl_diff.c \
	fsl_encode.c \
	fsl_event.c \
	fsl_fs.c \
	fsl_io.c \
	fsl_leaf.c \
	fsl_md5.c \
	fsl_mf.c \
	fsl_pq.c \
	fsl_repo.c \
	fsl_schema.c \
	fsl_sha1.c \
	fsl_tag.c \
	fsl_ticket.c \
	fsl_utf8.c \
	fsl_vfile.c \
	fsl_wiki.c
FSL.SRC := $(addprefix $(SRCDIR)/,$(FSL.SRC.BASENAMES))

########################################################################
# Set up building the main objects the $(OBJ.DIR). OBJ.DIR comes from
# configure bits.
$(OBJ.DIR):
	mkdir $@
DISTCLEAN_FILES += -r $(OBJ.DIR)
# Reminder to self: the fact that rm(1) on my system accepts -r
# in the middle of the file list somewhat surprises me, and it may
# be non-portable.

FSL.OBJ := $(SQLITE3.O)

########################################################################
# $(call)able macro
# which sets up rules for building dir/foo.c to $(OBJ.DIR)/foo.o
# $1 = input file. Must not be more than 1 subdir level
# deep (that would break these rules).
# Intended only for libs to be included in $(FSL.OBJ).
define ADD_C_TO_OBJ_DIR
$(1).OBJ := $(OBJ.DIR)/$(basename $(notdir $(1))).o
$$($(1).OBJ): $(1)
	@$$(call ShakeNMake.CALL.SETX,"CC [$$@] ..."); \
	$(COMPILE.c) $(COMPILE.c.OPTIONS) -o $$($(1).OBJ) $(1)
FSL.OBJ += $$($(1).OBJ)
endef
$(foreach cfile,$(FSL.SRC),$(eval $(call ADD_C_TO_OBJ_DIR,$(cfile))))

#####################################################################
# The obligatory kludge...
# We can't set $(FSL.OBJ) to depend on $(OBJ.DIR) b/c OBJ.DIR is always
# newer then the files it contains. So we make a dummy dep
# which creates the dir as a side-effect.
OBJ.DIR.MAKER := $(OBJ.DIR)/_mkdir
$(OBJ.DIR.MAKER):
	@test -d $(OBJ.DIR) || mkdir $(OBJ.DIR)
	@touch $@
# End $(OBJ.DIR) bits.
########################################################################

########################################################################
# Transform schema SQL files into source form. We don't use fossil(1)'s
# approach because it relies on unspecified length limits on C string
# literals. Yeah, it works, but i'm funny about the C Standard.
DIR.TOOLS := @srcdir@/tools
BIN.TEXT2C := $(DIR.TOOLS)/text2c
$(BIN.TEXT2C): $(DIR.TOOLS)/text2c.c
	cc $< -o $@
CLEAN_FILES += $(BIN.TEXT2C)
define SQL2C
#$$(OBJ.DIR)/$(1).o: $$(OBJ.DIR)/$(1).c
$(2):
$$(OBJ.DIR)/$(1).c: $(2) $$(BIN.TEXT2C) $$(MAIN_MAKEFILES) $$(OBJ.DIR.MAKER)
	@echo "Creating $$@ from $(2)..."; \
	{ \
		echo '/* Binary form of file $(2) */'; \
		echo '/** @page page_$(1) Schema: $$(notdir $(2))'; \
		echo '@code'; \
		cat "$(2)"; \
		echo ' @endcode'; \
		echo ' @see $$(subst _cstr,,$(1))()'; \
		echo '*/'; \
		$$(BIN.TEXT2C) $(1) < $(2); \
		echo '/* end of $(2) */'; \
	} > $$@;
FSL.SRC += $$(OBJ.DIR)/$(1).c
FSL.OBJ += $$(OBJ.DIR)/$(1).o
DISTCLEAN_FILES += $$(OBJ.DIR)/$(1).c
sql: $$(OBJ.DIR)/$(1).c
endef
$(eval $(call SQL2C,fsl_schema_config_cstr,sql/config.sql))
$(eval $(call SQL2C,fsl_schema_repo1_cstr,sql/repo-static.sql))
$(eval $(call SQL2C,fsl_schema_repo2_cstr,sql/repo-transient.sql))
$(eval $(call SQL2C,fsl_schema_checkout_cstr,sql/checkout.sql))
$(eval $(call SQL2C,fsl_schema_ticket_cstr,sql/ticket.sql))
$(eval $(call SQL2C,fsl_schema_ticket_reports_cstr,sql/ticket-reports.sql))
# end SQL transformation bits
########################################################################

CLEAN_FILES += $(FSL.OBJ)
$(FSL.OBJ): $(OBJ.DIR.MAKER)


EXTRA_LIBS := -lz $(SQLITE3_LDFLAGS)

libfossil.DLL.OBJECTS := $(FSL.OBJ)
libfossil.DLL.LDFLAGS := @SH_LDFLAGS@ $(EXTRA_LIBS)
libfossil.LIB.OBJECTS := $(libfossil.DLL.OBJECTS)
########################################################################
# Note that the limitation of building EITHER static OR shared libs
# is artificial. It simplifies figuring out the linker args needed
# for the test apps.
ifeq (1,@shared@)
# Shared lib
$(eval $(call ShakeNMake.CALL.RULES.DLLS,libfossil))
all: $(libfossil.DLL)
$(libfossil.DLL): $(libfossil.DLL.OBJECTS)
TEST_BINS_LIBDEPS += $(libfossil.DLL)
else
# Static lib
$(eval $(call ShakeNMake.CALL.RULES.LIBS,libfossil))
all: $(libfossil.LIB)
$(libfossil.LIB): $(libfossil.LIB.OBJECTS)
TEST_BINS_LIBDEPS += $(libfossil.LIB)
endif

########################################################################
# Binaries...
TEST_BINS_LDFLAGS := -L. -lfossil $(EXTRA_LIBS) @SH_LINKFLAGS@
test.BIN.OBJECTS := test.o
test.BIN.LDFLAGS := $(TEST_BINS_LDFLAGS)
$(eval $(call ShakeNMake.CALL.RULES.BIN,test))
$(test.BIN): $(TEST_BINS_LIBDEPS)
all: $(test.BIN)

########################################################################
# Sets up binary build rules for binary named $1. This only works
# for the basic test binaries which all have common compile/link
# bits. Assumes sources are in $1.c.
define RULES_F_BIN
$(1).BIN.OBJECTS := $(1).o
$(1).BIN.LDFLAGS := $$(TEST_BINS_LDFLAGS)
$(call ShakeNMake.CALL.RULES.BIN,$(1))
$$($(1).BIN): $$(TEST_BINS_LIBDEPS)
all: $$($(1).BIN)
endef
$(OBJ.DIR)/%.o: %.c
	@$(call ShakeNMake.CALL.SETX,"CC [$@] ..."); \
	$(COMPILE.c) $(COMPILE.c.OPTIONS) $(OUTPUT_OPTION) $<
F_BINS := \
	f-acat \
	f-delta \
	f-event \
	f-ls \
	f-mfparse \
	f-new \
	f-query \
	f-resolve \
	f-tag \
	f-timeline \
	f-sanity \
	f-sizeof \
	f-wiki
$(foreach fbin,$(F_BINS),$(eval $(call RULES_F_BIN,$(fbin))))


########################################################################
# A quick-n-dirty amalgamation build...
INCD := include/fossil-scm
AMAL_C := libfossil_amalgamation.c
AMAL_H := libfossil_amalgamation.h
AMAL_CONF.H := libfossil_amalgamation-config.h
CLEAN_FILES += $(AMAL_H) $(AMAL_C) $(AMAL_CONF.H)
AMAL_C.SRC := \
	$(FSL.SRC)
# ACHTUNG: in AMAL_H.SRC, $(AMAL_CONF.H) MUST be included first.
AMAL_H.SRC := \
	$(INCD)/fossil-config.h \
	$(INCD)/fossil.h \
	$(INCD)/fossil-util.h \
	$(INCD)/fossil-core.h \
	$(INCD)/fossil-db.h \
	$(INCD)/fossil-hash.h \
	$(INCD)/fossil-content.h \
	$(INCD)/fossil-internal.h \
	$(INCD)/fossil-pages.h \
	$(INCD)/fossil-cli.h
$(AMAL_H.SRC):
$(AMAL_C.SRC):
$(AMAL_H): $(MAIN_MAKEFILES) $(AMAL_H.SRC) $(AMAL_CONF.H)
$(AMAL_C): $(MAIN_MAKEFILES) $(AMAL_H) $(AMAL_C.SRC)
$(AMAL_CONF.H): $(MAIN_MAKEFILES) auto.def
	@echo "Generating $@ ..."
	sh configure --amal
$(AMAL_H): 
	@echo "Creating $@..."
	@{ \
		echo '#if !defined(FSL_AMALGAMATION_BUILD)'; \
		echo '#define FSL_AMALGAMATION_BUILD 1'; \
		echo '#endif'; \
		echo '#include "$(AMAL_CONF.H)"'; \
	} > $@
	@{ \
		for i in $(AMAL_H.SRC); do \
			echo "/* start of file $$i */"; \
			cat $$i; \
			echo "/* end of file $$i */"; \
		done; \
	} | sed  \
		 -e '/[ ]*#[ ]*include[ ]*.*fossil.*\.h["]/d' \
		 -e '/[ ]*#[ ]*include[ ]*.*".*config\.h"/d' \
		>> $@

$(AMAL_C): $(AMAL_H)
	@echo "Creating $@..."
	@echo '#include "$(AMAL_H)"' > $@
	@{ \
		for i in $(AMAL_C.SRC); do \
			echo "/* start of file $$i */"; \
			cat $$i; \
			echo "/* end of file $$i */"; \
		done; \
	} | sed \
		 -e '/[ ]*#[ ]*include[ ]*.*fossil.*\.h["]/d' \
		>> $@

amal: $(AMAL_C)
	@if which gcc >/dev/null; then \
		echo "Trying GCC C89..."; \
		gcc -c -pedantic -Wstrict-aliasing -Wall -Werror -std=c89 -Wno-long-long $(AMAL_C) || exit;\
		echo "Trying GCC C99..."; \
		gcc -c -pedantic -Wstrict-aliasing -Wall -Werror -std=c99 $(AMAL_C) || exit; \
	fi
	@if which tcc >/dev/null; then \
		echo "Trying tcc..."; \
		tcc -c -pedantic -Wall -Werror $(AMAL_C) || exit; \
		echo "Man, that was FAST!"; \
	 fi
	@if which clang >/dev/null; then \
		echo "Trying clang..."; \
		clang -c -pedantic -Wall -Werror $(AMAL_C) || exit; \
	fi
# /amalgamation
########################################################################



########################################################################
# Other stuff...

install: all
	@echo 'No installation rules yet.'

DISTCLEAN_FILES += $(AUTOCONFIG_H) Makefile config.log autosetup/jimsh0

# automake compatibility. do nothing for all these targets
#EMPTY_AUTOMAKE_TARGETS := dvi pdf ps info html tags ctags mostlyclean maintainer-clean check installcheck installdirs \
# install-pdf install-ps install-info install-html -install-dvi uninstall install-exec install-data distdir
#.PHONY: $(EMPTY_AUTOMAKE_TARGETS)
#$(EMPTY_AUTOMAKE_TARGETS):

## @top_srcdir@/Makefile.in: # b/c AUTODEPS contains this name (it probably shoudln't)
#$(FSL.OBJ): @AUTODEPS@ @top_srcdir@/Makefile @top_srcdir@/config.make

# Reconfigure if needed
ifeq ($(findstring clean,$(MAKECMDGOALS)),)
@top_srcdir@/config.make: @AUTODEPS@ @top_srcdir@/config.make.in
	@@AUTOREMAKE@
@top_srcdir@/Makefile: @AUTODEPS@ @top_srcdir@/Makefile.in
	chmod +w $@
	@@AUTOREMAKE@
@top_srcdir@/vars.make: @AUTODEPS@ @top_srcdir@/vars.make.in
	@@AUTOREMAKE@
endif

# Or on demand
reconfig:
	@AUTOREMAKE@

