# Build the barcodesdb core programs without pip.
#
#   make            # build everything into ./bin
#   make test       # build, then run the correctness suite against ./bin
#   make clean
#
# Most users should just `pip install barcodesdb`, which runs this compilation
# for them and puts the programs behind the `barcodesdb` command. This Makefile
# is for working on the C++ directly, or for environments without pip.
#
# Options:
#   ZLIB=0          build without gzip support (.gz input unavailable)
#   MARCH=1         add -march=native (faster, but the binary will not run on an
#                   older CPU than the build machine)

CXX      ?= g++
OPT      ?= -O3 -DNDEBUG
CXXFLAGS ?= $(OPT) -std=c++17 -pthread -Wall -Wextra
CPPFLAGS ?= -Icpp

BIN_DIR := bin
SRC_DIR := cpp

PROGRAMS := bdb-extract bdb-merge bdb-dump bdb-query
BINARIES := $(addprefix $(BIN_DIR)/,$(PROGRAMS))
HEADERS  := $(SRC_DIR)/common.hpp $(SRC_DIR)/encoders.hpp $(SRC_DIR)/json_mini.hpp

ZLIB ?= 1
ifeq ($(ZLIB),1)
  CPPFLAGS += -DHAVE_ZLIB
  LDLIBS_Z := -lz
else
  LDLIBS_Z :=
endif

MARCH ?= 0
ifeq ($(MARCH),1)
  CXXFLAGS += -march=native
endif

# Statically link the C++ runtime when the toolchain allows it. Without this the
# binaries bind to the build host's libstdc++ and fail with a GLIBCXX version
# error when run from a different environment on the same machine.
STATIC_RT := $(shell printf 'int main(){return 0;}' > /tmp/.bdb_probe.cpp 2>/dev/null && \
             $(CXX) -static-libstdc++ -static-libgcc -o /tmp/.bdb_probe /tmp/.bdb_probe.cpp \
             >/dev/null 2>&1 && echo "-static-libstdc++ -static-libgcc"; \
             rm -f /tmp/.bdb_probe /tmp/.bdb_probe.cpp)

.PHONY: all test clean

all: $(BINARIES)

$(BIN_DIR):
	mkdir -p $(BIN_DIR)

$(BIN_DIR)/bdb-extract: $(SRC_DIR)/extract.cpp $(HEADERS) | $(BIN_DIR)
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(STATIC_RT) -o $@ $< $(LDLIBS_Z)

$(BIN_DIR)/bdb-dump: $(SRC_DIR)/dump.cpp $(HEADERS) | $(BIN_DIR)
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(STATIC_RT) -o $@ $< $(LDLIBS_Z)

$(BIN_DIR)/bdb-query: $(SRC_DIR)/query.cpp $(HEADERS) | $(BIN_DIR)
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(STATIC_RT) -o $@ $< $(LDLIBS_Z)

$(BIN_DIR)/bdb-merge: $(SRC_DIR)/merge.cpp $(HEADERS) | $(BIN_DIR)
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(STATIC_RT) -o $@ $< $(LDLIBS_Z)

# Run the same suite `barcodesdb selftest` runs, against ./bin
test: all
	PATH=$(CURDIR)/$(BIN_DIR):$$PATH PYTHONPATH=$(CURDIR)/src \
	  python3 -c "from barcodesdb.selftest import run_selftest; raise SystemExit(run_selftest())"

clean:
	rm -rf $(BIN_DIR)
