# Copyright(c) 2013-2016 OMICRON electronics GmbH. All rights reserved.

# Use the following flags to compile in debug and/or simulation mode
SPIDER2_CFLAGS += -O2
#SPIDER2_CFLAGS += -DDEBUG -g -O1
#SPIDER2_CFLAGS += -DDUMP_TX_PACKET
#SPIDER2_CFLAGS += -DDUMP_RX_PACKET
SPIDER2_CFLAGS += -DEXTRA_SYSFS_DEBUG
# We switch this on.  This means that when we run sparse, we are a
# little more pickey about endian things.
SPIDER2_CFLAGS += -D__CHECK_ENDIAN__

ifeq ($(src),)
SPIDER2_CFLAGS += -Isrc
SPIDER2_CFLAGS += -Isrc/shared/spider2_pcie_if/include
else
SPIDER2_CFLAGS += -I$(src)
SPIDER2_CFLAGS += -I$(src)/../src/shared/spider2_pcie_if/include
endif

BLDDIR = build

ifneq ($(KERNELRELEASE),)

obj-m += spider2.o

spider2-objs := \
	spider2_core.o \
	spider2_auxio.o \
	spider2_dspgoo.o \
	spider2_dspsam.o \
	spider2_dsing.o \
	spider2_dsing_uart.o

KBUILD_CFLAGS += $(SPIDER2_CFLAGS)

else

# Try to detect correct build settings automatically
ifneq (,$(findstring powerpc,$(shell $(CC) -dumpmachine)))
AUTO_ARCH      = powerpc
AUTO_KERNELDIR = $(shell cd `$(CC) -print-sysroot`/../usr/src/linux-headers-* && pwd)
AUTO_TOOLCHAIN = $(CC:gcc=)

AUTO_CC        = $(AUTO_TOOLCHAIN)gcc
AUTO_CXX       = $(AUTO_TOOLCHAIN)g++

else
AUTO_CC   = gcc
AUTO_CXX  = g++
AUTO_ARCH = x86
AUTO_KERNELDIR = /lib/modules/$(shell uname -r)/build
AUTO_TOOLCHAIN =
endif

# Auto settings can be overwritten from command line
CC        ?= $(AUTO_CC)
CXX       ?= $(AUTO_CXX)
ARCH      ?= $(AUTO_ARCH)
KERNELDIR ?= $(AUTO_KERNELDIR)
TOOLCHAIN ?= $(AUTO_TOOLCHAIN)

PROGS = test_dspeng test_dspgoo cmd_dspeng test_poeint test_uart binio_tool test_cableint afe_sim dsi_loopback

CHECKFILES = \
	spider2_core.c \
	spider2_private.h \
	spider2_defs.h \
	spider2_auxio.c \
	spider2_dspgoo.c \
	spider2_dspsam.c \
	spider2_dsing.c \
	spider2_dsing_uart.c

CHECKFILES_USER = \
	test_dspeng.c \
	test_dspgoo.c \
	test_poeint.c \
	test_cableint.cpp \
	test_uart.c \
	cmd_dspeng.c \
	binio_tool.c \
	helper_test.c \
	afe_sim.c \
	dsi_loopback.c

RESULTS = spider2.ko $(PROGS)

all: module userland disasm

CFLAGS = -Wall -Wextra $(SPIDER2_CFLAGS) -D_GNU_SOURCE \
		 -iquote$(KERNELDIR)/include -iquote$(KERNELDIR)/usr/include \
		$(EXTRA_CFLAGS)
CXXFLAGS = -Wall -Wextra $(SPIDER2_CFLAGS) -D_GNU_SOURCE \
		 -iquote$(KERNELDIR)/include -iquote$(KERNELDIR)/usr/include \
		$(EXTRA_CXXFLAGS)
LDFLAGS = $(EXTRA_LDFLAGS)

OBJDIR ?= $(BLDDIR)-$(shell $(CC) -dumpmachine | sed -e "s/-.*//")

module:
	@mkdir -p $(OBJDIR)
	@ln --symbolic --force --target-directory=$(OBJDIR) \
		$(addprefix ../,$(wildcard src/*.c src/*.h Makefile))
	$(MAKE) -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(TOOLCHAIN) M=$(abspath $(OBJDIR)) modules

userland: $(addprefix $(OBJDIR)/,$(PROGS))

$(OBJDIR)/cmd_dspeng: $(OBJDIR)/helper_test.o $(OBJDIR)/cmd_dspeng.o
	$(LINK.c) $^ -o $@

$(OBJDIR)/test_dspeng: $(OBJDIR)/helper_test.o $(OBJDIR)/test_dspeng.o
	$(LINK.c) $^ -o $@

$(OBJDIR)/test_dspgoo: $(OBJDIR)/test_dspgoo.o
	$(LINK.c) $^ -o $@ -pthread

$(OBJDIR)/test_poeint: $(OBJDIR)/test_poeint.o
	$(LINK.c) $^ -o $@ -pthread

$(OBJDIR)/test_cableint: $(OBJDIR)/test_cableint.o
	$(LINK.cc) $^ -o $@ -pthread -lboost_system -lboost_chrono

$(OBJDIR)/test_uart: $(OBJDIR)/test_uart.o
	$(LINK.c) $^ -o $@

$(OBJDIR)/binio_tool: $(OBJDIR)/binio_tool.o
	$(LINK.c) $^ -o $@

$(OBJDIR)/afe_sim: $(OBJDIR)/afe_sim.o
	$(LINK.c) $^ -o $@

$(OBJDIR)/dsi_loopback: $(OBJDIR)/dsi_loopback.o $(OBJDIR)/helper_test.o
	$(LINK.c) $^ -o $@ -pthread

$(OBJDIR)/%.o: src/%.c
	@mkdir -p $(@D)
	$(COMPILE.c) -std=c11 $(OUTPUT_OPTION) $<

$(OBJDIR)/%.o: src/%.cpp
	@mkdir -p $(@D)
	$(COMPILE.cc) $(OUTPUT_OPTION) $<

clean:
	rm -f $(OBJDIR)/*.o
	rm -f $(OBJDIR)/*.mod.c
	rm -f $(OBJDIR)/.*.cmd
	rm -rf $(OBJDIR)/.tmp_versions

distclean:
	rm -rf $(BLDDIR)-*

checkstyle:
	$(KERNELDIR)/scripts/checkpatch.pl \
		--ignore LINUX_VERSION_CODE \
		--ignore STATIC_CONST_CHAR_ARRAY \
		--ignore CONSTANT_COMPARISON \
		--file $(addprefix src/,$(CHECKFILES)) \
		--no-tree --emacs --terse

cppcheck:
	cppcheck --version
	cppcheck --enable=all --template gcc --inline-suppr \
		--std=c11 --platform=unix32 \
		--error-exitcode=2 $(CPPCHECK_EXTRA) \
		$(filter -I%,$(SPIDER2_CFLAGS)) \
		$(addprefix src/,$(filter-out %.h, \
			$(CHECKFILES) $(CHECKFILES_USER))) \
		-Dwait_event_interruptible_hrtimeout \
		$(addprefix -U,B1000000 B115200 B4000000 B460800 B500000 \
			B57600 B1152000 B576000 B921600 B1500000 B19200 \
			B2000000 B230400 B2500000 B3000000 B3500000 B38400 \
			EXTA EXTB)

check: checkstyle cppcheck

disasm: module
	$(TOOLCHAIN)objdump -S $(OBJDIR)/spider2.ko -r > $(OBJDIR)/spider2.disasm

doc:
	doxygen doxyfile

TARGET ?= /tmp

install:
ifndef IP
	$(error No IP address given, e.g. make install IP=172.1.1.1)
endif
	scp -r $(addprefix $(OBJDIR)/,$(RESULTS)) root@$(IP):$(TARGET)

endif
