# Makefile — libmembus C++17
#
# Builds libmembus.a and test binaries.
# Usage:
#   make              Build library
#   make test         Build and run all tests
#   make install      Install library and header (sudo)
#   make uninstall    Remove installed files (sudo)
#   make clean        Remove build artifacts

PREFIX   = /usr/local
LIBDIR   = $(PREFIX)/lib
INCDIR   = $(PREFIX)/include/membus

CXX      = g++
CXXFLAGS = -std=c++17 -Wall -Wextra -Werror -O2 -fPIC -Iinclude
LDLIBS   = -lrt -lpthread
ARFLAGS  = rcs

SRCDIR   = src
BUILDDIR = build
TESTDIR  = tests

# ── Library ──

SRCS = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRCS))
LIB  = $(BUILDDIR)/libmembus.a
SO   = $(BUILDDIR)/libmembus.so

# ── Test binaries ──

TEST_MEMBUS = $(BUILDDIR)/test_membus

TESTS = $(TEST_MEMBUS)

# ── Targets ──

.PHONY: all clean test install uninstall help

all: $(LIB) $(SO)

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

$(BUILDDIR)/%.o: $(SRCDIR)/%.cpp include/membus.hpp | $(BUILDDIR)
	$(CXX) $(CXXFLAGS) -c -o $@ $<

$(LIB): $(OBJS)
	ar $(ARFLAGS) $@ $^

$(SO): $(OBJS)
	$(CXX) -shared -o $@ $^ $(LDLIBS)

# ── Test build rules ──
#
# MEMBUS-TEST-LINK-IS-BUILD-ORDER-DEPENDENT — the test links the freshly built
# ARCHIVE, named explicitly, not `-L$(BUILDDIR) -lmembus`.
#
# The rule already DEPENDED on $(LIB) and only the link line disagreed. With
# `-lmembus`, `make clean && make test` linked the archive statically and graded
# the tree, while `make clean && make all && make test` found build/libmembus.so
# first and — with no rpath — resolved /usr/local/lib/libmembus.so at run time.
# Same command, different subject, `45/45 passed` either way.
#
# Naming the archive makes the dependency and the link the same file, in both
# orders, and leaves no runtime search to shadow. This is the base/antheos fix.

$(TEST_MEMBUS): $(TESTDIR)/test_membus.cpp $(LIB) | $(BUILDDIR)
	$(CXX) $(CXXFLAGS) -I$(TESTDIR) -DTEST_MAIN_FN=test_membus_run -o $@ $< $(LIB) $(LDLIBS)

# ── Test runner ──

test: $(TESTS)
	@for t in $(TESTS); do echo "=== $$t ==="; ./$$t || exit 1; done

# ── Install / Uninstall ──

install: $(LIB) $(SO)
	install -d $(LIBDIR)
	install -m 644 $(LIB) $(LIBDIR)/libmembus.a
	install -m 755 $(SO) $(LIBDIR)/libmembus.so
	install -d $(INCDIR)
	install -m 644 include/membus.hpp $(INCDIR)/
	ldconfig
	@echo "libmembus installed to $(LIBDIR)/"

uninstall:
	rm -f $(LIBDIR)/libmembus.a $(LIBDIR)/libmembus.so
	rm -rf $(INCDIR)
	ldconfig
	@echo "libmembus uninstalled"

# ── Clean ──

clean:
	rm -rf $(BUILDDIR)

# ── Help ──

help:
	@echo "libmembus C++17 — available targets:"
	@echo "  all       Build libmembus.a (default)"
	@echo "  test      Build and run all tests"
	@echo "  install   Install library and header to PREFIX (default: /usr/local)"
	@echo "  uninstall Remove installed library and header"
	@echo "  clean     Remove build artifacts"
