# 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       = amalthea
DESCR         = "Small general Linux-specific library"
DC            = ldc2
VERSION       = $(shell cat source/$(PROJECT)/version)
MAJOR_VERSION = $(shell cat source/$(PROJECT)/version | cut -d'.' -f1)

BASENAME      = $(PROJECT)-$(DC)
LIBRARY       = lib$(BASENAME)
PKCONFIG_FILE = $(BASENAME).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)

GENERATED_PC = $(B_DIR)/$(PKCONFIG_FILE)

SONAME = $(SHLIB_BASE).$(MAJOR_VERSION)

SHLIB_FLAGS = $(shell ./mh.sh $(DC) shared-flags $(SONAME))
D_FLAGS     = $(shell ./mh.sh $(DC) debug-flags)
R_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
TESTFLAGS = -unittest -main
ifeq ($(DC),gdc)
	OUT = -o
	TESTFLAGS = -funittest -fmain
endif

.PHONY: all clean *install *-settings shared static test \
doc examples example* dub meson generate-pc

all: shared static

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:  " $(D_FLAGS)
	@echo "Options of release compilation:" $(R_FLAGS)
	@echo "Options for shared library:    " $(SHLIB_FLAGS)
	@echo ""

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

$(OBJECT): $(SOURCES)
	mkdir -p $(B_DIR)
	$(DC) $^ -c $(OUT)$@ $(D_FLAGS) $(OTHER_FLAGS)

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

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

test: $(SOURCES)
	$(DC) $^ $(OUT)$(B_DIR)/libapp $(TESTFLAGS) -J. $(R_FLAGS)
	@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
	cd meson_builddir ; meson compile

clean:
	rm -rf build/ doc/ meson_builddir/

install: installation-settings generate-pc
	mkdir -p "$(INST_INCDIR)" "$(INST_LIBDIR)" "$(INST_PCDIR)"
	cp $(SHLIB) "$(INST_LIBDIR)"
	cp $(STLIB) "$(INST_LIBDIR)"
	cp $(SOURCES) "$(INST_INCDIR)"
	ln -sf $(SHLIB_WITH_VERSION) "$(INST_LIBDIR)/$(SHLIB_WITH_MAJOR_VERSION)"
	ln -sf $(SHLIB_WITH_MAJOR_VERSION) "$(INST_LIBDIR)/$(SHLIB_WITHOUT_VERSION)"
	mkdir -p "$(SYS_CONF_DIR)"
	cp $(RESOURCES) "$(SYS_CONF_DIR)/" 2> /dev/null | true
	cp $(GENERATED_PC) "$(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)

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))
generate-pc:
	@echo PC_LDIR_RAW=$(PC_LDIR_RAW)
	@echo PC_LDIR=$(PC_LDIR)
	mkdir -p $(B_DIR)
	echo "Name: $(BASENAME)" > $(GENERATED_PC)
	echo "$(PC_DESCR)" >> $(GENERATED_PC)
	echo "Version: $(VERSION)" >> $(GENERATED_PC)
	echo "Libs: -L-L$(PC_LDIR) -L-l$(BASENAME)" >> $(GENERATED_PC)
	echo "Cflags: -I$(PC_IDIR)" >> $(GENERATED_PC)

examples: example-streebog example-dialog-example example-dialog-fselect \
example-dialog-menu example-encoding example-fileformats example-filelist \
example-stat example-cp example-langlocal-csv example-langlocal-ct \
example-langlocal example-net

EXAMPLE_OPTS=$(D_FLAGS) -Isource/

example-streebog: $(OBJECT) examples/crypto/streebog.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-dialog-example: $(OBJECT) examples/dialog/dialog_example.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-dialog-fselect: $(OBJECT) examples/dialog/dialog_fselect.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-dialog-menu: $(OBJECT) examples/dialog/dialog_menu.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-encoding: $(OBJECT) examples/encoding/encoding_and_net_example.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-fileformats: $(OBJECT) examples/fileformats/ff.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-filelist: $(OBJECT) examples/fs/filelist.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-stat: $(OBJECT) examples/fs/stat.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-cp: $(OBJECT) examples/fs/cp.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-xattr: $(OBJECT) examples/fs/xattributes.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-langlocal-csv: $(OBJECT) examples/langlocal/langlocal_csv_example.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-langlocal-ct: $(OBJECT) examples/langlocal/langlocal_ct_example.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS) -Jexamples/langlocal

example-langlocal: $(OBJECT) examples/langlocal/langlocal_example.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-net: $(OBJECT) examples/net/net_example.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-sys-anon-map: $(OBJECT) examples/sys/anon_map.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-sys-signal: $(OBJECT) examples/sys/signal.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-sys-mountpoints: $(OBJECT) examples/sys/mountpoints.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

example-sys-loops: $(OBJECT) examples/sys/loop_devices.d
	$(DC) $^ $(OUT)$(B_DIR)/$@ $(EXAMPLE_OPTS)

