Skip to content

Customizing build

Chung Leong edited this page Oct 30, 2025 · 3 revisions

Zigar uses its built-in build.zig when compiling your Zig files. There are occasions when you might need to customize the build settings. For instance, when you're employing third-party packages.

Starting from version 0.14.2, you no longer need to override the whole file if you just need to import a package or add a C source file. You can use build.extra.zig instead.

To create a barebone build.extra.zig, go to the directory where your Zig file is stored and run the following command:

npx node-zigar extra

Replace "node-zigar" with the actual package you're using ("bun-zigar", "rollup-plugin-zigar", etc).

Initially, the file will have the following content:

const std = @import("std");

pub fn getImports(b: *std.Build, args: anytype) []const std.Build.Module.Import {
    _ = b;
    _ = args;
    // args contains the following:
    //
    //     library: *std.Build.Step.Compile,
    //     target: std.Build.ResolvedTarget,
    //     optimize: std.builtin.OptimizeMode,
    return &.{};
}

pub fn getCSourceFiles(b: *std.Build, args: anytype) []const []const u8 {
    _ = b;
    _ = args;
    // args contains the following:
    //
    //     library: *std.Build.Step.Compile,
    //     module: *std.Build.Module,
    //     target: std.Build.ResolvedTarget,
    //     optimize: std.builtin.OptimizeMode,
    return &.{};
}

pub fn getIncludePaths(b: *std.Build, args: anytype) []const []const u8 {
    _ = b;
    _ = args;
    // args contains the following:
    //
    //     library: *std.Build.Step.Compile,
    //     module: *std.Build.Module,
    //     target: std.Build.ResolvedTarget,
    //     optimize: std.builtin.OptimizeMode,
    return &.{};
}

As their names suggest, one function is used to add imports while the others are used to add C files and include paths respectively.

The functions are inlined into build() in build.zig. This means it's perfectly legal to return a pointer to a local variable.

Adding a package

const std = @import("std");

pub fn getImports(b: *std.Build, args: anytype) []const std.Build.Module.Import {
    const ziglua = b.dependency("ziglua", .{
        .target = args.target,
        .optimize = args.optimize,
    }).module("ziglua");
    return &.{
        .{ .name = "ziglua", .module = ziglua },
    };
}

Adding a C source file

const std = @import("std");

pub fn getCSourceFiles(_: *std.Build, _: anytype) []const []const u8 {
    args.library.addIncludePath(.{ .path =  });
    return &.{
        "libx/src/main.c",
    };
}

pub fn getIncludePaths(b: *std.Build, args: anytype) []const []const u8 {
    return &.{
        "libx/include",
    };
}

Paths are relative to the directory holding the root Zig file.

You can also call addCSourceFile directly if you need to set compiler flags:

    args.library.addCSourceFile(.{ 
      .file = .{ .cwd_relative = cfg.module_dir ++ "libx/src/main.c" }
      .flags = &.{"-std=c89"} 
    });

Build configuration: build.cfg.zig

Zigar uses a file called build.cfg.zig to communicate its settings to build.zig. You can import it in build.extra.zig if you need them for some reason:

const cfg = @import("build.cfg.zig");

It has the following decls:

  • eval_branch_quota
    Value provided to @setEvalBranchQuota() during export. Corresponds to the evalBranchQuota configuration option.
  • is_wasm
    Whether the target archecture is WebAssembly.
  • max_memory
    The maximum amount of memory that the WebAssembly VM can use. Corresponds to the maxMemory configuration option.
  • module_dir
    The full path to the parent directory of module_path (with trailing slash).
  • module_name
    The name of the module, i.e. the name of the Zig file without the extension.
  • module_path
    The full path to the Zig file specified in the import statement (directly or indirectly through modules).
  • multithreaded
    Whether multithreading is enabled. Corresponds to the multithreaded configuration option.
  • omit_functions
    Whether functions are being exported. Corresponds to the omitFunctions configuration option.
  • omit_variables
    Whether variables are being exported. Corresponds to the omitVariables configuration option.
  • output_path The full path to the .so, .dylib, or .dll. file being generated.
  • pdb_path The full path to the .pdb file (Windows debug information).
  • stack_size
    The size of the call stack in bytes. Corresponds to the stackSize configuration option.
  • use_libc
    Whether the C standard library should be linked in. Corresponds to the useLibc configuration option. Relevant only for compilation to WASM.
  • use_redirection Whether IO redirection is enabled.
  • zigar_src_path
    The full path to the directory holding Zigar's zig files.

Overriding builtin process

If for some reason you need to extensively tinker with the build process, you can use your own build file. Start by getting a copy of Zigar's build.zig. Go to the directory where your Zig file is stored and run:

npx node-zigar custom

Clone this wiki locally