TARGETS = Sign Verify Derive CreateCSR SignCMS VerifyCMS EncryptCMS DecryptCMS KeyWrap KeyUnwrap
TARGETS_S = KeyGeneration
TARGETS_H = TokenPreparation KeyDeleting

DIR = $(dir $(lastword $(MAKEFILE_LIST)))

ifneq (, $(findstring darwin, $(shell $(CC) -dumpmachine)))
	AUTO_TARGET_OS = osx
else
	AUTO_TARGET_OS = linux_glibc
endif

ifndef TARGET_OS
	TARGET_OS = $(AUTO_TARGET_OS)
endif


ifeq ($(TARGET_OS), osx)
	AUTO_TARGET_ARCH = x86_64
else ifneq (, $(findstring x86_64, $(shell ${CC} -dumpmachine)))
	AUTO_TARGET_ARCH = x86_64
else
	AUTO_TARGET_ARCH = x86
endif

ifndef TARGET_ARCH
	TARGET_ARCH = $(AUTO_TARGET_ARCH)
endif

ifeq ($(TARGET_OS), osx)
	PLATFORM_DIR = macos-x86_64
else
	PLATFORM_DIR = $(TARGET_OS)-$(TARGET_ARCH)
endif

BIN_DIR = $(DIR)../bin/$(PLATFORM_DIR)
OPENSSL_DIR = $(DIR)../..
PKCS11_DIR= $(DIR)../../..

CFLAGS += -x c
CFLAGS += -Werror -Wall -Wextra
ifeq ($(TARGET_OS), osx)
	CFLAGS += -F$(BIN_DIR) -isystem $(PKCS11_DIR)/pkcs11/include -I$(DIR)include -isystem $(OPENSSL_DIR)/openssl-shared-1.1/\${PLATFORM_DIR}/include
	LDFLAGS += -framework rtengine -L$(OPENSSL_DIR)/openssl-shared-1.1/$(PLATFORM_DIR)/lib -lcrypto -Wl,-rpath,@executable_path/
else
	CFLAGS += -isystem $(PKCS11_DIR)/pkcs11/include -isystem $(BIN_DIR)/include -I$(DIR)include -isystem $(OPENSSL_DIR)/openssl-shared-1.1/\${PLATFORM_DIR}/include
	LDFLAGS += -L$(BIN_DIR)/lib -L$(OPENSSL_DIR)/openssl-shared-1.1/$(PLATFORM_DIR)/lib -lrtengine -lcrypto -Wl,-rpath,\$$ORIGIN
endif


ifeq ($(DEBUG),y)
	CFLAGS += -O0 -g -DDEBUG
	TARGET_DIR_POSTFIX=-debug
else
	CFLAGS += -O2 -DNDEBUG
	TARGET_DIR_POSTFIX=-release
endif


ifeq ($(TARGET_OS), osx)
	COMMON_FLAGS += -arch x86_64
else ifeq ($(TARGET_ARCH), x86_64)
	COMMON_FLAGS += -m64
else
	COMMON_FLAGS += -m32
endif

CFLAGS_H = $(CFLAGS) -DHARDWARE_KEYS
LDFLAGS_H = $(LDFLAGS) -ldl

TARGET_DIR = $(DIR)out/$(PLATFORM_DIR)$(TARGET_DIR_POSTFIX)
TARGET_PATHS = $(foreach target,$(TARGETS),$(TARGET_DIR)/$(target))

TARGET_PATHS_S = $(foreach target,$(TARGETS_S),$(TARGET_DIR)/$(target))
TARGET_PATHS_H = $(foreach target,$(TARGETS_H),$(TARGET_DIR)/$(target))

.PHONY: all clean $(TARGETS) $(TARGETS_S) $(TARGETS_H)

all: $(TARGET_PATHS) $(TARGET_PATHS_S) $(TARGET_PATHS_H)

clean:
	rm -f $(subst $(TARGET_DIR_POSTFIX)/,$(TARGET_DIR_POSTFIX)/Hardware,$(TARGET_PATHS))
	rm -f $(subst $(TARGET_DIR_POSTFIX)/,$(TARGET_DIR_POSTFIX)/Software,$(TARGET_PATHS))
	rm -f ${TARGET_DIR}/libcrypto*
	rm -f ${TARGET_DIR}/test_*
	rm -f ${TARGET_DIR}/librtpkcs11ecp*
ifeq ($(TARGET_OS), osx)
	rm -fR ${TARGET_DIR}/rtengine.framework
else
	rm -f ${TARGET_DIR}/librtengine*
endif


$(TARGETS):%: $(TARGET_DIR)/%

.SECONDEXPANSION:
$(TARGET_PATHS_S):$(TARGET_DIR)/%: $$(DIR)$$(subst target,%,target/target.c) CopyLibraries CopyTestData
	@mkdir -p $(TARGET_DIR)
	$(CC) $(COMMON_FLAGS) $(CFLAGS) $< $(LDFLAGS) -o $(subst $(TARGET_DIR_POSTFIX)/,$(TARGET_DIR_POSTFIX)/Software,$@)

.SECONDEXPANSION:
$(TARGET_PATHS_H):$(TARGET_DIR)/%: $$(DIR)$$(subst target,%,target/target.c) CopyLibraries CopyTestData
	@mkdir -p $(TARGET_DIR)
	$(CC) $(COMMON_FLAGS) $(CFLAGS_H) $< $(LDFLAGS_H) -o $(subst $(TARGET_DIR_POSTFIX)/,$(TARGET_DIR_POSTFIX)/Hardware,$@)

.SECONDEXPANSION:
$(TARGET_PATHS):$(TARGET_DIR)/%: $$(DIR)$$(subst target,%,target/target.c) CopyLibraries CopyTestData
	@mkdir -p $(TARGET_DIR)
	$(CC) $(COMMON_FLAGS) $(CFLAGS) $< $(LDFLAGS) -o $(subst $(TARGET_DIR_POSTFIX)/,$(TARGET_DIR_POSTFIX)/Software,$@)
	$(CC) $(COMMON_FLAGS) $(CFLAGS_H) $< $(LDFLAGS_H) -o $(subst $(TARGET_DIR_POSTFIX)/,$(TARGET_DIR_POSTFIX)/Hardware,$@)

CopyLibraries: CopyOpenSSLLibs CopyRtEngineLib CopyRtPkcs11ecpLib

CopyOpenSSLLibs:
	@mkdir -p ${TARGET_DIR}
	cp -fP $(OPENSSL_DIR)/openssl-shared-1.1/\${PLATFORM_DIR}/lib/libcrypto* ${TARGET_DIR}

CopyRtEngineLib:
	@mkdir -p ${TARGET_DIR}
ifeq ($(TARGET_OS), osx)
	cp -fPR ${BIN_DIR}/rtengine.framework ${TARGET_DIR}
else
	cp -fP ${BIN_DIR}/lib/librtengine* ${TARGET_DIR}
endif

CopyRtPkcs11ecpLib:
	@mkdir -p ${TARGET_DIR}
	cp -fP $(PKCS11_DIR)/pkcs11/lib/${PLATFORM_DIR}/librt* ${TARGET_DIR}

CopyTestData:
	@mkdir -p ${TARGET_DIR}
	cp -fP $(DIR)/testData/* ${TARGET_DIR}
