##### paths #####
BINDIR  = bin
INCDIR  = inc
OBJDIR  = obj
SRCDIR  = src

##### misc #####
QUIETLY = 1>nul 2>nul

##### sources, objects and libraries #####
BINNAME = liblfds611
LIB_BINARY = $(BINDIR)\$(BINNAME).lib
DLL_BINARY = $(BINDIR)\$(BINNAME).dll
SRCDIRS = lfds611_abstraction lfds611_freelist lfds611_liblfds lfds611_queue lfds611_ringbuffer lfds611_slist lfds611_stack
# TRD : lfds611_abstraction_cas.c lfds611_abstraction_dcas.c lfds611_abstraction_increment.c are inlined and are compiled by every C file
SOURCES = lfds611_abstraction_free.c lfds611_abstraction_malloc.c \
          lfds611_freelist_delete.c lfds611_freelist_get_and_set.c lfds611_freelist_new.c lfds611_freelist_query.c lfds611_freelist_pop_push.c \
          lfds611_liblfds_abstraction_test_helpers.c lfds611_liblfds_aligned_free.c lfds611_liblfds_aligned_malloc.c \
          lfds611_queue_delete.c lfds611_queue_new.c lfds611_queue_query.c lfds611_queue_queue.c \
          lfds611_ringbuffer_delete.c lfds611_ringbuffer_get_and_put.c lfds611_ringbuffer_new.c lfds611_ringbuffer_query.c \
          lfds611_slist_delete.c lfds611_slist_get_and_set.c lfds611_slist_link.c lfds611_slist_new.c \
          lfds611_stack_delete.c lfds611_stack_new.c lfds611_stack_push_pop.c lfds611_stack_query.c
OBJECTS = $(patsubst %.c,$(OBJDIR)/%.obj,$(notdir $(SOURCES)))
SYSLIBS = kernel32.lib

##### tools #####
MAKE    = make
MFLAGS  = 

CC      = cl
CBASE   = /nologo /W4 /WX /c "-I$(SRCDIR)" "-I$(INCDIR)" "/Fd$(BINDIR)\$(BINNAME).pdb" /DUNICODE /D_UNICODE /DWIN32_LEAN_AND_MEAN
CFREL   = /Ox /DNDEBUG
CFDBG   = /Od /Gm /Zi /D_DEBUG

AR      = lib
AFLAGS  = /nologo /subsystem:console /wx /verbose

LD      = link
LFBASE  = /dll /def:$(BINNAME).def /nologo /subsystem:console /wx /nodefaultlib /nxcompat
LFREL   = /incremental:no
LFDBG   = /debug "/pdb:$(BINDIR)\$(BINNAME).pdb"

##### variants #####
CFLAGS  = $(CBASE) $(CFDBG) /MTd
LFLAGS  = $(LFBASE) $(LFDBG)
CLIB    = libcmtd.lib

ifeq ($(MAKECMDGOALS),librel)
  CFLAGS  = $(CBASE) $(CFREL) /MT
  LFLAGS  = $(LFBASE) $(LFREL)
  CLIB    = libcmt.lib
endif

ifeq ($(MAKECMDGOALS),libdbg)
  CFLAGS  = $(CBASE) $(CFDBG) /MTd
  LFLAGS  = $(LFBASE) $(LFDBG)
  CLIB    = libcmtd.lib
endif

ifeq ($(MAKECMDGOALS),dllrel)
  CFLAGS  = $(CBASE) $(CFREL) /MD
  LFLAGS  = $(LFBASE) $(LFREL)
  CLIB    = msvcrt.lib
endif

ifeq ($(MAKECMDGOALS),dlldbg)
  CFLAGS  = $(CBASE) $(CFDBG) /MDd
  LFLAGS  = $(LFBASE) $(LFDBG)
  CLIB    = msvcrtd.lib
endif

##### search paths #####
vpath %.c $(patsubst %,$(SRCDIR)/%;,$(SRCDIRS))

##### implicit rules #####
$(OBJDIR)/%.obj : %.c
	$(CC) $(CFLAGS) "/Fo$@" $<

##### explicit rules #####
$(LIB_BINARY) : $(OBJECTS)
	$(AR) $(AFLAGS) $(OBJECTS) /out:$(LIB_BINARY)

$(DLL_BINARY) : $(OBJECTS)
	$(LD) $(LFLAGS) $(CLIB) $(SYSLIBS) $(OBJECTS) /out:$(DLL_BINARY)

##### phony #####
.PHONY : clean librel libdbg dllrel dlldbg

clean : 
	@erase /Q $(BINDIR)\$(BINNAME).* $(OBJDIR)\*.obj $(QUIETLY)

librel : $(LIB_BINARY)
libdbg : $(LIB_BINARY)

dllrel : $(DLL_BINARY)
dlldbg : $(DLL_BINARY)

