# This top-level Makefile can *not* be executed in parallel
.NOTPARALLEL:

SHELL=bash -o pipefail

CONFIG_CONFIG_SELECT_IN:=Config.select.in
CONFIG_CONFIG_LINUX_INSTALLED_IN:=Config.linux.installed.in
CONFIG_CONFIG_LEONTAR_SELECT_IN:=Config.leontar.select.in

.PHONY: default all preconfig postconfig xconfig gconfig menuconfig build \
        cfg_save cfg_load clean $(CONFIG_CONFIG_SELECT_IN) \
        $(CONFIG_CONFIG_LINUX_INSTALLED_IN) $(CONFIG_CONFIG_LEONTAR_SELECT_IN) \
        $(CONFIG_CONFIG_IN).processed

TOP:=$(CURDIR)
include common.mk

# We need to know in this makefile if linux is installed before it is noted in
# CONFIG_CONFIG_LINUX_INSTALLED_IN or saved to the top level .config.
#
# NOTE: Keep this check consistent with the CONFIG_CONFIG_LINUX_INSTALLED_IN target
ifneq ($(LB_LINUX_INSTALLED),y)
LB_LINUX_INSTALLED:=$(shell if grep -q "default y" $(CONFIG_CONFIG_LINUX_INSTALLED_IN) \
		      || test -e linux/$(LINUX_SRC); then echo "y"; fi)
endif

CFGDIR:=$(TOP)/gaisler/kconfig
CFGBINDIR:=$(CFGDIR)/build
CURRCFG:=$(TOP)/gaisler/currcfg
CONFIG_CONFIG_IN:=Config.in

# Needed by kconfig GUI
ifndef HOSTCC
HOSTCC:=gcc
else
endif
ifndef HOSTCXX
HOSTCXX:=g++
endif
HOSTCC:=$(shell which $(HOSTCC) || type -p $(HOSTCC) || echo gcc)
HOSTCXX:=$(shell which $(HOSTCXX) || type -p $(HOSTCXX) || echo g++)

export HOSTCC HOSTCXX

ifeq ($(LB_LINUX_INSTALLED),y)
default: build
else
default:
	@echo
	@echo " The Linux kernel needs to be installed first."
	@echo " Use one of the folling methods to install a Linux kernel"
	@echo
	@echo "  make xconfig          - Configure/Upgrade/Install using QT GUI"
	@echo "  make gconfig          - Configure/Upgrade/Install using GTK GUI"
	@echo "  make menuconfig       - Configure/Upgrade/Install using ncurses UI"
	@echo "  make -C linux install - Install Linux with default settings"
	@echo ""
	@echo "After Linux kernel installation, invoking the default make target will build all"
	@echo "configured components"
	@echo ""
	@exit 1
endif # LB_LINUX_INSTALLED - should envelop all dist/ calls

all: xconfig build

# configuration
# ---------------------------------------------------------------------------

$(CFGBINDIR)/%onf:
	mkdir -p $(@D)/lxdialog
	$(MAKE) CC="$(HOSTCC)" obj=$(@D) -C $(CFGDIR) -f Makefile.lb $(@F)

HOSTARCH=$(shell uname -m | \
	sed -e s/i.86/x86/ \
	    -e s/sun4u/sparc64/ \
	    -e s/arm.*/arm/ \
	    -e s/sa110/arm/ \
	    -e s/ppc64/powerpc/ \
	    -e s/ppc/powerpc/ \
	    -e s/macppc/powerpc/\
	    -e s/sh.*/sh/)

COMMON_CONFIG_ENV = \
	ARCH=sparc \
	KERNELVERSION=$(shell cd linux/$(LINUX_SRC) && make kernelversion | grep "^[0-9]") \
	BR2_VERSION_FULL=$(shell cd dist/buildroot/$(BUILDROOT_SRC); \
			   make -p help | grep BR2_VERSION_FULL | \
			   grep ":=" | awk '{ print $$3 }' ) \
	BR2_DEFCONFIG=$(shell readlink -m dist/buildroot/$(BUILDROOT_LEONLINK)/config/defconfig) \
	KCONFIG_AUTOCONFIG=$(CURRCFG)/auto.conf \
	KCONFIG_AUTOHEADER=$(CURRCFG)/autoconf.h \
	KCONFIG_TRISTATE=$(CURRCFG)/tristate.config \
	LINUXBUILD_CONFIG=$(TOP)/.config \
	HOSTARCH=$(HOSTARCH)

# Prepare Packages and others on a comming configuration, typcially
# prepare auto-generated menus etc.
preconfig:
	@echo PRERECONFIG
ifeq ($(LB_LINUX_INSTALLED),y)
	cd linux; make preconfig;
ifeq ($(LB_BUILDROOT),y)
	cd dist/buildroot; make preconfig
endif
endif # LB_LINUX_INSTALLED - should envelop all dist/ calls


# Execute stuff based on changes made to configuration.
postconfig:
	@echo POSTCONFIG

# After LB configuration utility but before and sub-diretory configuration
# utilities start.
	@echo PRE-SUBCONFIG
ifeq ($(LB_LINUX_INSTALLED),y)
	-cd linux; make pre_postconfig;
ifeq ($(LB_BUILDROOT),y)
	-cd dist/buildroot; make pre_postconfig
endif
endif # LB_LINUX_INSTALLED - should envelop all dist/ calls

# Run Post Configuration
ifeq ($(LB_LINUX_INSTALLED),y)
	 -cd linux; make postconfig;
ifeq ($(LB_BUILDROOT),y)
	 -cd dist/buildroot; make postconfig;
endif
endif # LB_LINUX_INSTALLED - should envelop all dist/ calls

	@echo
	@echo "Now do 'make build' to build the configuration"


PRECONF_FILENAME_TO_CONFIG=sed -e 's/[\/.]/_/g' | tr '[a-z]' '[A-Z]' | sed 's/^/LB_/'

# create a list of predefined configurations that are available in the gaisler/config subdirectory
$(CONFIG_CONFIG_SELECT_IN):
	echo  "choice" > $@.tmp
	echo "-tab-prompt \"Available predefined configurations\"" >> $@.tmp;\
	echo "config LB_NO_PRECONFIG" >> $@.tmp;\
	echo  "-tab-bool \"No predefined configuration\"" >> $@.tmp; \
	def="";\
	for f in `find gaisler/configs -type f -name lb_config*tar.bz2 | sort`; do \
		fc="`echo $${f} | $(PRECONF_FILENAME_TO_CONFIG)`"; \
		echo "config $${fc}" >> $@.tmp; \
		def="$${def}-tab-default \"$${f}\" if $${fc}-n-";\
		echo  "-tab-bool \"$$f\"" >> $@.tmp; \
	done; \
	echo "endchoice" >> $@.tmp; \
	echo    "config LB_SELECTED_AVAILABLE_CONFIG" >> $@.tmp; \
	echo  "-tab-string" >> $@.tmp;\
	echo  "$${def}" >> $@.tmp;\
	cat $@.tmp | sed -e 's@-tab-@\t@g' | sed -e 's@-n-@\n@g' > $@

# Never go back from y to n - it would only happen by manually fiddling with the
# linux source directory or source variable and could throw away the contents of
# the buildroot .config in the process when running top level x/g/menuconfig.
#
# NOTE: Keep this target consistent with the eary LB_LINUX_INSTALLED override in
# this Makefile
$(CONFIG_CONFIG_LINUX_INSTALLED_IN):
	if [ -e linux/$(LINUX_SRC) ]; then \
		echo -e "config LB_LINUX_INSTALLED" > $@; \
		echo -e "\tbool" >> $@; \
		echo -e "\tdefault y" >> $@; \
	  fi;

$(CONFIG_CONFIG_LEONTAR_SELECT_IN):
	rm -f $@ $@.tmp
	touch $@.tmp
	echo  "choice" > $@.tmp
	echo "-tab-prompt \"Available leon-linux archive files\"" >> $@.tmp
	tars="" ;\
	  for f in linux/reference/leon-linux-*.tar.bz2 ; do \
		if [ -e $$f ]; then \
			f="`echo $$f | sed 's@linux/reference/@@'`"; \
			fc="LB_LEONLINUX_TAR_`echo $${f} | tr '[a-z/]' '[A-Z_]'`"; \
			echo "config $${fc}" >> $@.tmp; \
			tars="$${tars}-tab-default \"$${f}\" if $${fc}-n-";\
			echo  "-tab-bool \"$$f\"" >> $@.tmp; \
		fi; \
	  done; \
	  echo "endchoice" >> $@.tmp; \
	  if [ -z "$$tars" ]; then \
		rm -f $@.tmp; \
		echo "comment \"No available leon-linux archive files\"" > $@.tmp; \
	  fi; \
	  echo "config LB_SELECTED_LEONLINUX_TAR" >> $@.tmp; \
	  echo "-tab-string" >> $@.tmp; \
	  echo "$${tars}-tab-default \"\"" >> $@.tmp
	cat $@.tmp | sed -e 's@-tab-@\t@g' | sed -e 's@-n-@\n@g' > $@

# activate the "execute" and "subsource" entries
$(CONFIG_CONFIG_IN).processed: $(CONFIG_CONFIG_IN) $(CONFIG_CONFIG_SELECT_IN) \
				$(CONFIG_CONFIG_LINUX_INSTALLED_IN) \
				$(CONFIG_CONFIG_LEONTAR_SELECT_IN)
	cp $< $@
ifeq ($(LB_LINUX_INSTALLED),y)
	sed -i -e 's@-linux-src-@$(LINUX_SRC)@g' $@
	sed -i -e 's@-linux-builddir-@$(LINUX_BUILDDIR)@g' $@
	sed -i -e 's@-buildroot-src-@$(BUILDROOT_SRC)@g' $@
	sed -i -e 's@-buildroot-builddir-@$(BUILDROOT_BUILDDIR)@g' $@
endif

CONFBIN=qconf
CONFARG=

doconfig: preconfig $(CFGBINDIR)/$(CONFBIN)
	mkdir -p $(CURRCFG)
	 # start xconfig until xconfig returns a value != 129, 129 means to execute a command and restart
	 # Recurse to make everything be reread, including makefile variables from .config files, upon restart
	source $(CURDIR)/path_prepare.sh; \
	  make $(CONFIG_CONFIG_IN).processed; \
	  $(COMMON_CONFIG_ENV) $(CFGBINDIR)/$(CONFBIN) $(CONFARG) $(CONFIG_CONFIG_IN).processed; \
	  returnval=$$?; \
	  echo "Return value is $${returnval}";\
	  if [ "$${returnval}" != 0 -a "$${returnval}" != "129" ]; then \
		exit $${returnval}; \
	  fi; \
	  $(MAKE) postconfig; \
	  if [ "$${returnval}" = "129" ]; then \
		test -f $(CURRCFG)/.config.cmd || rm -f $(CURRCFG)/.config; \
		$(MAKE) CONFBIN=$(CONFBIN) CONFARG=$(CONFARG) doconfig; \
	  fi;

xconfig:
	make CONFBIN=qconf doconfig

gconfig:
	make CONFBIN=gconf doconfig

menuconfig:
	make CONFBIN=mconf doconfig

oldconfig: preconfig $(CFGBINDIR)/conf
	make CONFBIN=conf CONFARG=--oldconfig doconfig
ifeq ($(LB_LINUX_INSTALLED),y)
	cd linux; make oldconfig
ifeq ($(LB_BUILDROOT),y)
	cd dist/buildroot; make oldconfig
endif
endif # LB_LINUX_INSTALLED - should envelop all dist/ calls

olddefconfig:
	bash -c 'yes "" | make oldconfig' # Prevent pipefail propagation due to -o pipefail
ifeq ($(LB_LINUX_INSTALLED),y)
	cd linux; make olddefconfig
ifeq ($(LB_BUILDROOT),y)
	cd dist/buildroot; make olddefconfig
endif
endif # LB_LINUX_INSTALLED - should envelop all dist/ calls

# Backup target when running older kernels or buildroots that does not have olddefconfig
defaultoldconfig:
	bash -c 'yes "" | make oldconfig' # Prevent pipefail propagation due to -o pipefail
ifeq ($(LB_LINUX_INSTALLED),y)
	cd linux; make defaultoldconfig
ifeq ($(LB_BUILDROOT),y)
	cd dist/buildroot; make defaultoldconfig
endif
endif # LB_LINUX_INSTALLED - should envelop all dist/ calls

unexport KCONFIG_AUTOCONFIG
unexport KCONFIG_AUTOHEADER
unexport KCONFIG_TRISTATE

build:
ifneq ($(LB_LINUX_INSTALLED),y)
	$(MAKE) default
endif
	@if [ ! -f $(CONFIG) ]; then \
	 echo ; \
	 echo "!!! Aborting: Configuration Missing" ; \
	 echo ; \
	 exit 1; \
	 fi;
#	Build Toolchain First
#	Build Distribution (and toolchain if configured so)
#	Build Linux Kernel
ifeq ($(LB_BUILDROOT),y)
	cd dist/buildroot; make build
endif
	cd linux; make build
	cd boot/mklinuximg; make build
ifeq ($(LB_MKPROM),y)
	cd boot/mkprom; make build
endif


# Save all configuarations of all packages into a TAR file
ifeq ($(CFG_FILE),)
cfg_save:
	@echo SAVE CFG: No configuration file specificed
cfg_load:
	@echo LOAD CFG: No configuration file specificed
else
CFG_DIR:=$(subst .tar.bz2,,$(CFG_FILE))
CFG_DIR2:=$(subst .tar.bz2,,$(shell basename $(CFG_FILE)))
cfg_save:
	@echo SAVE $(CFG_FILE)
	@echo CFG_DIR: $(CFG_DIR)
	@echo CFG_DIR2: $(CFG_DIR2)
ifneq ($(LB_NEWCONFIG),)
	@if [ -f $(CFG_FILE) -o -d $(CFG_DIR) ]; then \
	 echo ; \
	 echo "!!! Configuration file $(CFG_FILE) already exist" ; \
	 echo ; \
	 exit 1 ; \
	 fi;
endif
	@mkdir $(CFG_DIR)
# Let packages save their configuration files into the directory
ifeq ($(LB_BUILDROOT),y)
	cd dist/buildroot; make cfg_save CFG_BASE=$(abspath $(CFG_DIR))
endif
	cd linux; make cfg_save CFG_BASE=$(abspath $(CFG_DIR))
	cd boot/mklinuximg; make cfg_save CFG_BASE=$(abspath $(CFG_DIR))
ifeq ($(LB_MKPROM),y)
	cd boot/mkprom; make cfg_save CFG_BASE=$(abspath $(CFG_DIR))
endif
ifneq ($(LB_NEWCONFIG),)
	sed -ri "s/.?.?LB_GAISLER_CONFIGS_.*//" .config
	sed -ri "s/.?.?LB_NO_PRECONFIG.*/`echo $(CFG_FILE) | $(PRECONF_FILENAME_TO_CONFIG)`=y/" .config
endif
	cp -a .config $(CFG_DIR)/
	tar -C $(CFG_DIR)/.. -c $(CFG_DIR2) | bzip2 -9 -c > $(CFG_FILE)
	rm -rf $(CFG_DIR)
	@echo
	@echo Configuration file saved: $(CFG_FILE)
	@echo


# Restore all configuarations of all packages from a TAR file
cfg_load:
	@echo LOAD $(CFG_FILE)
	@if [ ! -f $(CFG_FILE) ]; then \
	 echo ; \
	 echo "!!! Configuration file $(CFG_FILE) does not exist" ; \
	 echo ; \
	 exit 1 ; \
	 fi;
	-@rm -rf "gaisler/tmp/$(CFG_DIR2)"
	mkdir -p gaisler/tmp
	tar -C gaisler/tmp -xf $(CFG_FILE)
	rm -f .config
	cp -a "gaisler/tmp/$(CFG_DIR2)/.config" .config
# Let packages save their configuration files into the directory
ifeq ($(LB_BUILDROOT),y)
	cd dist/buildroot; make cfg_load CFG_BASE=$(abspath gaisler/tmp/$(CFG_DIR2))
endif
	cd linux; make cfg_load CFG_BASE=$(abspath gaisler/tmp/$(CFG_DIR2))
	cd boot/mklinuximg; make cfg_load CFG_BASE=$(abspath gaisler/tmp/$(CFG_DIR2))
ifeq ($(LB_MKPROM),y)
	cd boot/mkprom; make cfg_load CFG_BASE=$(abspath gaisler/tmp/$(CFG_DIR2))
endif
	-@rm -rf gaisler/tmp/$(CFG_DIR2)
endif


# Clean target configuration
clean:
ifeq ($(LB_BUILDROOT),y)
	cd dist/buildroot; make clean
endif
	cd linux; make clean
	cd boot/mklinuximg; make clean
ifeq ($(LB_MKPROM),y)
	cd boot/mkprom; make clean
endif

# Convenience targets for running make targets in subdirectories from them
LINUX_TARGETS=$(shell grep "^[a-z_A-Z0-9-]*:" linux/Makefile | grep -v "^[^:]*:=" | \
		sed -E 's/^([^:]*):.*/\1/' | \
		grep -v -e ^cfg_ -e install -e default -e download -e checkdir -e _build \
			-e mkbuilddir -e upgrade -e postconfig -e preconfig)
LINUX_CONVENIENCE_TARGETS=$(patsubst %,linux-%,$(LINUX_TARGETS))
.phony $(LINUX_CONVENIENCE_TARGETS):
$(LINUX_CONVENIENCE_TARGETS):
	cd linux && make $(patsubst linux-%,%,$@)

linux: linux-build

ifeq ($(LB_BUILDROOT),y)
BUILDROOT_TARGETS=$(shell grep "^[a-z_A-Z0-9-]*:" dist/buildroot/Makefile | grep -v "^[^:]*:=" | \
		sed -E 's/^([^:]*):.*/\1/' | \
		grep -v -e ^cfg_ -e install -e default -e download -e checkdir -e _build \
			-e mkbuilddir -e upgrade -e postconfig -e preconfig)
BUILDROOT_CONVENIENCE_TARGETS=$(patsubst %,buildroot-%,$(BUILDROOT_TARGETS))
.phony $(BUILDROOT_CONVENIENCE_TARGETS):
$(BUILDROOT_CONVENIENCE_TARGETS):
	cd dist/buildroot && make $(patsubst buildroot-%,%,$@)

buildroot: buildroot-build
endif

MKLINUXIMG_TARGETS=$(shell grep "^[a-z_A-Z0-9-]*:" boot/mklinuximg/Makefile | grep -v "^[^:]*:=" | \
		sed -E 's/^([^:]*):.*/\1/' | \
		grep -v -e ^cfg_ -e install -e default -e download -e checkdir -e _build \
			-e mkbuilddir -e upgrade -e postconfig -e preconfig \
			-e config)
MKLINUXIMG_CONVENIENCE_TARGETS=$(patsubst %,mklinuximg-%,$(MKLINUXIMG_TARGETS))
.phony $(MKLINUXIMG_CONVENIENCE_TARGETS):
$(MKLINUXIMG_CONVENIENCE_TARGETS):
	cd boot/mklinuximg && make $(patsubst mklinuximg-%,%,$@)

mklinuximg: mklinuximg-build

ifeq ($(LB_MKPROM),y)
MKPROM_TARGETS=$(shell grep "^[a-z_A-Z0-9-]*:" boot/mkprom/Makefile | grep -v "^[^:]*:=" | \
		sed -E 's/^([^:]*):.*/\1/' | \
		grep -v -e ^cfg_ -e install -e default -e download -e checkdir -e _build \
			-e mkbuilddir -e upgrade -e postconfig -e preconfig \
			-e config)
MKPROM_CONVENIENCE_TARGETS=$(patsubst %,mkprom-%,$(MKPROM_TARGETS))
.phony $(MKPROM_CONVENIENCE_TARGETS):
$(MKPROM_CONVENIENCE_TARGETS):
	cd boot/mkprom && make $(patsubst mkprom-%,%,$@)

mkprom: mkprom-build
endif
