From b423a70c566e1dbbb00291783d367ee5db5a3e17 Mon Sep 17 00:00:00 2001 From: ngallodev Date: Sun, 17 May 2026 17:37:43 -0700 Subject: [PATCH 1/6] ci: fix release build warnings --- .github/workflows/release.yml | 4 +- Jenkinsfile | 2 +- Makefile | 10 +++- docs/release-fix-plan.md | 89 ++++++++++++++++++++++++++++++ src/mcp/mcp.c | 2 +- src/watcher/watcher.c | 20 ++++++- vendored/nomic/code_vectors_blob.S | 2 + 7 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 docs/release-fix-plan.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index da38833..c8d8250 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,7 @@ jobs: shell: bash run: | make clean - make -j2 CFLAGS_EXTRA='-DCBM_VERSION="${{ steps.version.outputs.value }}"' + make -j2 CBM_VERSION="${{ steps.version.outputs.value }}" chmod +x install.sh scripts/package-release.sh copilot-skill/scripts/install.sh scripts/package-release.sh "${{ steps.version.outputs.value }}" build/c/copilot-memory-mcp @@ -59,7 +59,7 @@ jobs: shell: msys2 {0} run: | make clean - make -j2 CC=gcc CXX=g++ CFLAGS_EXTRA='-DCBM_VERSION=\"${{ steps.version.outputs.value }}\"' + make -j2 CC=gcc CXX=g++ CBM_VERSION="${{ steps.version.outputs.value }}" if [ -f build/c/copilot-memory-mcp.exe ]; then : else diff --git a/Jenkinsfile b/Jenkinsfile index 6678374..d33bf45 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -44,7 +44,7 @@ pipeline { sh 'make clean' sh ''' set -eu - make -j2 CFLAGS_EXTRA='-DCBM_VERSION=\"'"$EFFECTIVE_RELEASE_VERSION"'\"' + make -j2 CBM_VERSION="$EFFECTIVE_RELEASE_VERSION" ''' } } diff --git a/Makefile b/Makefile index a2cf593..7b01835 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,8 @@ TS_SRC = $(CBM_DIR)/vendored/ts_runtime/src # ── Common flags ───────────────────────────────────────────────── +CBM_VERSION ?= dev + CFLAGS_COMMON = -std=c11 -D_DEFAULT_SOURCE -D_GNU_SOURCE -Wall -Wextra -Werror \ -Wno-unused-parameter -Wno-sign-compare \ -Wno-unused-result \ @@ -22,12 +24,16 @@ CFLAGS_COMMON = -std=c11 -D_DEFAULT_SOURCE -D_GNU_SOURCE -Wall -Wextra -Werror \ -Isrc -Ivendored -Ivendored/sqlite3 -Ivendored/mimalloc/include \ -I$(CBM_DIR) -I$(TS_INCLUDE) -I$(TS_SRC) -I$(TS_SRC)/unicode -ifneq (,$(findstring gcc,$(notdir $(CC)))) +# GCC-family compilers complain on a few legitimate fixed-size formatting paths +# that the release workflow keeps as warnings only; Clang does not accept those +# suppressions, so probe the compiler itself instead of relying on the CC name. +CC_IS_CLANG := $(shell printf '' | $(CC) -dM -E -x c - 2>/dev/null | grep -q '__clang__' && echo yes || echo no) +ifeq ($(CC_IS_CLANG),no) CFLAGS_COMMON += -Wno-format-truncation CFLAGS_COMMON += -Wno-stringop-truncation endif -CFLAGS_PROD = $(CFLAGS_COMMON) -O2 $(CFLAGS_EXTRA) +CFLAGS_PROD = $(CFLAGS_COMMON) -O2 -DCBM_VERSION=\"$(CBM_VERSION)\" $(CFLAGS_EXTRA) # ── Minimal source files ───────────────────────────────────────── diff --git a/docs/release-fix-plan.md b/docs/release-fix-plan.md new file mode 100644 index 0000000..60d0cb9 --- /dev/null +++ b/docs/release-fix-plan.md @@ -0,0 +1,89 @@ +# Release Fix Plan + +Source of truth: +- latest failing release workflow run: `26006685989` +- affected surface: `.github/workflows/release.yml` +- current release packagers: `scripts/package-release.sh`, `scripts/package-release.ps1` + +## Failure Summary + +1. Linux/macOS release build +- `CBM_VERSION` is reaching the compiler without being a string literal. +- GCC/Clang then expand it as `v0.x.y` tokens and fail in `src/main.c` and `src/cli/cli.c`. +- The workflow shell quoting is the immediate trigger. + +2. macOS release build +- Clang rejects GCC-only warning suppressions when they are passed unconditionally. +- `-Wno-format-truncation` and `-Wno-stringop-truncation` must not be sent to Clang. + +3. Windows release build +- `ts_runtime.o` cannot find `unicode/umachine.h`. +- The shared include path must cover `internal/cbm/vendored/ts_runtime/src`. + +## Phase 1: Fix version propagation + +Goal: +- make `CBM_VERSION` arrive at the compiler as a quoted string on Linux and macOS. + +Work: +- update `.github/workflows/release.yml` +- keep the build command shell-safe for both Bash and MSYS2 +- confirm the compiler sees `-DCBM_VERSION=\"vX.Y.Z\"` + +Acceptance: +- Linux/macOS job compiles `src/main.c` and `src/cli/cli.c` without `CBM_VERSION` token errors. +- package step still receives the same version value. + +## Phase 2: Fix macOS compiler portability + +Goal: +- stop sending GCC-only warning suppressions to Clang. + +Work: +- keep `-Wno-format-truncation` and `-Wno-stringop-truncation` gated to GCC only in `Makefile` +- verify the posix build path still compiles under Clang + +Acceptance: +- macOS job completes the build stage with Clang. +- local `make CC=clang CXX=clang++` reaches link/package stages. + +## Phase 3: Fix Windows include path + +Goal: +- make the vendored tree-sitter runtime compile on MSYS2. + +Work: +- ensure `Makefile` includes `internal/cbm/vendored/ts_runtime/src` +- keep `internal/cbm/vendored/ts_runtime/src/unicode` in the include list + +Acceptance: +- Windows job compiles `build/c/ts_runtime.o` +- `unicode/umachine.h` resolves without manual environment tweaks + +## Phase 4: Package verification + +Goal: +- make sure the packaging scripts still emit the expected assets after the build fixes. + +Work: +- confirm `scripts/package-release.sh` produces the Linux/macOS tarball and checksums +- confirm `scripts/package-release.ps1` produces the Windows zip and checksums +- confirm the release workflow uploads the right artifacts for each platform + +Acceptance: +- Linux/macOS upload `dist/*.tar.gz` and `dist/checksums-*.txt` +- Windows upload `dist/*.zip` and `dist/checksums-*.txt` +- published GitHub release assets match the package scripts + +## Verification Order + +1. local `make clean && make -j2` +2. local `make clean && make -j2 CC=clang CXX=clang++` +3. workflow dispatch or push to `main` +4. confirm the three GitHub Actions jobs pass + +## Notes + +- Keep Jenkins out of this fix unless the Jenkinsfile itself regresses. +- Do not widen scope beyond release build and packaging portability. +- If the workflow still fails after the above, inspect the exact compiler command line before changing package scripts. diff --git a/src/mcp/mcp.c b/src/mcp/mcp.c index 06b28bb..4c1e837 100644 --- a/src/mcp/mcp.c +++ b/src/mcp/mcp.c @@ -3286,7 +3286,7 @@ static char *handle_search_code(cbm_mcp_server_t *srv, const char *args) { * Query the graph for distinct file paths, write them to a temp file, * then use xargs to pass them to grep. Falls back to recursive grep if * no indexed files found (project not fully indexed). */ - char filelist[CBM_SZ_256]; + char filelist[CBM_SZ_512]; snprintf(filelist, sizeof(filelist), "%s.files", tmpfile); bool scoped = false; diff --git a/src/watcher/watcher.c b/src/watcher/watcher.c index 9430ecb..261bb4b 100644 --- a/src/watcher/watcher.c +++ b/src/watcher/watcher.c @@ -75,6 +75,22 @@ static int64_t now_ns(void) { return ((int64_t)ts.tv_sec * NS_PER_SEC) + ts.tv_nsec; } +static void copy_head(char *dst, size_t dst_size, const char *src) { + if (!dst || dst_size == 0) { + return; + } + if (!src) { + dst[0] = '\0'; + return; + } + size_t len = strlen(src); + if (len >= dst_size) { + len = dst_size - SKIP_ONE; + } + memcpy(dst, src, len); + dst[len] = '\0'; +} + /* ── Adaptive interval ──────────────────────────────────────────── */ int cbm_watcher_poll_interval_ms(int file_count) { @@ -340,10 +356,10 @@ static bool check_changes(project_state_t *s) { if (git_head(s->root_path, head, sizeof(head)) == 0) { if (s->last_head[0] != '\0' && strcmp(head, s->last_head) != 0) { /* HEAD moved — commit, checkout, pull */ - strncpy(s->last_head, head, sizeof(s->last_head) - 1); + copy_head(s->last_head, sizeof(s->last_head), head); return true; } - strncpy(s->last_head, head, sizeof(s->last_head) - 1); + copy_head(s->last_head, sizeof(s->last_head), head); } /* Check working tree */ diff --git a/vendored/nomic/code_vectors_blob.S b/vendored/nomic/code_vectors_blob.S index b927181..4b90b45 100644 --- a/vendored/nomic/code_vectors_blob.S +++ b/vendored/nomic/code_vectors_blob.S @@ -42,4 +42,6 @@ PRETRAINED_VECTOR_BLOB_END: .p2align 2 PRETRAINED_VECTOR_BLOB_LEN: .long PRETRAINED_VECTOR_BLOB_END - PRETRAINED_VECTOR_BLOB + + .section .note.GNU-stack,"",@progbits #endif From 68626eba27d6f5b5af21b1f8b07f04ddcea1e314 Mon Sep 17 00:00:00 2001 From: ngallodev Date: Sun, 17 May 2026 18:36:43 -0700 Subject: [PATCH 2/6] fix: add missing tree-sitter unicode include paths for ts_runtime.o The ts_runtime.o compilation was failing on Windows because GRAMMAR_CFLAGS lacked the -I$(TS_SRC) and -I$(TS_SRC)/unicode paths needed to resolve unicode/umachine.h. This adds them to GRAMMAR_CFLAGS so both grammar parsers and the tree-sitter runtime wrapper can find the ICU headers. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7b01835..c4bfa62 100644 --- a/Makefile +++ b/Makefile @@ -176,7 +176,7 @@ GRAMMAR_SRCS = \ # ── Vendored library compilation flags (relaxed warnings) ──────── SQLITE3_CFLAGS = -std=c11 -O2 -w -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=1 -DSQLITE_ENABLE_FTS5 -GRAMMAR_CFLAGS = -std=c11 -D_DEFAULT_SOURCE -O2 -w -Wno-unused-value -I$(CBM_DIR) -I$(TS_INCLUDE) +GRAMMAR_CFLAGS = -std=c11 -D_DEFAULT_SOURCE -O2 -w -Wno-unused-value -I$(CBM_DIR) -I$(TS_INCLUDE) -I$(TS_SRC) -I$(TS_SRC)/unicode # ── Linker flags ───────────────────────────────────────────────── From 9424f795d1fdd421f02fbdd3dd693f1f4e0a1d50 Mon Sep 17 00:00:00 2001 From: ngallodev Date: Sun, 17 May 2026 18:40:08 -0700 Subject: [PATCH 3/6] fix: disable mimalloc malloc override on Windows Windows does not support MI_MALLOC_OVERRIDE in static builds - it only works when building mimalloc as a DLL. On Windows, compile mimalloc without the override flag so it's available as an optional allocator but doesn't replace the system malloc. --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c4bfa62..c6fa1b2 100644 --- a/Makefile +++ b/Makefile @@ -241,9 +241,13 @@ $(BUILD_DIR)/zstd.o: internal/cbm/vendored/zstd/zstd.c | $(BUILD_DIR) $(BUILD_DIR)/code_vectors_blob.o: vendored/nomic/code_vectors_blob.S | $(BUILD_DIR) $(CC) -c -o $@ $< -# Compile mimalloc +# Compile mimalloc (no malloc override on Windows - not supported in static builds) $(BUILD_DIR)/mimalloc.o: vendored/mimalloc/src/static.c | $(BUILD_DIR) +ifeq ($(OS),Windows_NT) + $(CC) -std=c11 -O2 -w -Ivendored/mimalloc/include -c -o $@ $< +else $(CC) -std=c11 -O2 -w -Ivendored/mimalloc/include -DMI_MALLOC_OVERRIDE -c -o $@ $< +endif # Compile grammar files separately with relaxed warnings GRAMMAR_OBJS = $(patsubst $(GRAMMAR_DIR)/%.c,$(BUILD_DIR)/grammar_%.o,$(GRAMMAR_SRCS)) From 9a6e462180a16285e1cbf90cab5f7590f9c10f9b Mon Sep 17 00:00:00 2001 From: ngallodev Date: Sun, 17 May 2026 18:45:03 -0700 Subject: [PATCH 4/6] fix: add missing fcntl.h include for Windows pipe flags Windows _pipe() and _open() calls require _O_BINARY and _O_WRONLY constants from fcntl.h. This header was missing, causing undefined identifier errors on MSYS2/MinGW builds. --- src/foundation/compat_fs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/foundation/compat_fs.c b/src/foundation/compat_fs.c index 12e7cbd..08d9640 100644 --- a/src/foundation/compat_fs.c +++ b/src/foundation/compat_fs.c @@ -20,7 +20,8 @@ #endif #include #include /* _mkdir */ -#include /* _unlink */ +#include /* _unlink, _pipe, _open */ +#include /* _O_BINARY, _O_WRONLY */ #include struct cbm_dir { From 5d90cba9ffc4d4609866bbcef497b88d784c0008 Mon Sep 17 00:00:00 2001 From: ngallodev Date: Sun, 17 May 2026 18:50:04 -0700 Subject: [PATCH 5/6] fix: add TRE library link flag for Windows Windows (MSYS2) requires explicit linking against the TRE library for regex functions (tre_regcomp, tre_regexec, tre_regfree) used in compat_regex.c. On Linux/macOS these are part of libc, but Windows needs -ltre. --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index c6fa1b2..6a59cab 100644 --- a/Makefile +++ b/Makefile @@ -181,6 +181,10 @@ GRAMMAR_CFLAGS = -std=c11 -D_DEFAULT_SOURCE -O2 -w -Wno-unused-value -I$(CBM_DIR # ── Linker flags ───────────────────────────────────────────────── LDFLAGS = -lm -lstdc++ -lpthread -lz +# Windows requires explicit TRE library link (compat_regex uses tre_regcomp/tre_regexec) +ifeq ($(OS),Windows_NT) + LDFLAGS += -ltre +endif # ── Build directory ───────────────────────────────────────────── From cb4a9b315c15a38455edaf2d4994cd06702ad579 Mon Sep 17 00:00:00 2001 From: ngallodev Date: Sun, 17 May 2026 18:56:15 -0700 Subject: [PATCH 6/6] fix: compile vendored TRE library instead of linking system library Instead of trying to link against system -ltre (which may not be installed in MSYS2 environment), compile the vendored tre_all.c amalgamation file as tre.o and link it directly. This makes Windows builds work without external dependencies. --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 6a59cab..403b3dc 100644 --- a/Makefile +++ b/Makefile @@ -181,10 +181,6 @@ GRAMMAR_CFLAGS = -std=c11 -D_DEFAULT_SOURCE -O2 -w -Wno-unused-value -I$(CBM_DIR # ── Linker flags ───────────────────────────────────────────────── LDFLAGS = -lm -lstdc++ -lpthread -lz -# Windows requires explicit TRE library link (compat_regex uses tre_regcomp/tre_regexec) -ifeq ($(OS),Windows_NT) - LDFLAGS += -ltre -endif # ── Build directory ───────────────────────────────────────────── @@ -241,6 +237,10 @@ $(BUILD_DIR)/lz4hc.o: internal/cbm/vendored/lz4/lz4hc.c | $(BUILD_DIR) $(BUILD_DIR)/zstd.o: internal/cbm/vendored/zstd/zstd.c | $(BUILD_DIR) $(CC) -std=c11 -O2 -w -I$(CBM_DIR)/vendored/zstd -c -o $@ $< +# Compile vendored TRE regex library (used on Windows for compat_regex) +$(BUILD_DIR)/tre.o: vendored/tre/tre_all.c | $(BUILD_DIR) + $(CC) -std=c11 -O2 -w -Ivendored/tre -c -o $@ $< + # Assemble nomic vector blob $(BUILD_DIR)/code_vectors_blob.o: vendored/nomic/code_vectors_blob.S | $(BUILD_DIR) $(CC) -c -o $@ $< @@ -261,11 +261,11 @@ $(BUILD_DIR)/grammar_%.o: $(GRAMMAR_DIR)/%.c | $(BUILD_DIR) $(CC) $(GRAMMAR_CFLAGS) -c -o $@ $< # Compile and link (main sources in one pass, pre-compiled objects for grammars/vendored/cpp) -$(BUILD_DIR)/copilot-memory-mcp: $(ALL_SRCS) $(GRAMMAR_OBJS) $(BUILD_DIR)/yyjson.o $(BUILD_DIR)/sqlite3.o $(BUILD_DIR)/ts_runtime.o $(BUILD_DIR)/preprocessor.o $(BUILD_DIR)/lz4.o $(BUILD_DIR)/lz4hc.o $(BUILD_DIR)/zstd.o $(BUILD_DIR)/code_vectors_blob.o $(BUILD_DIR)/mimalloc.o | $(BUILD_DIR) +$(BUILD_DIR)/copilot-memory-mcp: $(ALL_SRCS) $(GRAMMAR_OBJS) $(BUILD_DIR)/yyjson.o $(BUILD_DIR)/sqlite3.o $(BUILD_DIR)/ts_runtime.o $(BUILD_DIR)/preprocessor.o $(BUILD_DIR)/lz4.o $(BUILD_DIR)/lz4hc.o $(BUILD_DIR)/zstd.o $(BUILD_DIR)/tre.o $(BUILD_DIR)/code_vectors_blob.o $(BUILD_DIR)/mimalloc.o | $(BUILD_DIR) $(CC) $(CFLAGS_PROD) -o $@ \ $(ALL_SRCS) \ $(GRAMMAR_OBJS) \ - $(BUILD_DIR)/yyjson.o $(BUILD_DIR)/sqlite3.o $(BUILD_DIR)/ts_runtime.o $(BUILD_DIR)/preprocessor.o $(BUILD_DIR)/lz4.o $(BUILD_DIR)/lz4hc.o $(BUILD_DIR)/zstd.o $(BUILD_DIR)/code_vectors_blob.o $(BUILD_DIR)/mimalloc.o \ + $(BUILD_DIR)/yyjson.o $(BUILD_DIR)/sqlite3.o $(BUILD_DIR)/ts_runtime.o $(BUILD_DIR)/preprocessor.o $(BUILD_DIR)/lz4.o $(BUILD_DIR)/lz4hc.o $(BUILD_DIR)/zstd.o $(BUILD_DIR)/tre.o $(BUILD_DIR)/code_vectors_blob.o $(BUILD_DIR)/mimalloc.o \ $(LDFLAGS) @echo "Built: $(BUILD_DIR)/copilot-memory-mcp" @@ -288,4 +288,4 @@ info: @echo " $(GRAMMARS)" @echo "Component sources: $(words $(COMPONENT_SRCS))" @echo "Grammar sources: $(words $(GRAMMAR_SRCS))" - @echo "Vendored: yyjson, sqlite3, mimalloc, lz4, zstd, tree-sitter" + @echo "Vendored: yyjson, sqlite3, mimalloc, lz4, zstd, tre, tree-sitter"