# Project properties

PROJECT_NAME = NBBiometricsCreateEnrollTemplateConsoleSampleC

CSRCS = \
    ./main.c

ifeq ($(shell uname), FreeBSD)
LDLIBS = -lNBBiometrics -lusb
else
LDLIBS = -lNBBiometrics -lusb-1.0
endif
# Common build properties

ifeq ($(DEBUG),yes)
  SKIP_STRIP ?= yes
endif

NATIVE_ARCH     ?= $(shell uname -m | sed 's/i.86/x86/')
NATIVE_OS       ?= $(shell uname)
NATIVE_PLATFORM ?= $(NATIVE_OS)_$(NATIVE_ARCH)

ifneq ($(CROSS),)
    ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep linux | sed -n '/linux/p'))
        BUILD_OS ?= Linux
        ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __ARMEL__))
            ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __SOFTFP__))
                BUILD_ARCH ?= armel
            endif
            BUILD_ARCH ?= armhf
        else ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __aarch64__))
            BUILD_ARCH ?= arm64
        else
            BUILD_ARCH ?= $(NATIVE_ARCH)
        endif
    else ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep FreeBSD | sed -n '/FreeBSD/p'))
        BUILD_OS ?= FreeBSD
        ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __amd64__))
            BUILD_ARCH ?= amd64
        else
            BUILD_ARCH ?= $(NATIVE_ARCH)
        endif
    else
        BUILD_OS ?= Embedded
        ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __arm__))
            ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __ARMEL__))
                ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __SOFTFP__))
                    BUILD_ARCH ?= armel
                endif
                    BUILD_ARCH ?= armhf
                endif
            endif
            BUILD_ARCH ?= arm
    endif
else
    ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep linux | sed -n '/linux/p'))
        BUILD_OS ?= Linux
        ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __ARMEL__))
            ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __SOFTFP__))
                BUILD_ARCH ?= armel
            endif
            BUILD_ARCH ?= armhf
        else ifneq (,$(shell $(CROSS)gcc -dM -E - < /dev/null | grep __aarch64__))
            BUILD_ARCH ?= arm64
        else
            BUILD_ARCH ?= $(NATIVE_ARCH)
        endif
    endif
endif

BUILD_OS        ?= $(NATIVE_OS)
BUILD_ARCH      ?= $(NATIVE_ARCH)
BUILD_PLATFORM  ?= $(BUILD_OS)_$(BUILD_ARCH)
OUTPUT_PLATFORM ?= $(BUILD_OS)/$(BUILD_ARCH)

BIN_DIR      ?= ../../Bin/$(OUTPUT_PLATFORM)
INCLUDE_DIR  ?= ../../Include/
LIB_DIR      ?= ../../Lib/$(OUTPUT_PLATFORM)
INSTALL_DIR  ?= $(BIN_DIR)/
OBJ_DIR      ?= Obj/$(if $(filter $(DEBUG),yes),Debug,Release)/$(BUILD_PLATFORM)/$(TARGET_NAME)/

# Compiling tools

CC      = $(CROSS)gcc
CXX     = $(CROSS)g++
LD      = $(CROSS)ld
OBJCOPY = $(CROSS)objcopy
OBJDUMP = $(CROSS)objdump
SIZE    = $(CROSS)size
STRIP   = $(CROSS)strip
LINKER  = $(if $(strip $(CXXSRCS)),$(CXX),$(CC))
CP      = cp -p
MKDIR   = mkdir -p
RM      = rm -f
LINK    = ln -s

CFLAGS   += -Wall -fno-strict-aliasing
CXXFLAGS += -Wall -fno-strict-aliasing -std=c++11 -static-libstdc++

ifneq ($(NATIVE_PLATFORM),$(BUILD_PLATFORM))
    CFLAGS_Linux_x86      += -m32
    CXXFLAGS_Linux_x86    += -m32
    LDFLAGS_Linux_x86     += -m32
    CFLAGS_Linux_x86_64   += -m64
    CXXFLAGS_Linux_x86_64 += -m64
    LDFLAGS_Linux_x86_64  += -m64
    
    CFLAGS_FreeBSD_x86      += -m32
    CXXFLAGS_FreeBSD_x86    += -m32
    LDFLAGS_FreeBSD_x86     += -m32
    CFLAGS_FreeBSD_x86_64   += -m64
    CXXFLAGS_FreeBSD_x86_64 += -m64
    LDFLAGS_FreeBSD_x86_64  += -m64
endif

ifeq ($(DEBUG), yes)
  CFLAGS   += -ggdb -g3 -D_DEBUG -DDEBUG
  CXXFLAGS += -ggdb -g3 -D_DEBUG -DDEBUG
  LDFLAGS  += -ggdb -g3
else
  CFLAGS   += -O3
  CXXFLAGS += -O3
  LDFLAGS  += -O3
  
  CFLAGS   += -DNDEBUG
  CXXFLAGS += -DNDEBUG
endif

ifeq ($(BUILD_OS),Linux)
  CFLAGS_Linux   += -D__LINUX__
  CXXFLAGS_Linux += -D__LINUX__
  CXXFLAGS_Linux += -static-libstdc++

  LDFLAGS_Linux  += -Wl,-rpath=$(LIB_DIR),-rpath-link=$(LIB_DIR)
  LDFLAGS_Linux  += -Wl,-rpath=../$(LIB_DIR),-rpath-link=../$(LIB_DIR)
  LDFLAGS_Linux  += -static-libgcc -L/usr/local/lib/ 
  
  LDLIBS_START   = -Wl,--start-group
  LDLIBS_END     = -Wl,--end-group
endif

ifeq ($(BUILD_OS),FreeBSD)
  CFLAGS_FreeBSD   += -D__FreeBSD__
  CXXFLAGS_FreeBSD += -D__FreeBSD__
  CXXFLAGS_FreeBSD += -static-libstdc++

  LDFLAGS_FreeBSD  += -Wl,-rpath=$(LIB_DIR),-rpath-link=$(LIB_DIR)
  LDFLAGS_FreeBSD  += -Wl,-rpath=../$(LIB_DIR),-rpath-link=../$(LIB_DIR)
  LDFLAGS_FreeBSD  += -static-libgcc -L/usr/local/lib/ 
  
  LDLIBS_START   = -Wl,--start-group
  LDLIBS_END     = -Wl,--end-group
endif

ifeq ($(BUILD_OS),Embedded)
  CFLAGS_Embedded   += -DEMBEDDED
  CFLAGS_Embedded += -specs=nosys.specs -specs=nano.specs -specs=rdimon.specs
  CFLAGS_Embedded_armel += -mcpu=cortex-m4 -mthumb -mfloat-abi=soft
  CFLAGS_Embedded_armhf += -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
  
  LDFLAGS_Embedded_armel += -mcpu=cortex-m4 -mthumb -mfloat-abi=soft
  LDFLAGS_Embedded_armhf += -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
  LDFLAGS_Embedded += -lc -lgcc -lrdimon
endif

CFLAGS   += -I$(INCLUDE_DIR)
CXXFLAGS += -I$(INCLUDE_DIR)
LDFLAGS  += -L$(LIB_DIR)

CFLAGS   += $(CFLAGS_$(BUILD_OS))
CFLAGS   += $(CFLAGS_$(BUILD_ARCH))
CFLAGS   += $(CFLAGS_$(BUILD_PLATFORM))

CXXFLAGS += $(CXXFLAGS_$(BUILD_OS))
CXXFLAGS += $(CXXFLAGS_$(BUILD_ARCH))
CXXFLAGS += $(CXXFLAGS_$(BUILD_PLATFORM))

LDFLAGS  += $(LDFLAGS_$(BUILD_OS))
LDFLAGS  += $(LDFLAGS_$(BUILD_ARCH))
LDFLAGS  += $(LDFLAGS_$(BUILD_PLATFORM))

LDLIBS   += $(LDLIBS_$(BUILD_OS))
LDLIBS   += $(LDLIBS_$(BUILD_ARCH))
LDLIBS   += $(LDLIBS_$(BUILD_PLATFORM))

OBJS += $(foreach OBJ,$(CSRCS:.c=.o),$(OBJ_DIR)$(OBJ))
OBJS += $(foreach OBJ,$(CXXSRCS:.cpp=.o),$(OBJ_DIR)$(OBJ))

TARGET_NAME ?= $(PROJECT_NAME)
TARGET      ?= $(OBJ_DIR)$(TARGET_NAME)

all: $(TARGET)

$(OBJ_DIR)$(PROJECT_NAME): $(OBJS)
	@$(if $(wildcard $(@D)),,$(MKDIR) $(@D))
	$(LINKER) $(LDFLAGS) $(OBJS) $(LDLIBS_START) $(LDLIBS) $(LDLIBS_END) -o $@
	$(RM) ./$(@F)
	$(LINK) $@ ./$(@F)
	
$(OBJ_DIR)$(PROJECT_NAME).bin: $(OBJS)
	@$(if $(wildcard $(@D)),,$(MKDIR) $(@D))
	$(LINKER) $(LDFLAGS) $(OBJS) $(LDLIBS_START) $(LDLIBS) $(LDLIBS_END) -o $@.elf
	$(OBJCOPY) -O binary $@.elf $@
	$(SIZE) $@.elf

$(OBJ_DIR)%.o: %.c
	@test -f $(dir $@) || $(MKDIR) $(dir $@)
	$(CC) $(CFLAGS) -c $< -o $@

$(OBJ_DIR)%.o: %.cpp
	@test -f $(dir $@) || $(MKDIR) $(dir $@)
	$(CXX) $(CXXFLAGS) -c $< -o $@

install: $(TARGET)
	$(if $(wildcard $(INSTALL_DIR)),,$(MKDIR) $(INSTALL_DIR))
	$(if $(wildcard $(INSTALL_DIR)$(notdir $(TARGET))),$(RM) -r $(INSTALL_DIR)$(notdir $(TARGET)))
	$(CP) -a $(TARGET) $(INSTALL_DIR)
ifneq ($(SKIP_STRIP),yes)
	$(STRIP) $(INSTALL_DIR)$(notdir $(TARGET))
endif

clean:
	$(RM) -r $(OBJ_DIR)
	$(RM) -r $(TARGET)

.PHONY: all clean install
