# Base Makefile providing various standard targets
# Part of mklove suite but may be used independently.

MKL_RED?=	\033[031m
MKL_GREEN?=	\033[032m
MKL_YELLOW?=	\033[033m
MKL_BLUE?=	\033[034m
MKL_CLR_RESET?=	\033[0m

DEPS=		$(OBJS:%.o=%.d)

# TOPDIR is "TOPDIR/mklove/../" i.e., TOPDIR.
# We do it with two dir calls instead of /.. to support mklove being symlinked.
MKLOVE_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
TOPDIR = $(MKLOVE_DIR:mklove/=.)


# Convert LIBNAME ("libxyz") to "xyz"
LIBNAME0=$(LIBNAME:lib%=%)

# Silence lousy default ARFLAGS (rv)
ARFLAGS=

ifndef MKL_MAKEFILE_CONFIG
-include $(TOPDIR)/Makefile.config
endif

_UNAME_S := $(shell uname -s)
ifeq ($(_UNAME_S),Darwin)
	LIBFILENAME=$(LIBNAME).$(LIBVER)$(SOLIB_EXT)
	LIBFILENAMELINK=$(LIBNAME)$(SOLIB_EXT)
else
	LIBFILENAME=$(LIBNAME)$(SOLIB_EXT).$(LIBVER)
	LIBFILENAMELINK=$(LIBNAME)$(SOLIB_EXT)
endif

INSTALL?=		install
INSTALL_PROGRAM?=	$(INSTALL)
INSTALL_DATA?=		$(INSTALL) -m 644

prefix?=	/usr/local
exec_prefix?=	$(prefix)
bindir?=	$(exec_prefix)/bin
sbindir?=	$(exec_prefix)/sbin
libexecdir?=	$(exec_prefix)/libexec/  # append PKGNAME on install
datarootdir?=	$(prefix)/share
datadir?=	$(datarootdir)		 # append PKGNAME on install
sysconfdir?=	$(prefix)/etc
sharedstatedir?=$(prefix)/com
localestatedir?=$(prefix)/var
runstatedir?=	$(localestatedir)/run
includedir?=	$(prefix)/include
docdir?=	$(datarootdir)/doc/$(PKGNAME)
infodir?=	$(datarootdir)/info
libdir?=	$(prefix)/lib
localedir?=	$(datarootdir)/locale
pkgconfigdir?=	$(libdir)/pkgconfig
mandir?=	$(datarootdir)/man
man1dir?=	$(mandir)/man1
man2dir?=	$(mandir)/man2
man3dir?=	$(mandir)/man3
man4dir?=	$(mandir)/man4
man5dir?=	$(mandir)/man5
man6dir?=	$(mandir)/man6
man7dir?=	$(mandir)/man7
man8dir?=	$(mandir)/man8


# Checks that mklove is set up and ready for building
mklove-check:
	@if [ ! -f "$(TOPDIR)/Makefile.config" ]; then \
		printf "$(MKL_RED)$(TOPDIR)/Makefile.config missing: please run ./configure$(MKL_CLR_RESET)\n" ; \
		exit 1 ; \
	fi

%.o: %.c
	$(CC) -MD -MP $(CPPFLAGS) $(CFLAGS) -c $< -o $@

%.o: %.cpp
	$(CXX) -MD -MP $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@


lib: $(LIBFILENAME) $(LIBNAME).a $(LIBFILENAMELINK) lib-gen-pkg-config

$(LIBNAME).lds: #overridable

$(LIBFILENAME): $(OBJS) $(LIBNAME).lds
	@printf "$(MKL_YELLOW)Creating shared library $@$(MKL_CLR_RESET)\n"
	$(CC) $(LDFLAGS) $(LIB_LDFLAGS) $(OBJS) -o $@ $(LIBS)

$(LIBNAME).a:	$(OBJS)
	@printf "$(MKL_YELLOW)Creating static library $@$(MKL_CLR_RESET)\n"
	$(AR) rcs$(ARFLAGS) $@ $(OBJS)

$(LIBFILENAMELINK): $(LIBFILENAME)
	@printf "$(MKL_YELLOW)Creating $@ symlink$(MKL_CLR_RESET)\n"
	rm -f "$@" && ln -s "$^" "$@"


# pkg-config .pc file definition
ifeq ($(GEN_PKG_CONFIG),y)
define _PKG_CONFIG_DEF
prefix=$(prefix)
libdir=$(libdir)
includedir=$(includedir)

Name: $(LIBNAME)
Description: $(MKL_APP_DESC_ONELINE)
Version: $(MKL_APP_VERSION)
Cflags: -I$${includedir}
Libs: -L$${libdir} -l$(LIBNAME0)
Libs.private: $(LIBS)
endef

export _PKG_CONFIG_DEF

define _PKG_CONFIG_STATIC_DEF
prefix=$(prefix)
libdir=$(libdir)
includedir=$(includedir)

Name: $(LIBNAME)-static
Description: $(MKL_APP_DESC_ONELINE) (static)
Version: $(MKL_APP_VERSION)
Cflags: -I$${includedir}
Libs: -L$${libdir} $${libdir}/$(LIBNAME).a $(LIBS)
endef

export _PKG_CONFIG_STATIC_DEF

$(LIBNAME0).pc: $(TOPDIR)/Makefile.config
	@printf "$(MKL_YELLOW)Generating pkg-config file $@$(MKL_CLR_RESET)\n"
	@echo "$$_PKG_CONFIG_DEF" > $@

$(LIBNAME0)-static.pc: $(TOPDIR)/Makefile.config
	@printf "$(MKL_YELLOW)Generating pkg-config file $@$(MKL_CLR_RESET)\n"
	@echo "$$_PKG_CONFIG_STATIC_DEF" > $@

lib-gen-pkg-config: $(LIBNAME0).pc $(LIBNAME0)-static.pc

lib-clean-pkg-config:
	rm -f $(LIBNAME0).pc $(LIBNAME0)-static.pc
else
lib-gen-pkg-config:
lib-clean-pkg-config:
endif


$(BIN): $(OBJS)
	@printf "$(MKL_YELLOW)Creating program $@$(MKL_CLR_RESET)\n"
	$(CC) $(CPPFLAGS) $(LDFLAGS) $(OBJS) -o $@ $(LIBS)


file-check:
	@printf "$(MKL_YELLOW)Checking $(LIBNAME) integrity$(MKL_CLR_RESET)\n"
	@RET=true ; \
	for f in $(CHECK_FILES) ; do \
		printf "%-30s " $$f ; \
		if [ -f "$$f" ]; then \
			printf "$(MKL_GREEN)OK$(MKL_CLR_RESET)\n" ; \
		else \
			printf "$(MKL_RED)MISSING$(MKL_CLR_RESET)\n" ; \
			RET=false ; \
		fi ; \
	done ; \
	$$RET


lib-install:
	@printf "$(MKL_YELLOW)Install $(LIBNAME) to $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n"
	$(INSTALL) -d $$DESTDIR$(includedir)/$(PKGNAME) ; \
	$(INSTALL) -d $$DESTDIR$(libdir) ; \
	$(INSTALL) $(HDRS) $$DESTDIR$(includedir)/$(PKGNAME) ; \
	$(INSTALL) $(LIBNAME).a $$DESTDIR$(libdir) ; \
	$(INSTALL) $(LIBFILENAME) $$DESTDIR$(libdir) ; \
	[ -f "$(LIBNAME0).pc" ] && ( \
		$(INSTALL) -d $$DESTDIR$(pkgconfigdir) ; \
		$(INSTALL) -m 0644 $(LIBNAME0).pc $$DESTDIR$(pkgconfigdir) \
	) ; \
	[ -f "$(LIBNAME0)-static.pc" ] && ( \
		$(INSTALL) -d $$DESTDIR$(pkgconfigdir) ; \
		$(INSTALL) -m 0644 $(LIBNAME0)-static.pc $$DESTDIR$(pkgconfigdir) \
	) ; \
	(cd $$DESTDIR$(libdir) && ln -sf $(LIBFILENAME) $(LIBFILENAMELINK))

lib-uninstall:
	@printf "$(MKL_YELLOW)Uninstall $(LIBNAME) from $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n"
	for hdr in $(HDRS) ; do \
		rm -f $$DESTDIR$(includedir)/$(PKGNAME)/$$hdr ; done
	rm -f $$DESTDIR$(libdir)/$(LIBNAME).a
	rm -f $$DESTDIR$(libdir)/$(LIBFILENAME)
	rm -f $$DESTDIR$(libdir)/$(LIBFILENAMELINK)
	rmdir $$DESTDIR$(includedir)/$(PKGNAME) || true



bin-install:
	@printf "$(MKL_YELLOW)Install $(BIN) to $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n"
	$(INSTALL) -d $$DESTDIR$(bindir) && \
	$(INSTALL) $(BIN) $$DESTDIR$(bindir) 

bin-uninstall:
	@printf "$(MKL_YELLOW)Uninstall $(BIN) from $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n"
	rm -f $$DESTDIR$(bindir)/$(BIN)


generic-clean:
	rm -f $(OBJS) $(DEPS)

lib-clean: generic-clean lib-clean-pkg-config
	rm -f $(LIBNAME)*.a $(LIBFILENAME) $(LIBFILENAMELINK) \
		$(LIBNAME).lds

bin-clean: generic-clean
	rm -f $(BIN)
