# compiler executables --------------------------------------------------------

CC = gcc
CXX = g++
FC = gfortran

# language standard -----------------------------------------------------------

# CSTD = -std=c89
  CSTD = -std=c99
  CXXSTD = -std=c++98
# CXXSTD = -std=c++11
  FSTD = -std=f2018 -ffree-form -Wno-c-binding-type

# common compiler options -----------------------------------------------------

OPTFLAGS = -O3
FLAGS = $(OPTFLAGS) -fPIC -pedantic -Wall -Wextra
LDFLAGS =
SOFLAGS =

# OpenMP compiler options -----------------------------------------------------

# do not comment out; use "make ZFP_WITH_OPENMP=0" to disable OpenMP
OMPFLAGS = -fopenmp

# Apple clang OpenMP options
# OMPFLAGS = -Xclang -fopenmp

# optional compiler macros ----------------------------------------------------

# use smaller bit stream word type for finer rate granularity;
# can bet set on command line, e.g., "make BIT_STREAM_WORD_TYPE=uint8"
# DEFS += -DBIT_STREAM_WORD_TYPE=uint8
# DEFS += -DBIT_STREAM_WORD_TYPE=uint16
# DEFS += -DBIT_STREAM_WORD_TYPE=uint32
# DEFS += -DBIT_STREAM_WORD_TYPE=uint64

# reduce bias and slack in errors; can be set on command line, e.g.,
# "make ZFP_ROUNDING_MODE=ZFP_ROUND_FIRST"
# DEFS += -DZFP_ROUNDING_MODE=ZFP_ROUND_NEVER
# DEFS += -DZFP_ROUNDING_MODE=ZFP_ROUND_FIRST
# DEFS += -DZFP_ROUNDING_MODE=ZFP_ROUND_LAST
# DEFS += -DZFP_WITH_TIGHT_ERROR

# treat subnormals as zero to avoid overflow; can be set on command line, e.g.,
# "make ZFP_WITH_DAZ=1"
# DEFS += -DZFP_WITH_DAZ

# use long long for 64-bit types
# DEFS += -DZFP_INT64='long long' -DZFP_INT64_SUFFIX='ll'
# DEFS += -DZFP_UINT64='unsigned long long' -DZFP_UINT64_SUFFIX='ull'

# cache alignment
# DEFS += -DZFP_CACHE_LINE_SIZE=256

# enable strided access for progressive zfp streams
# DEFS += -DBIT_STREAM_STRIDED

# use aligned memory allocation
# DEFS += -DZFP_WITH_ALIGNED_ALLOC

# use two-way skew-associative cache
# DEFS += -DZFP_WITH_CACHE_TWOWAY

# use faster but more collision prone hash function
# DEFS += -DZFP_WITH_CACHE_FAST_HASH

# count cache misses
# DEFS += -DZFP_WITH_CACHE_PROFILE

# build targets ---------------------------------------------------------------

# default targets
BUILD_CFP = 0
BUILD_ZFORP = 0
BUILD_UTILITIES = 1
BUILD_EXAMPLES = 0
BUILD_TESTING = 1
BUILD_SHARED_LIBS = 0

# build all targets?
ifdef BUILD_ALL
  ifneq ($(BUILD_ALL),0)
    BUILD_CFP = 1
    BUILD_ZFORP = 1
    BUILD_UTILITIES = 1
    BUILD_EXAMPLES = 1
    BUILD_TESTING = 1
  endif
endif

# build shared libraries?
ifneq ($(BUILD_SHARED_LIBS),0)
  LIBRARY = shared
  LIBZFP = libzfp.so
  LIBCFP = libcfp.so
else
  LIBRARY = static
  LIBZFP = libzfp.a
  LIBCFP = libcfp.a
endif

# operating system and compiler dependent flags -------------------------------

# macOS configuration; compile with "make OS=mac"
ifeq ($(OS),mac)
  SOFLAGS += -undefined dynamic_lookup
endif

# suppress unused function warnings when compiling C89
ifeq ($(CSTD),-std=c89)
  FLAGS += -Wno-unused-function
endif

# process macros set on the command line --------------------------------------

# bit stream word type
ifdef BIT_STREAM_WORD_TYPE
  DEFS += -DBIT_STREAM_WORD_TYPE=$(BIT_STREAM_WORD_TYPE)
endif

# enable OpenMP?
ifdef ZFP_WITH_OPENMP
  ifneq ($(ZFP_WITH_OPENMP),0)
    ifneq ($(ZFP_WITH_OPENMP),OFF)
      FLAGS += $(OMPFLAGS)
    endif
  endif
endif

# treat subnormals as zero to avoid overflow
ifdef ZFP_WITH_DAZ
  ifneq ($(ZFP_WITH_DAZ),0)
    FLAGS += -DZFP_WITH_DAZ
  endif
endif

# rounding mode and slack in error
ifdef ZFP_ROUNDING_MODE
  FLAGS += -DZFP_ROUNDING_MODE=$(ZFP_ROUNDING_MODE)
  ifneq ($(ZFP_ROUNDING_MODE),0)
    # tight error bound requires round-first or round-last mode
    ifdef ZFP_WITH_TIGHT_ERROR
      ifneq ($(ZFP_WITH_TIGHT_ERROR),0)
        FLAGS += -DZFP_WITH_TIGHT_ERROR
      endif
    endif
  endif
endif

# chroma mode for ppm example
ifdef PPM_CHROMA
  PPM_FLAGS += -DPPM_CHROMA=$(PPM_CHROMA)
endif

# compiler options ------------------------------------------------------------

CFLAGS = $(CSTD) $(FLAGS) $(DEFS)
CXXFLAGS = $(CXXSTD) $(FLAGS) $(DEFS)
FFLAGS = $(FSTD) $(FLAGS) $(DEFS)
