feat: format build.zig#2
Merged
Merged
Conversation
wemeetagain
added a commit
that referenced
this pull request
Mar 17, 2026
- #1: Clean stale build.zig.zon (remove deleted exe/test refs, bump to 0.3.0) - #2: Remove @ptrCast for dest_sub_path (Zig coerces comptime strings) - #3: Default modules to public (export to b.modules unless private = true) - #4: @CompileError for unknown option types + validateManifest for unknown top-level fields - #5: resolveImport returns error.ModuleNotFound instead of @Panic - #6: Remove duplicate modules.put (createModule handles it, callers don't) - #7: Add 8 comptime helper tests (toStringSlice, toEnumSlice, isIntType, isFloatType, isKnownField, validateManifest) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
wemeetagain
added a commit
that referenced
this pull request
May 11, 2026
* docs: add architecture refactor design spec Three-phase refactor: single ZON file, std.zon.parse-based Config, static build.zig. See docs/superpowers/specs/ for details. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add implementation plan for three-phase architecture refactor Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(phase-a): merge zbuild.zon into build.zig.zon — single source of truth - Rename test fixtures from .zbuild.zon to .build.zig.zon - Default zbuild_file to build.zig.zon - Remove syncManifest from cmd_sync (no more manifest generation) - Remove Manifest.zig dependency from cmd_init and cmd_fetch - Delete sync_manifest.zig and Manifest.zig (parallel data model eliminated) - Merge zbuild.zon content into build.zig.zon, delete zbuild.zon - Simplify cmd_fetch to delegate entirely to zig fetch Fixes: 2.9, 2.10, 2.12, 2.13, 4.5, 5.8 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(phase-b): rewrite parser with std.zon.parse - Change fingerprint from []const u8 to u64 (matches ZON directly) - Remove all deinit methods (arena handles cleanup) - Replace hand-rolled if/else if parser with: - inline for over struct fields for typed values - fromZoirNode for standard types - Custom parsers only for Dependency, ModuleLink, Option - parseHashMap replaces both parseHashMap and parseOptionalHashMap - Ignore unknown top-level fields (enables single-file approach) - Fix dependency parsing to include hash and lazy fields - Fix parseRun to use parseString (Run = []const u8) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(phase-c): replace codegen with static build.zig + build_runner - Create build_runner.zig with configureBuild() that reads build.zig.zon and configures the build graph via direct std.Build API calls - Replace cmd_sync codegen with static build.zig template that imports zbuild and calls configureBuild - Delete ConfigBuildgen.zig (~1280 lines) and sync_build_file.zig (~38 lines) - Hand-write zbuild's own build.zig (can't self-reference) - Expose configureBuild as public API via main.zig - Update sync test to verify static template generation Eliminates string-concatenation codegen, scratch buffers, and zig fmt post-processing. Fixes bugs 1.6, 2.5, 2.6, 2.14, 3.7, 4.1, 4.3, 4.6, 5.5, 5.6, 5.10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add comprehensive Config parser unit tests 16 inline tests covering: minimal config, modules, executables (inline and named module refs), dependencies (with hash/lazy/args), libraries, tests, runs, options, options_modules, fmts, module imports, description/ keywords, and error cases (missing required fields, invalid versions). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: complete serializer + add round-trip tests Bug fixes: - Implement serialization of libraries, objects, tests, fmts, runs sections (previously commented out, issue 2.7) - Implement enum and enum_list option serialization (previously TODO stubs, issue 2.8) - Add hash and lazy fields to dependency serialization (issue 2.10) Tests: - 8 round-trip tests that parse → serialize → re-parse and verify structural equivalence for each section type Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: wire depends_on for executables/libraries/objects The depends_on field was parsed but never used in the build graph. Now build_runner tracks install steps in a map and adds step dependencies in a final pass after all artifacts are created. Also adds parser + round-trip tests for depends_on. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: ZigEnv exit code, --no-sync loop, write_files parser, Args test Bug fixes: - ZigEnv: change 'and' to 'or' in exit code check so non-zero exits and signal terminations are properly detected (issue 1.3) - GlobalOptions: add args.next() when consuming --no-sync flag to prevent infinite loop (issue 1.4) - Config: implement write_files parser (was a stub that silently discarded all write_files entries) (issue 1.1) - Args: fix test calling non-existent Args.parse, should be Args.initFromString (issue 3.9) Tests: - GlobalOptions: --no-sync flag consumption (verifies no infinite loop) - Config: write_files parsing with file and dir items - Config: write_files round-trip serialization Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: wip_bundle memory leak and returnParseErrorFmt owned flag - main.zig: add defer wip_bundle.deinit() so the error bundle's internal allocations are freed on the success path (issue 3.4) - Config.zig: returnParseErrorFmt now sets .owned = true since the message is heap-allocated via allocPrint (issue 3.10) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: convert zbuild from CLI tool to library-only dependency zbuild no longer ships a CLI binary. Users consume it as a standard Zig dependency via build.zig.zon and call zbuild.configureBuild(b) from their build.zig. This eliminates ~1,100 lines of CLI indirection that was just wrapping zig build/fetch/init commands. Deleted: Args, GlobalOptions, ZigEnv, Package, run_zig, cmd_build, cmd_fetch, cmd_init, cmd_sync, test/sync, test/fixtures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: replace runtime parser with comptime @import("build.zig.zon") Delete Config.zig entirely (2,112 lines — parser, serializer, IR types, tests). The Zig compiler now parses build.zig.zon via @import, and build_runner.zig walks the comptime anonymous struct directly using inline for + @Hasfield. This resolves the dependency args impedance mismatch: since the manifest is comptime-known, dependency .args flow through to b.dependency() naturally without needing a runtime→comptime bridge. Project shrinks from ~2,630 to ~583 lines of source. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: manifest validation, error handling, and test coverage - #1: Clean stale build.zig.zon (remove deleted exe/test refs, bump to 0.3.0) - #2: Remove @ptrCast for dest_sub_path (Zig coerces comptime strings) - #3: Default modules to public (export to b.modules unless private = true) - #4: @CompileError for unknown option types + validateManifest for unknown top-level fields - #5: resolveImport returns error.ModuleNotFound instead of @Panic - #6: Remove duplicate modules.put (createModule handles it, callers don't) - #7: Add 8 comptime helper tests (toStringSlice, toEnumSlice, isIntType, isFloatType, isKnownField, validateManifest) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: replace field-name validation with cross-reference validation Instead of rejecting unknown top-level fields (which breaks forward compatibility with new Zig versions), validate semantic cross-references: root_module refs point to declared modules, depends_on refs point to declared artifacts, and imports reference modules/options_modules/deps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add runs field redesign spec Dual-form syntax (bare tuple for simple commands, struct with cmd + env/cwd/stdio/stdin/depends_on for complex ones), comptime validation, and cmd: step prefix to avoid collision with executable run: steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add runs field redesign implementation plan Three tasks: validation, createRun rewrite, and tests. Covers dual-form syntax, stdin/stdin_file exclusion, depends_on wiring, and cmd: step prefix to avoid executable collision. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add comptime validation for runs fields Cross-reference depends_on against declared artifacts and enforce stdin/stdin_file mutual exclusion at compile time. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: rewrite createRun with dual-form comptime support Short form (bare tuple) for simple commands, long form (struct with cmd + cwd/env/inherit_stdio/stdin/stdin_file/depends_on) for complex ones. Replaces runtime string splitting with comptime toStringSlice. Step prefix changes from run: to cmd: to avoid executable collision. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add validation tests for runs dual-form syntax Covers short-form tuples, long-form structs with depends_on/env/cwd, run+executable name coexistence, and forward-compat unknown fields. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: consolidate validateManifest and extract installAndRegister Merge three separate artifact-section loops in validateManifest into a single pass that validates root_module refs, depends_on, and imports per item. Extract the repeated install-artifact-and-register pattern into installAndRegister helper used by all three artifact creators. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: unify string extraction and depends_on wiring patterns Use toComptimeString consistently for extracting strings from ZON tuples (wireDependsOnList, wireModuleImports). Have createRun reuse wireDependsOnList instead of duplicating the depends_on logic inline. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: comptime string splitting for link_libraries Replace runtime splitScalar with comptime comptimeBaseName/comptimeAfterSep for link_libraries colon syntax. Also use toComptimeString so link_libraries accepts enum literals (consistent with imports and depends_on). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add built-in help step with project build information configureBuild now takes a comptime Options struct with a help_step field (default: "help"). When set, zig build help prints a formatted overview of the project's modules, artifacts, tests, runs, options, and dependencies — all derived from the manifest at comptime. The Options struct provides a natural extension point for future configuration without breaking the API. Breaking: configureBuild signature changed to accept a third opts parameter. Callers must add .{} as the third argument. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add documentation overhaul design spec B+C hybrid approach: README as landing page, docs/ for schema reference and motivation, examples/ as compilable annotated projects. Nukes all stale docs from the CLI tool era. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: fix spec review issues in docs overhaul design Add missing fields: zig_lib_dir/win32_manifest for libraries, zig_lib_dir for objects, passthrough/zig_lib_dir for tests, build-test step. Clarify target/optimize value types, link_libraries vs LazyPath colon syntax, LazyPath three-part form, inline module name override, help step metadata. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add documentation overhaul implementation plan 7 tasks: delete stale docs, write README/motivation/schema, create simple and full compilable examples, delete superpowers working docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: remove stale documentation from CLI tool era Delete MOTIVATION.md, TODO.md, AdvancedFeatures.md, and STRUCTURAL_ISSUES.md — all describe the old CLI tool architecture that no longer exists. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: rewrite README for library-based zbuild Pitch, before/after comparison, quickstart, feature list, and links to schema reference and examples. Replaces the stale CLI tool README. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add motivation doc explaining library approach Covers the problem (build.zig verbosity), the insight (@import + comptime), before/after comparison, and what zbuild is NOT. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add complete ZON schema reference Field tables for all manifest sections: modules, executables, libraries, objects, tests, fmts, runs, options_modules, dependencies. Plus LazyPath resolution, comptime validation, and configureBuild options. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: re-export API from build.zig and fix MakeOptions signature build.zig now re-exports configureBuild and Options so dependents can access them via @import("zbuild"). Fix help step makeFn to use Step.MakeOptions instead of Progress.Node (Zig 0.14.1 API). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add simple example project Minimal zbuild project with one executable. Uses inline manifest due to @import("build.zig.zon") type resolution constraint in Zig 0.14. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add full example project showcasing all features Demonstrates modules, executables, libraries, tests, fmts, runs (short + long form), options_modules with @import, and custom help step name. Also fixes LibraryOptions type name for Zig 0.14.1. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: remove internal superpowers working documents Delete specs and plans from docs/superpowers/ — these were internal development artifacts, not user-facing documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: accept enum literals for option type field options_modules .type field now accepts both enum literals (.bool) and strings ("bool") via toComptimeString. Enum literal form is preferred in docs and examples. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add BuildResult API design spec configureBuild returns BuildResult with typed getters for all entities: executables, libraries, objects, tests, modules, dependencies, options_modules, runs, fmts. install_steps stays internal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: return BuildResult from configureBuild configureBuild now returns a BuildResult struct with typed getters for all created entities: executable(), library(), object(), testArtifact(), module(), dependency(), optionsModule(), run(), fmt(). BuildRunner's per-entity state is restructured into a BuildResult field that becomes the return value. install_steps remains internal for depends_on wiring. This enables post-configure artifact modification, hybrid builds, and access to private modules — the escape hatch made ergonomic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: fix BuildResult getters, propagate errors, extract help.zig Fix bug where three BuildResult getters referenced self.result.X instead of self.X. Propagate OOM errors consistently — createModule, createRun, createFmt now return Error instead of panicking. Extract ~180 lines of help text generation into src/help.zig, keeping build_runner.zig focused on build graph construction. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: depends_on supports explicit step references depends_on entries can now reference any named step using colon syntax: "test:unit", "build-test:unit", "cmd:deploy", "fmt:src", "run:myapp", "build-exe:myapp", "build-lib:mylib", "build-obj:myobj". Plain names (enum literals or strings without colons) continue to reference artifact install steps as before. Comptime validation maps step prefixes to manifest sections. Runtime wiring looks up b.top_level_steps for colon-form references. This makes tests, runs, and fmts valid depends_on targets — previously only executables, libraries, and objects worked. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: move help tests to help.zig Move buildHelpText, comptimePad, describeValue tests to help.zig where the functions live. build_runner.zig keeps 20 tests, help.zig has 4. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: cleanup pass — re-export chain, version bump, depends_on for tests - build.zig imports build_runner.zig directly (skip main.zig passthrough) - Version bump to 0.4.0 (breaking API changes since 0.3.0) - wireDependsOn now handles tests via top_level_steps lookup - Delete leftover docs/specs/ - Update schema.md: depends_on step reference syntax, LazyPath collision note Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: remove main.zig, use build_runner.zig as module root main.zig was a pure passthrough with no added value. build_runner.zig is now the root source file for both the zbuild module and tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: centralize depends_on wiring in wireDependsOn Move runs depends_on wiring from createRun into wireDependsOn, alongside artifacts and tests. All dependency wiring now happens in Phase 11, keeping creation phases focused on creation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * build: migrate to Zig 0.16.0 * fix: generate typed options modules * fix: validate dependency-backed manifest references * fix: isolate inline root module namespaces * fix: support manual build.zig interop * fix: reject invalid manifest fields * test: add fixture integration coverage * fix: harden manifest validation and manual interop * fix: split manifest refs by ownership * fix: reserve unified import namespace * fix: harden fixture integration checks * fix: harden depends_on artifact refs * fix: tighten manual ref validation * docs: refine onboarding and examples * feat: add alias steps * ci: add GitHub Actions test workflow * feat: add named option presets * fix: forward target/optimize to dependencies by default `configureBuild` previously resolved every dependency that lacked an explicit `.args` field via `b.dependency(name, .{})`. Empty args mean the child build's `b.standardOptimizeOption` and `b.standardTargetOptions` fall back to their own defaults (host target, Debug) regardless of the parent's CLI flags. For C-heavy deps this is a real footgun: in Debug, Zig's default `sanitize_c=.full` emits `__ubsan_handle_*` external calls into the dep's object files. When the parent links those objects into a shared library (e.g. a Node NAPI `.node`), the symbols stay unresolved and the library fails to dlopen at runtime despite `-Doptimize=ReleaseSafe` being passed to the top-level `zig build`. Forward `runner.target` and `runner.optimize` by default so child builds inherit the parent's CLI resolution. Users who need full control (e.g. pin a dep to a specific optimize) can still supply `.args` explicitly; in that case zbuild passes their args through unchanged without injecting anything. Tested with: - zig build test (26/26) - zig build test:fixtures (all passing) * feat: support linker_allow_shlib_undefined for tests Tests that link against C symbols which the runtime resolves at dlopen time (e.g. napi C symbols Node provides when loading a `.node` file) need this flag so the linker doesn't fail standalone test binaries. Previously the option was only allowed for libraries; mirror the same behaviour for tests: - `isKnownArtifactField`: accept `linker_allow_shlib_undefined` in `tests` in addition to `libraries`. - `createTest`: copy the field onto the resulting Compile artifact post-create, mirroring `createLibrary`. - Extend the `stdlib_passthrough` fixture to set the field on both the library and the test entry, exercising both code paths. - Document the field on the `tests` schema table. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Chen Kai <grapebabamarch@outlook.com> Co-authored-by: Chen Kai <281165273grape@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before, any feature here that alters codegen can cause diffs in generated
build.zigdue to formatting errors. This is quite annoying. (see ChainSafe/ssz-z#42 as an example)Now, after syncing
build.zig, format it usingzig fmt.