# Makefile — PackFS
#
# Builds the static and shared library from src/, plus the test binaries
# under tests/. See CLAUDE.md for the project's static-linking constraint
# (Section 11.1 of concept.md): the core here has zero required
# third-party dependencies; it links only against the platform C library,
# pthread, and (on Linux) direct kernel syscalls for openat2/Landlock.

CC       ?= cc
AR       ?= ar
PREFIX   ?= /usr/local

CFLAGS   ?= -std=c11 -Wall -Wextra -Wpedantic -O2 -g -fPIC
CFLAGS   += -Iinclude -Isrc -D_GNU_SOURCE
LDLIBS   := -lpthread

# Single source of truth: PACKFS_VERSION_STRING in include/packfs.h.
# packfs.pc is generated from it, never hand-maintained separately.
VERSION  := $(shell grep -m1 'define PACKFS_VERSION_STRING' include/packfs.h | sed -E 's/.*"([^"]+)".*/\1/')

SRC := $(wildcard src/*.c)
OBJ := $(SRC:.c=.o)

STATIC_LIB := libpackfs.a
SONAME     := libpackfs.so.0
SHARED_LIB := libpackfs.so

TEST_SRC := $(wildcard tests/test_*.c)
TEST_BIN := $(TEST_SRC:tests/%.c=build/%)

.PHONY: all static shared test demo bench clean install uninstall

all: static shared

static: $(STATIC_LIB)

shared: $(SHARED_LIB)

$(STATIC_LIB): $(OBJ)
	$(AR) rcs $@ $(OBJ)

$(SHARED_LIB): $(OBJ)
	$(CC) -shared -Wl,-soname,$(SONAME) -o $(SONAME) $(OBJ) $(LDLIBS)
	ln -sf $(SONAME) $(SHARED_LIB)

%.o: %.c src/internal.h include/packfs.h
	$(CC) $(CFLAGS) -c $< -o $@

build:
	mkdir -p build

build/%: tests/%.c $(STATIC_LIB) | build
	$(CC) $(CFLAGS) $< $(STATIC_LIB) $(LDLIBS) -o $@

test: $(TEST_BIN)
	@set -e; for t in $(TEST_BIN); do echo "-- $$t --"; $$t; done

build/packfs_demo: examples/demo.c $(STATIC_LIB) | build
	$(CC) $(CFLAGS) $< $(STATIC_LIB) $(LDLIBS) -o $@

demo: build/packfs_demo
	./build/packfs_demo

build/packfs_bench: bench/bench.c $(STATIC_LIB) | build
	$(CC) $(CFLAGS) $< $(STATIC_LIB) $(LDLIBS) -o $@

bench: build/packfs_bench
	./build/packfs_bench

clean:
	rm -f src/*.o $(STATIC_LIB) $(SHARED_LIB) $(SONAME) packfs.pc
	rm -rf build

packfs.pc: packfs.pc.in
	sed -e 's|@PREFIX@|$(PREFIX)|g' -e 's|@VERSION@|$(VERSION)|g' packfs.pc.in > packfs.pc

install: static shared packfs.pc
	install -d $(DESTDIR)$(PREFIX)/lib $(DESTDIR)$(PREFIX)/include $(DESTDIR)$(PREFIX)/lib/pkgconfig
	install -m 644 $(STATIC_LIB) $(DESTDIR)$(PREFIX)/lib/
	install -m 755 $(SONAME) $(DESTDIR)$(PREFIX)/lib/
	ln -sf $(SONAME) $(DESTDIR)$(PREFIX)/lib/$(SHARED_LIB)
	install -m 644 include/packfs.h $(DESTDIR)$(PREFIX)/include/
	install -m 644 packfs.pc $(DESTDIR)$(PREFIX)/lib/pkgconfig/

uninstall:
	rm -f $(DESTDIR)$(PREFIX)/lib/$(STATIC_LIB) $(DESTDIR)$(PREFIX)/lib/$(SONAME) $(DESTDIR)$(PREFIX)/lib/$(SHARED_LIB)
	rm -f $(DESTDIR)$(PREFIX)/include/packfs.h
	rm -f $(DESTDIR)$(PREFIX)/lib/pkgconfig/packfs.pc
