#!/usr/bin/make -f

#
# \brief  Prepare Genode build directory
# \author Christian Helmuth, Norman Feske
# \date   2008-08-14
#

MAKEOVERRIDES =

PLATFORM = $(MAKECMDGOALS)

PLATFORMS = x86_32  x86_64  panda  pbxa9  rpi arndale imx53_qsb imx53_qsb_tz \
            usb_armory wand_quad odroid_xu odroid_x2 zynq_qemu muen \
            riscv_spike linux

PLATFORMS_DEPR = linux_x86 linux_arm fiasco_x86 okl4_x86 pistachio_x86 \
                 nova_x86_32 nova_x86_64 hw_x86_64 foc_x86_32 foc_x86_64 \
                 sel4_x86_32 hw_panda foc_panda hw_pbxa9 foc_pbxa9 hw_rpi \
                 foc_rpi hw_arndale foc_arndale hw_imx53_qsb \
                 hw_imx53_qsb_tz hw_usb_armory hw_wand_quad hw_odroid_xu \
                 hw_zynq hw_x86_64_muen hw_riscv foc_odroid_x2

PLATFORM_ALT(linux_x86)       = linux
PLATFORM_ALT(linux_arm)       = linux
PLATFORM_ALT(fiasco_x86)      = x86_32
PLATFORM_ALT(okl4_x86)        = x86_32
PLATFORM_ALT(pistachio_x86)   = x86_32
PLATFORM_ALT(nova_x86_32)     = x86_32
PLATFORM_ALT(nova_x86_64)     = x86_64
PLATFORM_ALT(hw_x86_64)       = x86_64
PLATFORM_ALT(foc_x86_32)      = x86_32
PLATFORM_ALT(foc_x86_64)      = x86_64
PLATFORM_ALT(sel4_x86_32)     = x86_32
PLATFORM_ALT(hw_panda)        = panda
PLATFORM_ALT(foc_panda)       = panda
PLATFORM_ALT(hw_pbxa9)        = pbxa9
PLATFORM_ALT(foc_pbxa9)       = pbxa9
PLATFORM_ALT(hw_rpi)          = rpi
PLATFORM_ALT(foc_rpi)         = rpi
PLATFORM_ALT(hw_arndale)      = arndale
PLATFORM_ALT(foc_arndale)     = arndale
PLATFORM_ALT(hw_imx53_qsb)    = imx53_qsb
PLATFORM_ALT(hw_imx53_qsb_tz) = imx53_qsb_tz
PLATFORM_ALT(hw_usb_armory)   = usb_armory
PLATFORM_ALT(hw_wand_quad)    = wand_quad
PLATFORM_ALT(hw_odroid_xu)    = odroid_xu
PLATFORM_ALT(hw_zynq)         = zynq_qemu
PLATFORM_ALT(hw_x86_64_muen)  = muen
PLATFORM_ALT(hw_riscv)        = riscv_spike
PLATFORM_ALT(foc_odroid_x2)   = odroid_x2

usage:
	@echo
	@echo "Tool for preparing Genode build directories"
	@echo
	@echo "usage:"
	@echo
	@echo "  create_builddir <platform> [BUILD_DIR=<build-dir>]"
	@echo
	@echo "  <platform>   can be:"
	@$(foreach PLAT,$(PLATFORMS), \
	   echo "                  '$(PLAT)'";)
	@echo
	@echo "  the following <platform> arguments are deprecated:"
	@$(foreach PLAT,$(PLATFORMS_DEPR), \
	   printf "                  %-20s(use '$(PLATFORM_ALT($(PLAT)))')\n" "'$(PLAT)'";)
	@echo
	@echo "  The definition of BUILD_DIR is optional. If specified,"
	@echo "  <build-dir> is the location of the build directory to create."
	@echo "  If not specified, the build directory will be created at"
	@echo "  <genode-dir>/build/<platform>."
	@echo

#
# Determine Genode base directory based on the known location of the
# 'create_builddir' tool within the Genode source tree
#
GENODE_DIR ?= $(realpath $(dir $(MAKEFILE_LIST))/..)

#
# Define default location of the build directory if not explicitly specified
#
BUILD_DIR ?= $(GENODE_DIR)/build/$(PLATFORM)

#
# Sanity checks
#
ifneq ($(PLATFORM),)
   #
   # Check if platform is deprecated or unknown
   #
   ifneq ($(filter $(PLATFORM),$(PLATFORMS_DEPR)),)
      $(warning Platform '$(PLATFORM)' is deprecated, use '$(PLATFORM_ALT($(PLATFORM)))' instead)
   else ifeq ($(filter $(PLATFORM),$(PLATFORMS)),)
      $(error Bad platform argument '$(PLATFORM)')
   endif

   #
   # Check if build directory exists already
   #
   ifneq ($(wildcard $(BUILD_DIR)),)
      $(error Build directory '$(BUILD_DIR)' already exists)
   endif
endif

SHELL := bash


#
# Convert GENODE_DIR to an absolute directory because the user
# may have specified a '~'-relative location or a pwd-relative
# location.
#
GENODE_ABS_DIR := $(realpath $(shell echo $(GENODE_DIR)))

#
# Define absolute path to the contrib directory as written to the
# 'etc/build.conf' file. We use 'abs_path' instead of 'realpath' because the
# contrib directory may not exist when the build directory is created. In this
# case, 'realpath' would return an empty string.
#
ifeq ($(CONTRIB_DIR),)
CONTRIB_ABS_DIR := $$(GENODE_DIR)/contrib
else
CONTRIB_ABS_DIR := $(abspath $(shell echo $(CONTRIB_DIR)))
endif

$(BUILD_DIR)/etc:
	@mkdir -p $@

BUILD_CONF_X86_32 := run_qemu_iso run_opt_x86_32 run_boot_dir qemu_opt_x86 repos repos_x86
BUILD_CONF_X86_64 := run_qemu_iso run_opt_x86_64 run_boot_dir qemu_opt_x86 repos repos_x86
BUILD_CONF_PBXA9  := run_qemu run_opt_arm_hw_foc run_boot_dir qemu_opt_arm repos

BUILD_CONF(x86_32) := run_kernel_x86_32 $(BUILD_CONF_X86_32)
BUILD_CONF(x86_64) := run_kernel_x86_64 $(BUILD_CONF_X86_64)
BUILD_CONF(pbxa9)  := run_kernel_hw_foc $(BUILD_CONF_PBXA9)
BUILD_CONF(panda)        := run_kernel_hw_foc run_boot_dir repos
BUILD_CONF(rpi)          := run_kernel_hw_foc run_boot_dir repos
BUILD_CONF(arndale)      := run_kernel_hw_foc run_boot_dir repos
BUILD_CONF(imx53_qsb)    := run_kernel_hw     run_boot_dir repos
BUILD_CONF(imx53_qsb_tz) := run_kernel_hw     run_boot_dir repos
BUILD_CONF(usb_armory)   := run_kernel_hw     run_boot_dir repos
BUILD_CONF(wand_quad)    := run_kernel_wand_quad run_boot_dir repos
BUILD_CONF(odroid_xu)    := run_kernel_hw     run_boot_dir repos
BUILD_CONF(odroid_x2)    := run_kernel_foc    run_boot_dir repos
BUILD_CONF(zynq_qemu)    := run_kernel_hw run_qemu run_opt_hw run_boot_dir qemu_opt_arm repos
BUILD_CONF(muen)         := run_kernel_hw run_opt_muen        run_boot_dir repos repos_x86
BUILD_CONF(riscv_spike)  := run_kernel_hw run_opt_spike       run_boot_dir repos
BUILD_CONF(linux)        := run_kernel_linux repos

# deprecated platforms, to be removed
BUILD_CONF(linux_x86)       := run_kernel_linux repos
BUILD_CONF(linux_arm)       := run_kernel_linux repos
BUILD_CONF(fiasco_x86)      := run_kernel_fiasco    $(BUILD_CONF_X86_32)
BUILD_CONF(okl4_x86)        := run_kernel_okl4      $(BUILD_CONF_X86_32)
BUILD_CONF(pistachio_x86)   := run_kernel_pistachio $(BUILD_CONF_X86_32)
BUILD_CONF(nova_x86_32)     := run_kernel_nova      $(BUILD_CONF_X86_32)
BUILD_CONF(nova_x86_64)     := run_kernel_nova      $(BUILD_CONF_X86_64)
BUILD_CONF(hw_x86_64)       := run_kernel_hw        $(BUILD_CONF_X86_64)
BUILD_CONF(foc_x86_32)      := run_kernel_foc       $(BUILD_CONF_X86_32)
BUILD_CONF(foc_x86_64)      := run_kernel_foc       $(BUILD_CONF_X86_64)
BUILD_CONF(sel4_x86_32)     := run_kernel_sel4      $(BUILD_CONF_X86_32)
BUILD_CONF(sel4_x86_64)     := run_kernel_sel4      $(BUILD_CONF_X86_64)
BUILD_CONF(hw_panda)        := ${BUILD_CONF(panda)}
BUILD_CONF(foc_panda)       := run_kernel_foc run_boot_dir repos
BUILD_CONF(hw_pbxa9)        := ${BUILD_CONF(pbxa9)}
BUILD_CONF(foc_pbxa9)       := run_kernel_foc $(BUILD_CONF_PBXA9)
BUILD_CONF(hw_rpi)          := ${BUILD_CONF(rpi)}
BUILD_CONF(foc_rpi)         := run_kernel_foc run_boot_dir repos
BUILD_CONF(hw_arndale)      := ${BUILD_CONF(arndale)}
BUILD_CONF(foc_arndale)     := run_kernel_foc run_boot_dir repos
BUILD_CONF(hw_imx53_qsb)    := ${BUILD_CONF(imx53_qsb)}
BUILD_CONF(hw_imx53_qsb_tz) := ${BUILD_CONF(imx53_qsb_tz)}
BUILD_CONF(hw_usb_armory)   := ${BUILD_CONF(usb_armory)}
BUILD_CONF(hw_wand_quad)    := ${BUILD_CONF(wand_quad)}
BUILD_CONF(hw_odroid_xu)    := ${BUILD_CONF(odroid_xu)}
BUILD_CONF(hw_zynq)         := ${BUILD_CONF(zynq_qemu)}
BUILD_CONF(hw_x86_64_muen)  := ${BUILD_CONF(muen)}
BUILD_CONF(hw_riscv)        := ${BUILD_CONF(riscv_spike)}
BUILD_CONF(foc_odroid_x2)   := ${BUILD_CONF(odroid_x2)}

message: $(BUILD_DIR)/etc/build.conf
$(BUILD_DIR)/etc/build.conf:
	@echo "GENODE_DIR  := $(GENODE_ABS_DIR)" > $@
	@echo 'BASE_DIR    := $$(GENODE_DIR)/repos/base' >> $@
	@echo 'CONTRIB_DIR := $(CONTRIB_ABS_DIR)' >> $@
	@echo >> $@
	@for i in make_j run; do \
		cat $(GENODE_DIR)/tool/builddir/build.conf/$$i; done >> $@
	@for i in ${BUILD_CONF(${PLATFORM})}; do \
		cat $(GENODE_DIR)/tool/builddir/build.conf/$$i; done >> $@

message: $(BUILD_DIR)/Makefile
$(BUILD_DIR)/Makefile:
	@ln -sf $(GENODE_ABS_DIR)/tool/builddir/build.mk $@

$(BUILD_DIR)/etc/build.conf: $(BUILD_DIR)/etc
$(BUILD_DIR)/etc/specs.conf: $(BUILD_DIR)/etc

#
# Detect host CPU architecture (needed for creating Linux build directory that
# matches the host system)
#
UNAME_MACHINE := $(shell uname -m)

SPEC_ARCH(i686)   := x86_32
SPEC_ARCH(x86_64) := x86_64
SPEC_ARCH(armv6l) := armv_v6
SPEC_ARCH(armv7l) := armv_v7

HOST_SPEC_ARCH := ${SPEC_ARCH(${UNAME_MACHINE})}

#
# SPECS definitions
#

SPECS(x86_32)       := x86_32
SPECS(x86_64)       := x86_64
SPECS(pbxa9)        := pbxa9
SPECS(panda)        := panda
SPECS(rpi)          := rpi
SPECS(arndale)      := arndale
SPECS(imx53_qsb)    := imx53_qsb
SPECS(imx53_qsb_tz) := imx53_qsb trustzone
SPECS(usb_armory)   := usb_armory trustzone
SPECS(wand_quad)    := wand_quad
SPECS(odroid_xu)    := odroid_xu
SPECS(odroid_x2)    := odroid_x2
SPECS(zynq_qemu)    := zynq_qemu
SPECS(muen)         := muen x86_64
SPECS(riscv_spike)  := riscv
SPECS(linux)        := $(HOST_SPEC_ARCH)

# deprecated platforms
SPECS(linux_x86)       := $(HOST_SPEC_ARCH)
SPECS(linux_arm)       := $(HOST_SPEC_ARCH)
SPECS(fiasco_x86)      :=
SPECS(okl4_x86)        :=
SPECS(pistachio_x86)   :=
SPECS(nova_x86_32)     := nova_x86_32 x86_32 acpi
SPECS(nova_x86_64)     := nova_x86_64 x86_64 acpi
SPECS(hw_x86_64)       := ${SPECS(x86_64)}
SPECS(foc_x86_32)      := foc_x86_32 x86_32 acpi
SPECS(foc_x86_64)      := foc_x86_64 x86_64 acpi
SPECS(sel4_x86_32)     := sel4_x86_32 x86_32 acpi
SPECS(sel4_x86_64)     := sel4_x86_64 x86_64 acpi
SPECS(hw_panda)        := ${SPECS(panda)}
SPECS(foc_panda)       := foc_panda panda
SPECS(hw_pbxa9)        := ${SPECS(pbxa9)}
SPECS(foc_pbxa9)       := foc_pbxa9 pbxa9
SPECS(hw_rpi)          := ${SPECS(rpi)}
SPECS(foc_rpi)         := foc_rpi rpi
SPECS(hw_arndale)      := ${SPECS(arndale)}
SPECS(foc_arndale)     := foc_arndale arndale
SPECS(hw_imx53_qsb)    := ${SPECS(imx53_qsb)}
SPECS(hw_imx53_qsb_tz) := ${SPECS(imx53_qsb_tz)}
SPECS(hw_usb_armory)   := ${SPECS(usb_armory)}
SPECS(hw_wand_quad)    := ${SPECS(wand_quad)}
SPECS(hw_odroid_xu)    := ${SPECS(odroid_xu)}
SPECS(hw_zynq)         := ${SPECS(zynq_qemu)}
SPECS(hw_x86_64_muen)  := ${SPECS(muen)}
SPECS(hw_riscv)        := ${SPECS(riscv_spike)}
SPECS(foc_odroid_x2)   := foc_odroid_x2 odroid_x2

ifneq (${SPECS(${PLATFORM})},)
message: $(BUILD_DIR)/etc/specs.conf
$(BUILD_DIR)/etc/specs.conf:
	@echo "SPECS += ${SPECS(${PLATFORM})}" > $@
endif

$(PLATFORM): message
message:
	@echo "Successfully created build directory at $(BUILD_DIR)."
	@echo "Please adjust $(BUILD_DIR)/etc/build.conf according to your needs."

.PHONY: $(PLATFORM)
