# EtherPix library
#
# Copyright 2010-2017 Stefan Schuermans <stefan schuermans info>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

LIBTARGET := libetherpix
VER_MAJ   := 1
VER_MIN   := 3
VER_REV   := 0
VERSION   := $(VER_MAJ).$(VER_MIN).$(VER_REV)

CFLAGS     := -Wall -Wextra -Werror -O3
DEFINES    := -DETP_VER_MAJ=$(VER_MAJ) -DETP_VER_MIN=$(VER_MIN) \
              -DETP_VER_REV=$(VER_REV)
INCLUDES   := -Iinclude
SH_LDFLAGS :=
SH_LIBS    :=
EX_LDFLAGS := -Llib
EX_LIBS    := -letherpix -lm
STOW_DIR   := /usr/local/stow
DEF_PREFIX := /usr/local

OS_RAW := $(shell uname -s)
ifeq ($(OS_RAW),Linux)
  OS         := linux
  CC         := gcc
  AR         := ar
  RANLIB     := ranlib
  LEXT       := so
  LEXTSUF    := .$(VERSION)
  BSUF       :=
  INSTALL    := install
  CFLAGS     += -fPIC
  SH_LDFLAGS += -shared -Wl,-soname,$(LIBTARGET).so.$(VER_MAJ)
  EX_LDFLAGS += -Wl,-rpath,\$$ORIGIN/../../lib
  EX_LIBS    += -lpthread
endif

ifeq ($(OS_RAW),Darwin)
  OS         := darwin
  CC         := gcc
  AR         := ar
  RANLIB     := ranlib
  LEXT       := dylib
  LEXTSUF    :=
  BSUF       :=
  INSTALL    := install
  CFLAGS     += -fPIC
  SH_LDFLAGS += -dynamiclib
  EX_LIBS    += -lpthread
endif

ifeq ($(patsubst MINGW32%,MINGW32,$(OS_RAW)),MINGW32)
  OS         := mingw32
  CC         := gcc
  AR         := ar
  RANLIB     := ranlib
  LEXT       := dll
  LEXTSUF    :=
  BSUF       := .exe
  INSTALL    := install
  DEFINES    += -DWINDOWS
  SH_LDFLAGS += -shared
  SH_LIBS    += -lwsock32
  EX_LIBS    += -lwsock32
endif

ifeq ($(CROSS_WIN),1)
  OS         := mingw32
  CC         := x86_64-w64-mingw32-gcc
  AR         := ar
  RANLIB     := ranlib
  LEXT       := dll
  LEXTSUF    :=
  BSUF       := .exe
  INSTALL    := install
  DEFINES    += -DWINDOWS
  SH_LDFLAGS += -shared
  SH_LIBS    += -lwsock32
  EX_LIBS    += -lwsock32
endif

ifeq ($(OS),)
  $(error unsupported operating system $(OS_RAW))
endif

SRCS      := $(wildcard src/*.c)
SRCS_BASE := $(notdir $(patsubst %.c,%,$(SRCS)))
DEPS      := $(addprefix obj/,$(addsuffix .d,$(SRCS_BASE)))
OBJS      := $(addprefix obj/,$(addsuffix .o,$(SRCS_BASE)))

EX_SRCS      := $(wildcard examples/src/*.c)
EX_SRCS_BASE := $(notdir $(patsubst %.c,%,$(EX_SRCS)))
EX_DEPS      := $(addprefix examples/obj/,$(addsuffix .d,$(EX_SRCS_BASE)))
EX_OBJS      := $(addprefix examples/obj/,$(addsuffix .o,$(EX_SRCS_BASE)))
EX_TARGETS   := $(addprefix examples/bin/,$(addsuffix $(BSUF),$(EX_SRCS_BASE)))

TARGET    := lib/$(LIBTARGET).a
SH_TARGET := lib/$(LIBTARGET).$(LEXT)$(LEXTSUF)

ENV_PREFIX := $(shell echo $$PREFIX)
STOW_PREFIX := $(STOW_DIR)/libetherpix-$(VERSION)
ifneq ($(ENV_PREFIX),)
  PREFIX := $(ENV_PREFIX)
else
  ifeq ($(shell if [ -d $(STOW_DIR) ]; then echo stow; fi),stow)
    PREFIX := $(STOW_PREFIX)
  else
    PREFIX := $(DEF_PREFIX)
  endif
endif

.PHONY: all clean install uninstall ver pack
.SECONDARY:
.SUFFIXES:

all: $(DEPS) $(TARGET) $(SH_TARGET) $(EX_DEPS) $(EX_TARGETS)

ifneq ($(MAKECMDGOALS),clean)
  -include $(DEPS)
endif

obj:
	mkdir -p $@

lib:
	mkdir -p $@

obj/%.d: src/%.c | obj
	$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -MM -MT $(@:.d=.o) -o $@ $<

obj/%.o: src/%.c | obj
	$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -c -o $@ $<

$(TARGET): $(OBJS) | lib
	$(AR) cr $@ $(filter-out lib,$+)
	$(RANLIB) $@

$(SH_TARGET): $(OBJS) | lib
	$(CC) $(SH_LDFLAGS) -o $@ $+ $(SH_LIBS)
ifeq ($(OS),linux)
	cd $(dir $@); \
	  ln -sf $(notdir $@) \
	         $(patsubst %.$(VER_REV),%,$(notdir $@))
	cd $(dir $@); \
	  ln -sf $(patsubst %.$(VER_REV),%,$(notdir $@)) \
	         $(patsubst %.$(VER_MIN).$(VER_REV),%,$(notdir $@))
	cd $(dir $@); \
	  ln -sf $(patsubst %.$(VER_MIN).(VER_REV),%,$(notdir $@)) \
	         $(patsubst %.$(VER_MAJ).$(VER_MIN).$(VER_REV),%,$(notdir $@))
endif

examples/obj:
	mkdir -p $@

examples/bin:
	mkdir -p $@

examples/obj/%.d: examples/src/%.c | examples/obj
	$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -MM -MT $(@:.d=.o) -o $@ $<

examples/obj/%.o: examples/src/%.c | examples/obj
	$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -c -o $@ $<

examples/bin/%$(BSUF): examples/obj/%.o $(TARGET) $(SH_TARGET) | examples/bin
	$(CC) $(EX_LDFLAGS) -o $@ $< $(EX_LIBS)

clean:
	rm -rf obj lib examples/obj examples/bin

install: all
	$(INSTALL) -d $(PREFIX)/include/etherpix
	$(INSTALL) -m 644 -t $(PREFIX)/include/etherpix $(wildcard include/etherpix/*.h)
	$(INSTALL) -d $(PREFIX)/lib
	$(INSTALL) -m 644 -t $(PREFIX)/lib $(TARGET) $(SH_TARGET)
ifeq ($(OS),linux)
	ln -sf $(LIBTARGET).$(LEXT).$(VER_MAJ).$(VER_MIN).$(VER_REV) \
	   $(PREFIX)/lib/$(LIBTARGET).$(LEXT).$(VER_MAJ).$(VER_MIN)
	ln -sf $(LIBTARGET).$(LEXT).$(VER_MAJ).$(VER_MIN) \
	   $(PREFIX)/lib/$(LIBTARGET).$(LEXT).$(VER_MAJ)
endif

uninstall:
	rm -f $(PREFIX)/lib/$(notdir $(SH_TARGET))
	rm -f $(PREFIX)/lib/$(notdir $(TARGET))
	rm -rf $(PREFIX)/include/etherpix