#!/usr/bin/make --file

#
# \brief  Create Genode software development kit
# \author Emery Hemingway
# \date   2018-08-26
#

MAKEOVERRIDES =

PLATFORM = $(MAKECMDGOALS)

PLATFORMS = x86_32 x86_64

VERBOSE ?= @

GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/..)

VERSION := $(strip $(shell cat $(GENODE_DIR)/VERSION))

DEFAULT_SDK_DIR_PREFIX := $(GENODE_DIR)/build/sdk

DEFAULT_DEPOT_USER = genodelabs

sdk_usage:
	@echo
	@echo "Tool for preparing a Genode SDK"
	@echo
	@echo "usage:"
	@echo
	@echo "  create_sdk <platform> [SDK_DIR=<sdk-dir> DEPOT_USER=$(DEFAULT_DEPOT_USER)]"
	@echo
	@echo "  <platform> can be:"
	@$(foreach PLAT,$(PLATFORMS), \
	   echo "                     '$(PLAT)'";)
	@echo
	@echo "  The definition of SDK_DIR is optional. If specified,"
	@echo "  <sdk-dir> is the location of the directory to create."
	@echo "  If not specified, the directory will be created at"
	@echo "  $(DEFAULT_SDK_DIR_PREFIX)-<platform>-$(VERSION)."
	@echo

#
# Define default location of the build directory if not explicitly specified
#
SDK_DIR ?= $(DEFAULT_SDK_DIR_PREFIX)-$(PLATFORM)-$(VERSION)
DEPOT_USER ?= $(DEFAULT_DEPOT_USER)

TOOLCHAIN_DIR ?= /usr/local/genode/tool/current

#
# Sanity checks
#
ifneq ($(PLATFORM),)
   #
   # Check if platform is unknown
   #
   ifeq ($(filter $(PLATFORM),$(PLATFORMS)),)
      $(error Bad platform argument '$(PLATFORM)')
   endif

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

#
# SPECS definitions
#

SPECS(x86_32) := x86 x86_32 32bit
SPECS(x86_64) := x86 x86_64 64bit

ifneq (${SPECS(${PLATFORM})},)

GENODE_API_PKG_NAMES = \
	base so os \
	audio_in_session \
	audio_out_session \
	block_session \
	file_system_session \
	framebuffer_session \
	gpio_session \
	gpu_session \
	input_session \
	nic_session \
	nitpicker_session \
	platform_session \
	regulator_session \
	report_session \
	rtc_session \
	terminal_session \
	timer_session \
	uart_session \
	usb_session \
	vfs \

CONTRIB_API_PKG_NAMES = \
	libc \
	stdcxx \

SDK_BIN_PKG_NAME = \
	base-linux \
	vfs \
	libc \
	posix \
	stdcxx \

include $(GENODE_DIR)/tool/depot/mk/front_end.inc

depot_api_pkg = $(DEPOT_DIR)/$(DEPOT_USER)/api/$(1)/$(call recipe_version,api/$(1))

GENODE_API_PKGS  := $(foreach PKG,$(GENODE_API_PKG_NAMES),$(call depot_api_pkg,$(PKG)))
CONTRIB_API_PKGS := $(foreach PKG,$(CONTRIB_API_PKG_NAMES),$(call depot_api_pkg,$(PKG)))

BIN_PKGS := $(foreach X, $(SDK_BIN_PKG_NAME), \
	$(X)/$(call  recipe_version,src/$(X)))

DEPOT_BIN_PKGS := $(foreach X, $(BIN_PKGS), \
	$(DEPOT_DIR)/$(DEPOT_USER)/bin/$(PLATFORM)/$(X))

USER_SRC_NAME_VERSIONS := $(foreach X, $(BIN_PKGS), \
	$(DEPOT_USER)/src/$(X))

LINK_SCRIPTS = genode_dyn.dl genode_dyn.ld genode_rel.ld

SDK_LINK_SCRIPTS := $(addprefix $(SDK_DIR)/ld/,$(LINK_SCRIPTS))

PKGCONFIG_INS := $(wildcard $(GENODE_DIR)/tool/sdk/*.pc.in)
SDK_PKGCONFIGS := $(patsubst %.pc.in,$(SDK_DIR)/pkgconfig/%.pc,$(notdir $(PKGCONFIG_INS)))

$(SDK_DIR)/pkgconfig/%.pc: $(GENODE_DIR)/tool/sdk/%.pc.in
	$(VERBOSE)mkdir -p $(dir $@)
	$(VERBOSE)sed \
		-e 's|!SDK_DIR!|$(SDK_DIR)|' \
		-e 's|!TOOLCHAIN_DIR!|$(TOOLCHAIN_DIR)|' \
		-e 's|!VERSION!|$(VERSION)|' \
		< $< > $@

message: \
	$(SDK_DIR) \
	$(SDK_DIR)/archives \
	$(SDK_DIR)/include \
	$(SDK_DIR)/lib \
	$(SDK_DIR)/lib/ldso-startup.lib.a \
	$(SDK_LINK_SCRIPTS) \
	$(SDK_PKGCONFIGS) \

$(SDK_DIR)/archives:
	$(VERBOSE)for pkg in $(USER_SRC_NAME_VERSIONS); do echo $$pkg >> $@; done

# Rule to create all depot packages first
$(SDK_DIR): $(GENODE_API_PKGS) $(CONTRIB_API_PKGS) $(DEPOT_BIN_PKGS)
	$(VERBOSE)mkdir --parents $@

$(SDK_LINK_SCRIPTS): $(addprefix $(GENODE_DIR)/repos/base/src/ld/,$(LINK_SCRIPTS))
	$(VERBOSE)mkdir --parents $(dir $@)
	$(VERBOSE)cp $^ $(dir $@)

api_pkg_includes = \
	$(filter-out $(1)/include/spec,$(wildcard $(1)/include/*)) \
	$(foreach SPEC,${SPECS(${PLATFORM})},$(wildcard $(1)/include/spec/$(SPEC)/*)) \

cp_includes = \
	mkdir $(SDK_DIR)/include/$(1); \
	cp --recursive $(call api_pkg_includes,$(call depot_api_pkg,$(1))) $(SDK_DIR)/include/$(1);

GENODE_INCLUDES := $(foreach PKG,$(GENODE_API_PKGS),$(call api_pkg_includes,$(PKG)))

$(SDK_DIR)/include: $(SDK_DIR) $(GENODE_API_PKGS) $(CONTRIB_API_PKGS)
	$(VERBOSE)mkdir --parents $@
	$(VERBOSE)mkdir --parents $@/genode
	$(VERBOSE)cp --no-clobber --recursive $(GENODE_INCLUDES) $@/genode
	$(VERBOSE)$(foreach PKG,$(CONTRIB_API_PKG_NAMES),$(call cp_includes,$(PKG)))

$(SDK_DIR)/lib: $(SDK_DIR) $(DEPOT_BIN_PKGS)
	$(VERBOSE)mkdir --parents $@
	$(VERBOSE)cp --no-clobber \
		$(foreach PKG,$(DEPOT_BIN_PKGS),$(wildcard $(PKG)/*.lib.*)) $@

$(SDK_DIR)/lib/startup.o: $(GENODE_DIR)/repos/base/src/lib/ldso/startup/startup.cc $(SDK_DIR)/lib
	$(VERBOSE)$(CXX) -c $< -o $@

$(SDK_DIR)/lib/ldso-startup.lib.a: $(SDK_DIR)/lib/startup.o
	$(VERBOSE)$(AR) -rcs $@ $<

.INTERMEDIATE: $(SDK_DIR)/lib/startup.o

$(DEPOT_DIR)/%:
	$(VERBOSE)make --file $(GENODE_DIR)/tool/depot/create $*

endif

$(PLATFORM): message
message:
	@echo "Successfully created SDK directory at $(SDK_DIR)."

.PHONY: $(PLATFORM)