Files
packfs/Makefile
T
retoorandClaude Sonnet 5 72e3c900f2 Add PackFS v0: statically linked in-process VFS implementing concept.md
Implements the core design: a mount table published as an atomically-
swapped snapshot; mem/dir/pack/overlay backends; copy-on-write overlay
with copy-up and whiteout deletion; a checksummed append journal;
compaction with exact-duplicate elimination; single-writer/wait-free-
reader concurrency with a structural/content write split; openat2/
Landlock path containment for dir mounts; and load-time pack integrity
validation. Zero required third-party dependencies.

Sanitizer testing (ASan/UBSan) caught and led to fixing a genuine
heap-use-after-free in the snapshot-reclamation path: the textbook
"load pointer, then increment its refcount" pattern left a gap a
concurrent writer could free through. Closed with a small reclaim_gate
rwlock, documented in internal.h and CLAUDE.md since it's a pattern
every refcounted structure in the codebase now follows.

zip/tar import/export backends, recommended in concept.md Section 11,
will not be built — a permanent project decision recorded in CLAUDE.md
since concept.md itself is frozen and cannot be edited to reflect it.

Includes a runnable demo (examples/demo.c, `make demo`) exercising the
library end to end and proving cross-run persistence through the pack
file, plus open-source scaffolding: MIT license, README, CONTRIBUTING,
and a CI workflow running the test suite under ASan/UBSan/TSan.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UqJpkdJ6Njnt1pw3CbghzB
2026-09-14 05:44:08 +00:00

74 lines
2.0 KiB
Makefile

# 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
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 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
clean:
rm -f src/*.o $(STATIC_LIB) $(SHARED_LIB) $(SONAME)
rm -rf build
install: static shared
install -d $(DESTDIR)$(PREFIX)/lib $(DESTDIR)$(PREFIX)/include
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/
uninstall:
rm -f $(DESTDIR)$(PREFIX)/lib/$(STATIC_LIB) $(DESTDIR)$(PREFIX)/lib/$(SONAME) $(DESTDIR)$(PREFIX)/lib/$(SHARED_LIB)
rm -f $(DESTDIR)$(PREFIX)/include/packfs.h