From afb07d69c105c564c38bb4249ea80202e4ffe0fc Mon Sep 17 00:00:00 2001 From: Andrew Hundt Date: Mon, 23 Mar 2026 03:09:27 -0400 Subject: [PATCH] Makefile.cbm: add integrated codesign + install target for macOS 25+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit macOS 25+ enforces ad-hoc code signatures. Copying a binary with cp invalidates the existing signature and the binary gets SIGKILL at startup. Changes: - Detect platform with UNAME_S := $(shell uname -s) at Makefile top - codesign_binary() make function: calls codesign --force --sign - on macOS, prints warning if codesign not found, no-op + informational message on Linux - cbm target: calls codesign_binary after linking (build/c/... is always signed) - install target: new target — builds, copies to INSTALL_DIR (~/.local/bin), re-signs the copy (required because cp invalidates the build signature) - Clear status lines on every outcome: ✓ signed (ad-hoc, macOS 25+ compatible) ✗ WARNING: codesign failed — may crash on macOS 25+ ✗ WARNING: codesign not found — install Xcode CLT (signing skipped — not macOS) - Updated usage comment with install target and macOS signing note To install: make -f Makefile.cbm install Signed-off-by: Andrew Hundt --- Makefile.cbm | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/Makefile.cbm b/Makefile.cbm index b9a7a61a0..933a51b7b 100644 --- a/Makefile.cbm +++ b/Makefile.cbm @@ -4,8 +4,15 @@ # make -f Makefile.cbm test # Build + run all tests (ASan + UBSan) # make -f Makefile.cbm test-foundation # Foundation tests only (fast) # make -f Makefile.cbm test-tsan # Thread sanitizer build -# make -f Makefile.cbm cbm # Production binary +# make -f Makefile.cbm cbm # Production binary (auto-signed on macOS) +# make -f Makefile.cbm install # Build + install to INSTALL_DIR (default ~/.local/bin) # make -f Makefile.cbm clean-c # Remove build artifacts +# +# macOS signing note: +# macOS 25+ enforces ad-hoc code signatures on binaries. Copying a binary +# without re-signing causes immediate SIGKILL at runtime. This Makefile +# runs `codesign --force --sign -` automatically after every build and +# install step on macOS. On Linux and other platforms the step is a no-op. # Compiler selection — override via: make CC=gcc CXX=g++ # macOS: cc (Apple Clang) — universal binary with ASan support @@ -36,6 +43,33 @@ LIBGIT2_FLAGS = LIBGIT2_LIBS = endif +# ── Platform detection & code signing ─────────────────────────── +# macOS 25+ kills unsigned or invalidly-signed binaries with SIGKILL. +# codesign --force --sign - applies an ad-hoc signature (no Apple Developer +# account required). On Linux/other platforms this entire block is a no-op. +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Darwin) +CODESIGN_BIN := $(shell command -v codesign 2>/dev/null) +ifneq ($(CODESIGN_BIN),) +# codesign is available — sign and report +define codesign_binary + @$(CODESIGN_BIN) --force --sign - $(1) 2>&1 && \ + echo " ✓ signed $(1) (ad-hoc, macOS 25+ compatible)" || \ + { echo " ✗ WARNING: codesign failed for $(1) — binary may crash on macOS 25+"; true; } +endef +else +# codesign not found — warn but don't fail the build +define codesign_binary + @echo " ✗ WARNING: codesign not found — $(1) may crash on macOS 25+ (install Xcode CLT)" +endef +endif +else +# Non-macOS: signing is a documented no-op +define codesign_binary + @echo " (signing skipped — not macOS)" +endef +endif + # GCC-only warning suppressions (Clang rejects unknown -Wno-* with -Werror). # Detect GCC by checking for __GNUC__ without __clang__ — handles all versions. IS_GCC := $(shell echo | $(CC) -dM -E - 2>/dev/null | grep -q '__GNUC__' && ! echo | $(CC) -dM -E - 2>/dev/null | grep -q '__clang__' && echo yes || echo no) @@ -323,7 +357,7 @@ PP_OBJ_TEST = $(BUILD_DIR)/preprocessor.o # ── Targets ────────────────────────────────────────────────────── -.PHONY: test test-foundation test-tsan cbm cbm-with-ui frontend embed clean-c lint lint-tidy lint-cppcheck lint-format +.PHONY: test test-foundation test-tsan cbm cbm-with-ui frontend embed clean-c lint lint-tidy lint-cppcheck lint-format install $(BUILD_DIR): mkdir -p $(BUILD_DIR) @@ -446,6 +480,17 @@ $(BUILD_DIR)/codebase-memory-mcp: $(MAIN_SRC) $(PROD_SRCS) $(EXTRACTION_SRCS) $( cbm: $(BUILD_DIR)/codebase-memory-mcp @echo "Built: $(BUILD_DIR)/codebase-memory-mcp" + $(call codesign_binary,$(BUILD_DIR)/codebase-memory-mcp) + +# ── Install to INSTALL_DIR (default ~/.local/bin) ──────────────── +# Re-signs after copy — required on macOS 25+ where cp invalidates the +# existing ad-hoc signature and an unsigned binary gets SIGKILL at startup. +INSTALL_DIR ?= $(HOME)/.local/bin +install: cbm + @echo "Installing to $(INSTALL_DIR)/codebase-memory-mcp ..." + cp $(BUILD_DIR)/codebase-memory-mcp $(INSTALL_DIR)/codebase-memory-mcp + $(call codesign_binary,$(INSTALL_DIR)/codebase-memory-mcp) + @echo "Done. Run: $(INSTALL_DIR)/codebase-memory-mcp" # ── Build with embedded UI (requires Node.js) ───────────────────