
#########################################################
#                                                       #
#       FuturaSoft Topfield TAP Emulator                #
#       Makefile                                        #
#       Version 1.00                                    #
#                                                       #
#       Copyright (c) 2015 Martin Krämer                #
#                                                       #
#########################################################

# Options
#VERBOSE = 1				# you can see the compile options
#DEBUG = 1				# compile with -g -DDEBUG
MS_EXTENSIONS = 1		# enable Microsoft extensions to C/C++
AR002 = 1				# compile with AR002 code for decompression of TFP graphics format
SHARED_LIB = 1			# link program with shared library

# Default settings
CUR_DIR = $(abspath .)
SRC_DIR = $(CUR_DIR)
INC_DIR = $(CUR_DIR)/include
OBJ_DIR = $(CUR_DIR)/obj
OBJ_SO_DIR = $(OBJ_DIR)/so
LIB_DIR = $(CUR_DIR)/lib
BIN_DIR = $(CUR_DIR)/bin

# Auto detect object files and options
OBJS := $(patsubst $(SRC_DIR)/%.c, %.o, $(wildcard $(SRC_DIR)/*.c))
CXX_OBJS := $(patsubst $(SRC_DIR)/%.cpp, %.o, $(wildcard $(SRC_DIR)/*.cpp))
ifneq ($(CXX_OBJS),)
OBJS += $(CXX_OBJS)
endif

APP_OBJS = FsTapDummy.o
OBJS_S = tfemu.o
OBJS_SO = $(filter-out $(APP_OBJS) $(OBJS_S), $(OBJS))
LIB_NAME = tap
APP_NAME = tfemu

ifeq ($(FSTAP_DIR),)
FSTAP_DIR = /opt/fstap
ifneq ($(wildcard $(FSTAP_DIR)/),)
$(info [Auto detect FuturaSoft's tap directory at ... $(FSTAP_DIR)])
else
$(error FuturaSoft's tap directory not found)
endif
endif

# Compile options
ifeq ($(VERBOSE),)
Q = @
endif

ifneq ($(DEBUG),)
$(info [Compile with -g -DDEBUG])
MY_CFLAGS += -g -DDEBUG
endif

ifneq ($(MS_EXTENSIONS),)
$(info [Enable Microsoft extensions])
MY_CFLAGS += -fms-extensions
endif

ifneq ($(AR002),)
$(info [Compile with AR002 code])
ifeq ($(AR002_DIR),)
AR002_DIR = /opt/ar002
ifneq ($(wildcard $(AR002_DIR)/),)
$(info [Auto detect AR002 directory at ... $(AR002_DIR)])
else
$(error AR002 directory not found)
endif
endif
MY_CFLAGS += -DAR002
AR002_INCLUDE = $(AR002_DIR)
AR002_LIB = $(AR002_DIR)
AR002_OBJS = $(addprefix $(AR002_LIB)/, decode.o huf.o maketbl.o maketree.o)
endif

# Include directories and libraries
INCLUDE_DIRS = $(INC_DIR) $(AR002_INCLUDE) $(FSTAP_DIR)/include $(TAP_INCLUDE)
MY_CFLAGS += $(addprefix -I, $(INCLUDE_DIRS))
MY_CFLAGS += $(shell pkg-config --cflags gtk+-2.0)
MY_LDFLAGS += $(shell pkg-config --libs gtk+-2.0) -lgmodule-2.0 -lm

# Target objects
MY_APP_OBJS = $(addprefix $(OBJ_DIR)/, $(APP_OBJS))
MY_OBJS_S = $(addprefix $(OBJ_DIR)/, $(OBJS_S))
MY_OBJS_SO = $(addprefix $(OBJ_SO_DIR)/, $(OBJS_SO))
MY_LIB_S = $(LIB_DIR)/lib$(LIB_NAME)_s.a
MY_LIB_SO = $(LIB_DIR)/lib$(LIB_NAME).so
ifneq ($(SHARED_LIB),)
MY_LIB := $(MY_OBJS_S) $(FSTAP_DIR)/lib/emu/lib$(LIB_NAME).so
else
MY_LIB = $(MY_LIB_S)
STATIC_INFO = static #
endif
MY_OBJS_S += $(addprefix $(OBJ_DIR)/, $(OBJS_SO))
MY_APP = $(BIN_DIR)/$(APP_NAME)
MY_ZIP = $(APP_NAME).zip
ifneq ($(TFDISK),)
MY_ZIP := $(TFDISK)/$(MY_ZIP)
else
MY_ZIP := $(CUR_DIR)/$(MY_ZIP)
endif

# Commands
RANLIB = ranlib
MKDIR = mkdir -p
TOUCH = touch -c
ZIP = zip

# Flags
#MY_CFLAGS += -DLINUX -MD -W -Wall -O2
MY_CFLAGS += -DLINUX -MD -O2
CFLAGS += $(MY_CFLAGS)
CXXFLAGS += $(MY_CFLAGS)
ARFLAGS = -rvcsu
LDFLAGS += $(MY_LDFLAGS)

# Targets
.PHONY: all touch zip clean
.SUFFIXES:				# Delete the default suffixes
#.SECONDARY:

all: $(OBJ_DIR) $(OBJ_SO_DIR) $(LIB_DIR) $(BIN_DIR) $(MY_LIB_S) $(MY_LIB_SO) $(MY_APP)

touch:
	$(info [Touch all deployable files ...])
	$(Q)$(TOUCH) -d "00:00:00" $(SRC_DIR)/* $(INC_DIR)/* $(OBJ_DIR)/* $(OBJ_SO_DIR)/* $(LIB_DIR)/* $(BIN_DIR)/*

zip: $(MY_ZIP)

clean:
	$(info [Remove all generated files ...])
	$(Q)-$(RM) $(OBJ_DIR)/*.d $(OBJ_DIR)/*.o $(OBJ_SO_DIR)/*.d $(OBJ_SO_DIR)/*.o $(LIB_DIR)/*.a $(LIB_DIR)/*.so $(MY_APP) $(MY_ZIP)

$(OBJ_DIR) $(OBJ_SO_DIR) $(LIB_DIR) $(BIN_DIR):
	$(info [Make directory ... $@])
	$(Q)$(MKDIR) $@

# Implicit rule for building local apps
%.o : %.c
	$(info [Compile ... $<])
	$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

# Implicit rule for building local apps
%.o : %.cpp
	$(info [Compile ... $<])
	$(Q)$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

$(OBJ_DIR)/%.o : $(SRC_DIR)/%.c
	$(info [Compile ... $<])
	$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
	$(info [Compile ... $<])
	$(Q)$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

$(OBJ_SO_DIR)/%.o : $(SRC_DIR)/%.c
	$(info [Compile for shared ... $<])
	$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -DSHARED_LIB -fPIC -c $< -o $@

$(OBJ_SO_DIR)/%.o : $(SRC_DIR)/%.cpp
	$(info [Compile for shared ... $<])
	$(Q)$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DSHARED_LIB -fPIC -c $< -o $@

$(MY_LIB_S): $(MY_OBJS_S) $(AR002_OBJS)
    ifneq ($(findstring t, $(MAKEFLAGS)),)
	+$(TOUCH) $@
	+$(RANLIB) -t $@
    else
	$(info [Update archive ... $@])
	$(Q)$(AR) $(ARFLAGS) $@ $^
    endif

$(MY_LIB_SO): $(MY_OBJS_SO) $(AR002_OBJS)
	$(info [Link shared library ... $@])
	$(Q)$(CC) $+ $(LDFLAGS) -shared -o $@

$(MY_APP): $(MY_APP_OBJS) $(MY_LIB)
	$(info [Link program $(STATIC_INFO)... $@])
	$(Q)$(CC) $+ $(LDFLAGS) -o $@

$(MY_ZIP):
	$(info [Pack source files ... $@])
	$(Q)$(ZIP) -or $@ . -x $(patsubst $(CUR_DIR)/%, "%/*", $(OBJ_DIR) $(OBJ_SO_DIR) $(LIB_DIR) $(BIN_DIR)) $(patsubst $(CUR_DIR)/%, %, $(MY_ZIP)) "*.old" "*.fnt" "DataFiles/*" "ProgramFiles/*"

# Dependency file checking (created with gcc -M command)
-include $(OBJ_DIR)/*.d $(OBJ_SO_DIR)/*.d
