.PHONY: help umk ide theide package start all install uninstall clean
SHELL = /usr/bin/env bash

# Variables

comma := ,
empty:=
space:= $(empty) $(empty)
Dollar := $$
Dollar != if [ "$(Dollar)" = "$$" ]; then echo '$$$$'; else echo '$$$$$$$$' ; fi

# Commands

RM = rm -f
CP = cp -p
RM = rm -f
MKDIR = mkdir -p

# Targets

help:
	@echo 'The main purpose to this makefile is to build U++ tools (umk and theide).'
	@echo 'U++ tools run in sandboxed mode. The install target is mainly for package maintainers.'
	@echo 'See readme file for more details.'
	@echo ''
	@echo 'USAGE'
	@echo ''
	@echo 'Normal usage'
	@echo ''
	@echo '  make                     : show this help message'
	@echo '  make theide              : build U++ tools (theide and umk) and ask for permission to install missing depencies if any'
	@echo '  ./theide                 : start U++ ide'
	@echo ''
	@echo 'Avanced usage - Full list'
	@echo ''
	@echo '  make theide              [UPPOUT=<path>] [OutFile=<filename>]'
	@echo '                           [BUILD_METHOD=<method|full_filename>] [OPTIONS=-<option<,option<,...>>>] [FLAGS=+<flag<,flag><,...>>>]'
	@echo '                           [USE_NPROC=<true|false>] [AUTO_INSTALL_DEPENDENCY=<true|false>] [STOP_ON_MISSING_DEPENDENCY=<true|false>]'
	@echo ''
	@echo '  make ide|umk             [UPPOUT=<path>] [OutFile=<filename>] [MAKE=<executable>] [FLAGS=+<flag<,flag><,...>>>]'
	@echo '                           [CXX=<cxx_compiler>] [CXXFLAGS=<compiler_flags>] [CXXSTD=<compiler_mode>] [CINC=<path<;path<;..>>>'
	@echo '                           [LINKER=<executable>] [LDFLAGS=<linker_flags>] [LIBPATH=<path<;path<;..>>> [AR=<executable>]'
	@echo '                           [USE_NPROC=<true|false>] [AUTO_INSTALL_DEPENDENCY=<true|false>] [STOP_ON_MISSING_DEPENDENCY=<true|false>]'
	@echo ''
	@echo '  make package             [UPPOUT=<path>] ASSEMBLY=<nest<,nest><,...>> PACKAGE=<package>'
	@echo '                           [BUILD_METHOD=<method|full_filename>] [OPTIONS=-<option<,option<,...>>>] [FLAGS=+<flag<,flag><,...>>>]'
	@echo '                           [USE_NPROC=<true|false>] [AUTO_INSTALL_DEPENDENCY=<true|false>] [STOP_ON_MISSING_DEPENDENCY=<true|false>]'
	@echo ''
	@echo '  make start               [UPPOUT=<path>] ASSEMBLY=<nest<,nest><,...>> PACKAGE=<package>'
	@echo ''
	@echo '  make all                 [BUILD_METHOD=<method|full_filename>] [OPTIONS=-<option<,option<,...>>>] [FLAGS=+<flag<,flag><,...>>>]'
	@echo '                           [USE_NPROC=<true|false>] [AUTO_INSTALL_DEPENDENCY=<true|false>] [STOP_ON_MISSING_DEPENDENCY=<true|false>]'
	@echo ''
	@echo '  make install|uninstall   [DESTDIR=<path>] [prefix=<path>] [exec_prefix=<path>] [bindir=<path>] [datadir=<path>]'
	@echo '                           [docdir=<path>] [mandir=<path>] [mandir1=<path>]'
	@echo '                           [INSTALLDIC=<true|false>] [INSTALLDOC=<true|false>] [INSTALLMAN=<true|false>]'
	@echo ''
	@echo '  make clean               [UPPOUT=<path>]'
	@echo ''
	@echo 'PARAMETERS'
	@echo ''
	@echo ' * Global build parameters:'
	@echo '   - AUTO_INSTALL_DEPENDENCY    : ask and install missing build dependencies ( default: true )'
	@echo '   - STOP_ON_MISSING_DEPENDENCY : stop if the process can'"'"'t find a build depency ( default: true )'
	@echo '   - USE_NPROC                  : run several build jobs if possible ( default: true )'
	@echo ''
	@echo ' * parameters for targets using umk (theide, package, start and all):'
	@echo '   - ASSEMBLY      : nests separated by comma (example: ASSEMBLY="tutorial,uppsrc")'
	@echo '   - BUILD_METHOD  : CLANG(default), GCC or full_filename (file extension: .bm)'
	@echo '   - FLAGS         : umk build flags (ex: +GUI,LINUX,POSIX,SHARED)'
	@echo '   - OPTIONS       : umk build options (for more help, run "man ./uppsrc/umk/umk.1")'
	@echo '   - OutFile       : final binary name (default: $(Dollar)(PACKAGE)'
	@echo '   - PACKAGE       : package name'
	@echo '   - UPPOUT        : output directory (full path or relative to current directory)'
	@echo ''
	@echo ' * parameters for targets using makefiles (ide,umk):'
	@echo '   - AR            : archive-maintaining program'
	@echo '   - CINC          : default include directory list (use '"';'"' as separator)'
	@echo '   - CXX           : c++ compiler'
	@echo '   - CXXFLAGS      : c++ compiler flags'
	@echo '   - CXXSTD        : selected c++ mode (for -std value)'
	@echo '   - FLAGS         : umk build flags (ex: +GUI,LINUX,POSIX,SHARED)'
	@echo '   - LDFLAGS       : linker extra flags'
	@echo '   - LINKER        : linker binary name'
	@echo '   - LIBPATH       : library path list (use '"';'"' as separator)'
	@echo '   - OutFile       : final binary name (default: $(Dollar)(PACKAGE)'
	@echo '   - MAKE          : make binary name'
	@echo '   - UPPOUT        : output directory (full path or relative to uppsrc)'
	@echo ''
	@echo ' * install and uninstall related parameters:'
	@echo '   - DESTDIR       : installation root directory ; prepending each target directory to provides staged installs ( default: void )'
	@echo '   - prefix        : installation prefix ( default: /usr/local)'
	@echo '   - exec_prefix   : installation exec prefix for executables and subroutine ( default: /usr/local e.q $(Dollar)(prefix) )'
	@echo '   - bindir        : programs installation directory, executable that users can run ( default: /usr/local/bin e.g. $(Dollar)(exec_prefix)/bin )'
	@echo '   - datadir       : read-only idiosyncratic architecture-independent data files directory ( default: /usr/local/share e.g $(Dollar)(prefix)/share )'
	@echo '   - docdir        : documentation files directory ( default: /usr/local/share/doc e.g $(Dollar)(datadir)/doc )'
	@echo '   - mandir        : man pages top level directory ( default: /usr/local/share/man e.g $(Dollar)(datadir)/man )'
	@echo '   - mandir1       : man1 pages top level directory ( default: /usr/local/share/man/man1 e.g $(Dollar)(mandir)/man1 )'
	@echo '   - INSTALLDIC    : install dictionaries in $(Dollar)(datadir)/upp/speller/ ( default: true )'
	@echo '   - INSTALLDOC    : install documentation in $(Dollar)(docdir)/upp/ ( default: true )'
	@echo '   - INSTALLMAN    : install man pages in $(Dollar)(mandir1) ( default: true )'
	@echo ''
	@echo 'EXAMPLES'
	@echo ''
	@echo '  make                                                 : show this help message'
	@echo '  make theide                                          : build umk then use it to build theide with default parameters'
	@echo '  make theide OPTIONS=-rbsv                            : build umk then use it to build theide as release binary'
	@echo '  make theide BUILD_METHOD=CLANG FLAGS=+GUI,MT         : build umk then use it to build theide using CLANG and specific FLAGS'
	@echo '  make ide    AUTO_INSTALL_DEPENDENCY=false            : build theide using its makefile (not umk) and ignore not found dependencies'
	@echo '  make umk                                             : build umk only'
	@echo '  make umk MAKE=gmake CXX=g++ USE_NPROC=false          : build umk using gmake and g++, using only one job that can run simultaneously'
	@echo '  make package ASSEMBLY=examples,uppsrc PACKAGE=Button : build Button package from examples directory using examples,uppsrc assembly'
	@echo '  make start   ASSEMBLY=examples,uppsrc PACKAGE=Button : start Button binary if it exists'
	@echo '  make install                                         : install umk and theide in default POSIX directories (see install parameters for possible options)'
	@echo '  make install DESTDIR=/home/user/upp                  : install umk and theide in DESTDIR (see install parameters for possible options)'
	@echo '  make install prefix=/usr                             : install umk and theide in /usr POSIX directories (see install parameters for possible options)'
	@echo '  make clean                                           : delete $(Dollar)(UPPOUT) directory content and build binaries'

umk:
	@+./domake umk "UPPOUT=$(UPPOUT)" "OutFile=$(OutFile)" "MAKE=$(MAKE)" "FLAGS=$(FLAGS)" "CXX=$(CXX)" "CXXFLAGS=$(CXXFLAGS)" "CXXSTD=$(CXXSTD)" "CINC=$(CINC)" "LINKER=$(LINKER)" "LDFLAGS=$(LDFLAGS)" "LIBPATH=$(LIBPATH)" "AR=$(AR)" "USE_NPROC=$(USE_NPROC)" "AUTO_INSTALL_DEPENDENCY=$(AUTO_INSTALL_DEPENDENCY)" "STOP_ON_MISSING_DEPENDENCY=$(STOP_ON_MISSING_DEPENDENCY)"

ide: umk
	@+./domake ide "UPPOUT=$(UPPOUT)" "OutFile=$(OutFile)" "MAKE=$(MAKE)" "FLAGS=$(FLAGS)" "CXX=$(CXX)" "CXXFLAGS=$(CXXFLAGS)" "CXXSTD=$(CXXSTD)" "CINC=$(CINC)" "LINKER=$(LINKER)" "LDFLAGS=$(LDFLAGS)" "LIBPATH=$(LIBPATH)" "AR=$(AR)" "USE_NPROC=$(USE_NPROC)" "AUTO_INSTALL_DEPENDENCY=$(AUTO_INSTALL_DEPENDENCY)" "STOP_ON_MISSING_DEPENDENCY=$(STOP_ON_MISSING_DEPENDENCY)"

theide: umk
	@+./domake theide "UPPOUT=$(UPPOUT)" "OutFile=$(OutFile)" "BUILD_METHOD=$(BUILD_METHOD)" "OPTIONS=$(OPTIONS)" "FLAGS=$(FLAGS)" "USE_NPROC=$(USE_NPROC)" "AUTO_INSTALL_DEPENDENCY=$(AUTO_INSTALL_DEPENDENCY)" "STOP_ON_MISSING_DEPENDENCY=$(STOP_ON_MISSING_DEPENDENCY)"

package: umk
	@+./domake package "UPPOUT=$(UPPOUT)" "ASSEMBLY=$(ASSEMBLY)" "PACKAGE=$(PACKAGE)" "BUILD_METHOD=$(BUILD_METHOD)" "OPTIONS=$(OPTIONS)" "FLAGS=$(FLAGS)" "USE_NPROC=$(USE_NPROC)" "AUTO_INSTALL_DEPENDENCY=$(AUTO_INSTALL_DEPENDENCY)" "STOP_ON_MISSING_DEPENDENCY=$(STOP_ON_MISSING_DEPENDENCY)"

start:
	@+./domake start "UPPOUT=$(UPPOUT)" "ASSEMBLY=$(ASSEMBLY)" "PACKAGE=$(PACKAGE)"

all: umk
	@+@for i in $(wildcard examples/* reference/* tutorial/* bazaar/*) ; do \
		nest=$$(dirname "$$i") ; \
		package=$$(basename "$$i") ; \
		./domake package "UPPOUT=$(UPPOUT)" "ASSEMBLY=$$nest$(comma)uppsrc" "PACKAGE=$$package" "BUILD_METHOD=$(BUILD_METHOD)" "OPTIONS=$(OPTIONS)" "FLAGS=$(FLAGS)" "USE_NPROC=$(USE_NPROC)" "AUTO_INSTALL_DEPENDENCY=$(AUTO_INSTALL_DEPENDENCY)" "STOP_ON_MISSING_DEPENDENCY=$(STOP_ON_MISSING_DEPENDENCY)" ; \
	done

install:
	@+./domake install "DESTDIR=$(DESTDIR)" "prefix=$(prefix)" "exec_prefix=$(exec_prefix)" "bindir=$(bindir)" "datadir=$(datadir)" "docdir=$(docdir)" "mandir=$(mandir)" "mandir1=$(mandir1)" "INSTALLDIC=$(INSTALLDIC)" "INSTALLDOC=$(INSTALLDOC)" "INSTALLMAN=$(INSTALLMAN)"

uninstall:
	@+./domake uninstall "DESTDIR=$(DESTDIR)" "prefix=$(prefix)" "exec_prefix=$(exec_prefix)" "bindir=$(bindir)" "datadir=$(datadir)" "docdir=$(docdir)" "mandir=$(mandir)" "mandir1=$(mandir1)" "INSTALLDIC=$(INSTALLDIC)" "INSTALLDOC=$(INSTALLDOC)" "INSTALLMAN=$(INSTALLMAN)"

clean:
	-if [ "$(UPPOUT)" != "" -a "$(UPPOUT)" != "/" -a -d "$(UPPOUT)" ] ; then \
		$(RM) -r "$(UPPOUT)/"* ; \
	fi
	-$(RM) uppsrc/umk.out
	-$(RM) uppsrc/ide.out
	-$(RM) ide
	-$(RM) theide
	-$(RM) umk
