# 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:=$(PWD)
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

default:
	@echo
	@echo " LINUX BUILD TARGETS"
	@echo " ==================="
	@echo
	@echo "  xconfig      - Configure/Upgrade LINUXBUILD using QT GUI"
	@echo "  gconfig      - same as xconfig but GTK GUI"
	@echo "  menuconfig   - same as xconfig but terminal menu config"
	@echo "  build        - build all enabled packages"
	@echo
	@echo " Run 'make xconfig first to download/install (upgrade) and configure"
	@echo " the LINUXBUILD packages. Then do 'make build' to build all selected"
	@echo " packages. Images will be available in output/images/:"
	@echo "  image        - Linux Kernel Virtual Addresses (do 'sym image' in"
	@echo "                 GRMON to load symbols)"
	@echo "  image.ram    - Linux Kernel RAM Image (use with GRMON/MKPROM2)"
	@echo "  image.prom   - Linux Kernel PROM Image. Boots from FLASH."
	@echo "  uImage       - Linux Kernel Image for U-Boot"
	@echo "  fs/          - Optional file systems images"
	@echo

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/$(LINUXSRC) && 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 }' ) \
	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

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:
	@if [ ! -f $(CONFIG) ]; then \
	 echo ; \
	 echo "!!! Aborting: Configuration Missing" ; \
	 echo ; \
	 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)"
	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
