###################################
SRCDIR := src
BUILDDIR := build

CFLAGS +=
CPPFLAGS +=
LDFLAGS +=

###################################
# Where to install
INSTALL_PREFIX	= $(DESTDIR)/usr/local

###################################
# Where to find libraries, and their header files.
LIBPATHS	= -L/usr/local/lib
INCLUDE		= -I/usr/local/include
ifdef FFTW_PATH
LIBPATHS	+= -L$(FFTW_PATH)/lib
INCLUDE		+= -I$(FFTW_PATH)/include
endif
INCLUDE		+= -I/usr/include/pipewire-0.3 -I/usr/include/spa-0.2
INCLUDE 	+= -I$(SRCDIR)

###################################
# Compile options

# Package maintaners: it's recommended to activate SINGLE_MOD_PATH to disallow loading modules
# from any location
DEFINE 	   = #-DSINGLE_MOD_PATH=/usr/local/lib/brutefir


###################################
# FFTW3 libraries for single and double precision
FFTW_LIB	= -lfftw3 -lfftw3f

###################################
# Binaries
FLEX	= flex
LD	= gcc
CC	= gcc
CHMOD	= chmod

###################################
# Flags
CC_WARN		= -Wall -Wpointer-arith -Wshadow \
-Wcast-align -Wwrite-strings -Wstrict-prototypes \
-Wmissing-prototypes -Wmissing-declarations -Wnested-externs
CC_STD          = -std=c99 -D_POSIX_C_SOURCE=200809L
CC_FLAGS	= $(DEFINE) -O2 $(CC_STD) $(CFLAGS) $(CPPFLAGS)
CC_FPIC		= -fPIC
LD_SHARED	= -shared
CHMOD_REMOVEX	= -x

###################################
# Objects and libs for targets
BRUTEFIR_LIBS	= $(FFTW_LIB) -lm
BRUTEFIR_OBJS = \
    $(BUILDDIR)/brutefir.o \
    $(BUILDDIR)/fftw_convolver.o \
    $(BUILDDIR)/bfconcurrency.o \
    $(BUILDDIR)/bfconf.o \
    $(BUILDDIR)/bfrun.o \
    $(BUILDDIR)/compat.o \
    $(BUILDDIR)/firwindow.o \
    $(BUILDDIR)/emalloc.o \
    $(BUILDDIR)/shmalloc.o \
    $(BUILDDIR)/dai.o \
    $(BUILDDIR)/bfconf_lexical.o \
    $(BUILDDIR)/dither.o \
    $(BUILDDIR)/delay.o

BRUTEFIR_SSE_OBJS = $(BUILDDIR)/convolver_xmm.o

BFIO_FILE_OBJS	= $(BUILDDIR)/bfio_file.fpic.o

BFIO_ALSA_LIBS	= -lasound
BFIO_ALSA_OBJS	= $(BUILDDIR)/bfio_alsa.fpic.o $(BUILDDIR)/compat.fpic.o

BFIO_JACK_LIBS	= -ljack
BFIO_JACK_OBJS	= $(BUILDDIR)/bfio_jack.fpic.o

BFIO_PIPEWIRE_LIBS = -lpipewire-0.3
BFIO_PIPEWIRE_OBJS = $(BUILDDIR)/bfio_pipewire.fpic.o $(BUILDDIR)/compat.fpic.o

BFLOGIC_CLI_OBJS = $(BUILDDIR)/bflogic_cli.fpic.o $(BUILDDIR)/compat.fpic.o
BFLOGIC_EQ_OBJS = $(BUILDDIR)/bflogic_eq.fpic.o $(BUILDDIR)/emalloc.fpic.o $(BUILDDIR)/compat.fpic.o $(BUILDDIR)/shmalloc.fpic.o

BIN_TARGETS	= $(BUILDDIR)/brutefir
LIB_TARGETS	= $(BUILDDIR)/cli.bflogic $(BUILDDIR)/eq.bflogic $(BUILDDIR)/file.bfio
# These targets requires libs that are less portable
LIB_TARGETS	+= $(BUILDDIR)/alsa.bfio $(BUILDDIR)/jack.bfio $(BUILDDIR)/pipewire.bfio

###################################
# System-specific settings

UNAME_M         = $(shell uname -m)

ifeq ($(UNAME_M),i586)
BRUTEFIR_OBJS	+= $(BRUTEFIR_SSE_OBJS)
CC_FLAGS	+= -msse
endif
ifeq ($(UNAME_M),i686)
BRUTEFIR_OBJS	+= $(BRUTEFIR_SSE_OBJS)
CC_FLAGS	+= -msse
endif
ifeq ($(UNAME_M),x86_64)
BRUTEFIR_OBJS	+= $(BRUTEFIR_SSE_OBJS)
CC_FLAGS	+= -msse
endif
BRUTEFIR_LIBS	+= -ldl
LDMULTIPLEDEFS	= -Xlinker --allow-multiple-definition

TARGETS		= $(BIN_TARGETS) $(LIB_TARGETS)

###################################
# Targets

all: $(TARGETS)

$(BUILDDIR):
	mkdir -p $(BUILDDIR)

$(BUILDDIR)/%.fpic.o: $(SRCDIR)/%.c | $(BUILDDIR)
	$(CC) -o $@			-c $(LDFLAGS) $(INCLUDE) $(CC_FPIC) $(CC_WARN) $(CC_FLAGS) $<

$(BUILDDIR)/%.o: $(SRCDIR)/%.c | $(BUILDDIR)
	$(CC) -o $@			-c $(LDFLAGS) $(INCLUDE) $(CC_WARN) $(CC_FLAGS) $<

# special rule to avoid to get warnings from code generated by flex
$(BUILDDIR)/bfconf_lexical.o: $(BUILDDIR)/bfconf_lexical.c | $(BUILDDIR)
	$(CC) -o $@			-c $(LDFLAGS) $(INCLUDE) $(CC_FLAGS) $<

$(BUILDDIR)/%.c: $(SRCDIR)/%.lex | $(BUILDDIR)
	$(FLEX) -o$@ $<

$(BUILDDIR)/brutefir: $(BRUTEFIR_OBJS)
	$(CC) $(LDFLAGS) $(LIBPATHS) $(LDMULTIPLEDEFS) -o $@ $(BRUTEFIR_OBJS) $(BRUTEFIR_LIBS)

$(BUILDDIR)/alsa.bfio: $(BFIO_ALSA_OBJS)
	$(LD) $(LD_SHARED) $(LDFLAGS) $(CC_FPIC) $(LIBPATHS) -o $@ $(BFIO_ALSA_OBJS) $(BFIO_ALSA_LIBS) -lc
	$(CHMOD) $(CHMOD_REMOVEX) $@

$(BUILDDIR)/jack.bfio: $(BFIO_JACK_OBJS)
	$(LD) $(LD_SHARED) $(LDFLAGS) $(CC_FPIC) $(LIBPATHS) -o $@ $(BFIO_JACK_OBJS) $(BFIO_JACK_LIBS) -lc
	$(CHMOD) $(CHMOD_REMOVEX) $@

$(BUILDDIR)/pipewire.bfio: $(BFIO_PIPEWIRE_OBJS)
	$(LD) $(LD_SHARED) $(LDFLAGS) $(CC_FPIC) $(LIBPATHS) -o $@ $(BFIO_PIPEWIRE_OBJS) $(BFIO_PIPEWIRE_LIBS) -lc
	$(CHMOD) $(CHMOD_REMOVEX) $@

$(BUILDDIR)/file.bfio: $(BFIO_FILE_OBJS)
	$(LD) $(LD_SHARED) $(LDFLAGS) $(CC_FPIC) $(LIBPATHS) -o $@ $(BFIO_FILE_OBJS) -lc
	$(CHMOD) $(CHMOD_REMOVEX) $@

$(BUILDDIR)/cli.bflogic: $(BFLOGIC_CLI_OBJS)
	$(LD) $(LD_SHARED) $(LDFLAGS) $(CC_FPIC) $(LIBPATHS) -o $@ $(BFLOGIC_CLI_OBJS) -lc
	$(CHMOD) $(CHMOD_REMOVEX) $@

$(BUILDDIR)/eq.bflogic: $(BFLOGIC_EQ_OBJS)
	$(LD) $(LD_SHARED) $(LDFLAGS) $(CC_FPIC) $(LIBPATHS) -o $@ $(BFLOGIC_EQ_OBJS) -lc
	$(CHMOD) $(CHMOD_REMOVEX) $@

install: $(BIN_TARGETS) $(LIB_TARGETS)
	install -d $(INSTALL_PREFIX)/bin $(INSTALL_PREFIX)/lib/brutefir
	install $(BIN_TARGETS) $(INSTALL_PREFIX)/bin
	install $(LIB_TARGETS) $(INSTALL_PREFIX)/lib/brutefir

clean:
	rm -rf $(BUILDDIR)/bfconf_lexical.c $(BRUTEFIR_OBJS) $(BFIO_FILE_OBJS) $(BFLOGIC_CLI_OBJS) \
$(BFLOGIC_EQ_OBJS) $(BFIO_ALSA_OBJS) $(BFIO_JACK_OBJS) $(BFIO_PIPEWIRE_OBJS) $(TARGETS)
	rmdir $(BUILDDIR)
