# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.

PROJECT       = oxfuse
DESCR         = "D object-oriented binding for libfuse3"
DC            = ldc2
VERSION       = $(shell cat source/$(PROJECT)/version)
MAJOR_VERSION = $(shell cat source/$(PROJECT)/version | cut -d'.' -f1)

BASENAME                 = $(PROJECT)-$(DC)
LIBRARY                  = lib$(BASENAME)
PCFILE_NAME              = $(BASENAME).pc
PCFILE_NAME_ST           = $(BASENAME)-static.pc
OBJFILE                  = $(LIBRARY).o
SHLIB_BASE               = $(LIBRARY).so
STLIB_NAME               = $(LIBRARY).a
SHLIB_WITH_VERSION       = $(SHLIB_BASE).$(VERSION)
SHLIB_WITH_MAJOR_VERSION = $(SHLIB_BASE).$(MAJOR_VERSION)
SHLIB_WITHOUT_VERSION    = $(SHLIB_BASE)

B_DIR     = build
OBJECT    = $(B_DIR)/$(OBJFILE)
SHLIB     = $(B_DIR)/$(SHLIB_WITH_VERSION)
STLIB     = $(B_DIR)/$(STLIB_NAME)
PCFILE    = $(B_DIR)/$(PCFILE_NAME)
PCFILE_ST = $(B_DIR)/$(PCFILE_NAME_ST)

SONAME = $(SHLIB_BASE).$(MAJOR_VERSION)

SHLIB_FLAGS   = $(shell ./mh.sh $(DC) shared-flags $(SONAME))
EXTERNAL_LIBS = $(shell ./mh.sh $(DC) external-libs)
DEBUG_FLAGS   = $(shell ./mh.sh $(DC) debug-flags)
RELEASE_FLAGS = $(shell ./mh.sh $(DC) release-flags)
OTHER_FLAGS   = -J.

SOURCES   = $(shell find source/$(PROJECT) -name "*.d")
RESOURCES = $(shell find res/*)

DESTDIR         =
PREFIX          = usr
LIBDIR          = $(shell ./mh.sh $(DC) library-path)
INCDIR          = $(shell ./mh.sh $(DC) include-path)
INST_LIBDIR     = $(DESTDIR)/$(PREFIX)/$(LIBDIR)
INST_INCDIR_TOP = $(DESTDIR)/$(PREFIX)/$(INCDIR)
INST_INCDIR     = $(INST_INCDIR_TOP)/$(PROJECT)
INST_PCDIR      = $(INST_LIBDIR)/pkgconfig

SYS_CONF_DIR = $(DESTDIR)/etc/$(BASENAME)/

OUT = -of
ifeq ($(DC),gdc)
	OUT = -o
endif

.PHONY: doc examples install

all: shared static

libfuse-version-file:
	./make-libfuse-version-file.sh

shared: compilation-settings $(SHLIB)
	@echo "Compiled to" $(SHLIB)

static: compilation-settings $(STLIB)
	@echo "Compiled to" $(STLIB)

compilation-settings:
	@echo "Project:" $(PROJECT)
	@echo "Version:" $(VERSION)
	@echo "Major version:" $(MAJOR_VERSION)
	@echo ""
	@echo "Compiler:" $(DC)
	@echo "Options of debug compilation:  " $(DEBUG_FLAGS)
	@echo "Options of release compilation:" $(RELEASE_FLAGS)
	@echo "Options for shared library:    " $(SHLIB_FLAGS) $(EXTERNAL_LIBS)
	@echo ""

installation-settings:
	@echo "Library directory:" $(INST_LIBDIR)/
	@echo "Files to import:  " $(INST_INCDIR)/

$(OBJECT): libfuse-version-file $(SOURCES)
	mkdir -p $(B_DIR)
	$(DC) $(SOURCES) -c $(OUT)$@ $(DEBUG_FLAGS) $(OTHER_FLAGS)

$(SHLIB): $(OBJECT)
	$(DC) $^ $(OUT)$@ $(SHLIB_FLAGS) $(EXTERNAL_LIBS)

$(STLIB): $(OBJECT)
	ar r $@ $^

TESTFLAGS = -unittest -main
ifeq ($(DC),gdc)
	TESTFLAGS = -funittest -fmain
endif
test: $(SOURCES)
	$(DC) $^ $(OUT)$(B_DIR)/libapp $(TESTFLAGS) -J. $(EXTERNAL_LIBS)
	@echo "================================"
	$(B_DIR)/libapp
	@echo "================================"

# https://gitlab.com/os-18/hgen
doc:
	hgen source/ --macros ddoc-macros

dub:
	dub build --compiler=$(DC) -v --force

meson:
	meson meson_builddir --prefix=/$(PREFIX)
	cd meson_builddir ; meson compile

meson-install:
	cd meson_builddir ; meson install --destdir=$(DESTDIR)

clean:
	rm -rf build/ doc/ meson_builddir/ source/oxfuse/libfuse_version.d

install: installation-settings generate-pc
	mkdir -p "$(INST_INCDIR)" "$(INST_LIBDIR)" "$(INST_PCDIR)"
	cp $(SHLIB) "$(INST_LIBDIR)"
	cp $(STLIB) "$(INST_LIBDIR)"
	cp source/oxfuse/* "$(INST_INCDIR)" -r
	ln -sf $(SHLIB_WITH_VERSION) "$(INST_LIBDIR)/$(SHLIB_WITH_MAJOR_VERSION)"
	ln -sf $(SHLIB_WITH_MAJOR_VERSION) "$(INST_LIBDIR)/$(SHLIB_WITHOUT_VERSION)"
	cp $(PCFILE) $(PCFILE_ST) "$(INST_PCDIR)/"

uninstall: installation-settings
	rm -f "$(INST_LIBDIR)/$(SHLIB_WITH_VERSION)"
	rm -f "$(INST_LIBDIR)/$(SHLIB_WITH_MAJOR_VERSION)"
	rm -f "$(INST_LIBDIR)/$(SHLIB_WITHOUT_VERSION)"
	rm -f "$(INST_LIBDIR)/$(STLIB_NAME)"
	rm -rf "$(INST_INCDIR)"
	rm -rf $(SYS_CONF_DIR)
	rm -f "$(INST_PCDIR)/$(PCFILE_NAME)" "$(INST_PCDIR)/$(PCFILE_NAME_ST)"


DESCR_ENDING = "the $(shell echo $(DC) | tr a-z A-Z) version"
PC_DESCR     = "Description: $(DESCR), $(DESCR_ENDING)"
PC_LDIR      = $(subst //,/,/$(PREFIX)/$(LIBDIR))
PC_IDIR      = $(subst //,/,/$(PREFIX)/$(INCDIR))
LPATH_OPT    = $(shell ./mh.sh $(DC) libpath-opt)
LN_OPT       = $(shell ./mh.sh $(DC) libname-opt)
SHARED_OPTS  = $(LPATH_OPT)$(PC_LDIR) $(LN_OPT)$(BASENAME)
STATIC_OPTS  = $(LPATH_OPT)$(PC_LDIR) $(LN_OPT):lib$(BASENAME).a
generate-pc:
	mkdir -p $(B_DIR)
	# for dynamic version
	echo "Name: $(BASENAME)" > $(PCFILE)
	echo "$(PC_DESCR)" >> $(PCFILE)
	echo "Version: $(VERSION)" >> $(PCFILE)
	echo "Libs: $(SHARED_OPTS)" >> $(PCFILE)
	echo "Cflags: -I$(PC_IDIR)" >> $(PCFILE)
	# for static version
	echo "Name: $(BASENAME)-static" > $(PCFILE_ST)
	echo "$(PC_DESCR). Static library" >> $(PCFILE_ST)
	echo "Version: $(VERSION)" >> $(PCFILE_ST)
	echo "Libs: $(STATIC_OPTS) $(EXTERNAL_LIBS)" >> $(PCFILE_ST)
	echo "Cflags: -I$(PC_IDIR)" >> $(PCFILE_ST)


# EXAMPLES

EOPTS=$(DEBUG_FLAGS) $(EXTERNAL_LIBS) -Isource/

examples: example-mirror example-hello example-nullfs example-poll

example-mirror: $(OBJECT) examples/mirror.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EOPTS)

example-hello: $(OBJECT) examples/hello.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EOPTS)

example-nullfs: $(OBJECT) examples/nullfs.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EOPTS)

example-poll: $(OBJECT) examples/poll.d examples/poll_client.d
	$(DC) $(OBJECT) examples/poll.d $(OUT)$(B_DIR)/poll $(EOPTS)
	$(DC) examples/poll_client.d $(OUT)$(B_DIR)/poll-client
