# Copyright © 2016 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

.DEFAULT_GOAL := all

ifeq ($(.DEFAULT_GOAL),)
  $(warning no default goal is set)
endif

BOARD ?= arduino_101_factory
BOARD_NAME ?= arduino_101

ifeq ($(BOARD),qemu_x86)
BOARD_NAME = qemu_x86
endif

TARGET_ZEPHYR ?= ./targets/zephyr
TARGET_ZEPHYR_SRC_DIR = $(TARGET_ZEPHYR)/src

TYPE  ?= jerry-core
JERRYHEAP ?= 16
JERRYPROFILE ?= minimal

# Include functionality like regular expressions
# check Jerry script documentation
#
# -cp
# -cp_minimal
# -cp_minimal-mem_stats
# -mem_stats
# -mem_stress_test

ifndef ZEPHYR_BASE
$(error Missing Zephyr base, did you source zephyr-env.sh? )
endif

INTERM     = build/$(BOARD)/obj-$(BOARD)
OUTPUT     = build/$(BOARD)

-include $(ZEPHYR_BASE)/boards/$(BOARD_NAME)/Makefile.board
-include $(ZEPHYR_BASE)/scripts/Makefile.toolchain.$(ZEPHYR_GCC_VARIANT)

EXT_CFLAGS := -fno-asynchronous-unwind-tables -fno-omit-frame-pointer
EXT_CFLAGS += -fno-stack-protector -fno-strict-overflow -ffreestanding
EXT_CFLAGS += -fno-reorder-functions -fno-defer-pop -fdata-sections
EXT_CFLAGS += -ffunction-sections -fno-inline-functions

ifeq ($(BOARD),qemu_x86)
CONFIG_TOOLCHAIN_VARIANT = x86
CPU = i686
EXT_CFLAGS += -march=pentium
EXT_CFLAGS += -mpreferred-stack-boundary=2 -mno-sse
else ifeq ($(BOARD),qemu_cortex_m3)
CONFIG_TOOLCHAIN_VARIANT = arm
CPU = arm7-m
EXT_CFLAGS += -march=armv7-m -mthumb -mcpu=cortex-m3 -mabi=aapcs
else ifeq ($(BOARD),frdm_k64f)
CONFIG_TOOLCHAIN_VARIANT = arm
CPU = arm7e-m
EXT_CFLAGS += -march=armv7e-m -mthumb -mcpu=cortex-m4 -mabi=aapcs -mfloat-abi=hard -mfpu=fpv4-sp-d16
else ifeq ($(BOARD),em_starterkit)
# TODO: Tested only to build, untested to boot
CONFIG_TOOLCHAIN_VARIANT = arc
CPU = arc
EXT_CFLAGS += -mARCv2EM -mav2em -mno-sdata
else
CONFIG_TOOLCHAIN_VARIANT = iamcu
CPU = i686
EXT_CFLAGS += -march=lakemont -mtune=lakemont -miamcu -msoft-float
EXT_CFLAGS += -mpreferred-stack-boundary=2 -mno-sse
endif

EXT_CFLAGS += -Wall -Wno-format-zero-length -Wno-pointer-sign
EXT_CFLAGS += -Werror=format -Werror=implicit-int -Wno-unused-but-set-variable
EXT_CFLAGS += -Wno-main -Wno-strict-aliasing -Wno-old-style-declaration
EXT_CFLAGS += -Wno-error=format=
EXT_CFLAGS += -D_XOPEN_SOURCE=700
EXT_CFLAGS += -nostdlib

# Pass2
-include $(ZEPHYR_BASE)/scripts/Makefile.toolchain.$(ZEPHYR_GCC_VARIANT)

CC = $(CROSS_COMPILE)gcc

ZEPHYR_LIBC_INC = $(subst -I,,$(TOOLCHAIN_CFLAGS))
LIB_INCLUDE_DIR += -L $(CURDIR)/$(OUTPUT)

# TODO: There is a warning when compiling in some architectures related to __sputc_r
EXT_CFLAGS += -Wno-error=conversion
EXT_CFLAGS += $(LIB_INCLUDE_DIR)
EXT_CFLAGS += $(TOOLCHAIN_CFLAGS)

EXTERNAL_LIB = $(INTERM)/lib/libjerry-core.a
ZEPHYR_BIN = $(OUTPUT)/zephyr/zephyr.strip

LIBS = jerry-core

BUILD_CONFIG = O="$(OUTPUT)/zephyr" V=$(V) USER_LIBS="$(LIBS)" USER_LIB_INCLUDE_DIR="-L $(CURDIR)/$(INTERM)/lib" TARGET_ZEPHYR=$(TARGET_ZEPHYR)

.PHONY: all
all: jerry zephyr

$(EXTERNAL_LIB):
ifdef V
	@echo "- JERRY SCRIPT -------------------------------------------------"
endif
	mkdir -p $(INTERM)
	mkdir -p $(OUTPUT)
	cmake -B$(INTERM) -H./ \
 	 -DENABLE_LTO=OFF \
	 -DFEATURE_VALGRIND=OFF \
	 -DFEATURE_PROFILE=$(JERRYPROFILE) \
	 -DFEATURE_ERROR_MESSAGES=ON \
	 -DCMAKE_BUILD_TYPE=Release \
	 -DCMAKE_VERBOSE_MAKEFILE=$(V) \
	 -DMEM_HEAP_SIZE_KB=$(JERRYHEAP) \
	 -DEXTERNAL_CMAKE_C_COMPILER=$(CC) \
	 -DEXTERNAL_CMAKE_C_COMPILER_ID=GNU \
	 -DEXTERNAL_CMAKE_SYSTEM_PROCESSOR=$(CPU) \
	 -DJERRY_CMDLINE=OFF \
	 -DEXTERNAL_COMPILE_FLAGS="$(EXT_CFLAGS)" \
	 -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_external.cmake \
	 -DFEATURE_SNAPSHOT_EXEC=OFF \
	 -DENABLE_ALL_IN_ONE=OFF \
	 -DJERRY_LIBC=OFF \
	 $(EXT_JERRY_FLAGS)

	make -C $(INTERM) $(TYPE)$(VARIETY) V=1

$(ZEPHYR_BIN):
ifdef V
	@echo "- ZEPHYR -------------------------------------------------------"
endif
	make -f $(TARGET_ZEPHYR)/Makefile $(BUILD_CONFIG)
	@echo "Finished"
	@file $(OUTPUT)/zephyr/zephyr.strip
	@size $(OUTPUT)/zephyr/zephyr.strip

jerry: $(EXTERNAL_LIB)
	@touch $(EXTERNAL_LIB)

zephyr:	$(EXTERNAL_LIB) $(ZEPHYR_BIN)
	@touch $(ZEPHYR_BIN)

qemu:	$(EXTERNAL_LIB) $(ZEPHYR_BIN)
	make -f $(TARGET_ZEPHYR)/Makefile $(BUILD_CONFIG) qemu

flash:	$(EXTERNAL_LIB) $(OUTPUT)/zephyr/zephyr.strip
	make -f $(TARGET_ZEPHYR)/Makefile $(BUILD_CONFIG) flash

debugserver:
	make -f $(TARGET_ZEPHYR)/Makefile BOARD=$(BOARD_NAME) debugserver

dfu-x86: all
	@- dfu-util -a x86_app -D build/$(BOARD)/zephyr/zephyr.bin; \
	if [ $$? -eq 0 ] ; then echo "\nYour program will launch in 5 seconds." ; \
	else echo "\nProgram didn't flash, try pressing the reset buttons \nand wait a second for the bootloader to load, \nor flash again the factory bootloader."; fi

usage:
help:
	@echo Usage:
	@echo showconfig	 Show parameters and configuration
	@echo flash	         Flash into board
	@echo all	         Compile jerryscript and zephyr

showconfig:
	@echo "- CONFIGURATION ------------------------------------------------"
	@echo "INTERM           = $(INTERM)"
	@echo "OUTPUT           = $(OUTPUT)"
	@echo "CC               = $(CC) "
	@echo "BOARD            = $(ZEPHYR_BASE)/boards/$(BOARD)/Makefile.board "
	@echo "TOOLCHAIN        = $(ZEPHYR_BASE)/scripts/Makefile.toolchain.$(ZEPHYR_GCC_VARIANT) "
	@echo "TOOLCHAIN_CFLAGS = $(TOOLCHAIN_CFLAGS) "
	@echo "CROSS_COMPILE    = $(CROSS_COMPILE) "
	@echo "TOOLCHAIN_LIBS   = $(TOOLCHAIN_LIBS) "
	@echo "LIBS             = $(LIBS) "
	@echo "LIB_INCLUDE_DIR  = $(LIB_INCLUDE_DIR) "
	@echo "BUILD_CONFIG     = $(BUILD_CONFIG) "
	@echo "ZEPHYR_LIBC_INC  = $(ZEPHYR_LIBC_INC) "
	make -f $(TARGET_ZEPHYR)/Makefile $(BUILD_CONFIG) showconfig

clean:
	@echo "Clearing Jerryscript"
	@rm -rf $(OUTPUT)
	@rm -rf $(INTERM)
	@rm -f $(TARGET_ZEPHYR_SRC_DIR)/*.o
	@echo "Clearing Zephyr"
	make -f $(TARGET_ZEPHYR)/Makefile clean
	make -f $(TARGET_ZEPHYR)/Makefile pristine

mrproper:
	make -f $(TARGET_ZEPHYR)/Makefile mrproper