Is there a way to run `addTranslateC` and importing the translated module directly in `build.zig`?

You can do this by compiling your C code to a dynamic library and using the lib in a custom build step that depends on the libs install step like this:

build.zig:

const std = @import("std");

pub fn build(b: *std.Build) !void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const c_dep_mod = blk: {
        const dep = b.dependency("c_dep", .{});
        const tc = b.addTranslateC(.{
            .root_source_file = dep.path("hello.h"),
            .target = b.graph.host,
            .optimize = optimize,
        });
        const mod = tc.createModule();
        mod.addCSourceFile(.{
            .file = dep.path("hello.c"),
            .flags = &.{"-std=c99"},
            .language = .c,
        });
        break :blk mod;
    };

    const lib = b.addLibrary(.{
        .name = "hello",
        .root_module = c_dep_mod,
        .linkage = .dynamic,
    });
    const c_dep_install_artifact = b.addInstallArtifact(lib, .{});

    const use_c_deps_step = UseCDeps.create(b);
    use_c_deps_step.dependOn(&c_dep_install_artifact.step);

    b.getInstallStep().dependOn(use_c_deps_step);

    [...]
}

const UseCDeps = struct {
    pub fn create(owner: *std.Build) *std.Build.Step {
        const step = owner.allocator.create(std.Build.Step) catch @panic("OOM");
        step.* = .init(.{
            .id = .custom,
            .name = "use c deps",
            .owner = owner,
            .makeFn = make,
        });
        return step;
    }

    pub fn make(step: *std.Build.Step, options: std.Build.Step.MakeOptions) !void {
        _ = options;
        const b = step.owner;

        // Adjust lib name to your target
        var c_deps = try std.DynLib.open(b.getInstallPath(.lib, "libhello.dylib"));
        defer c_deps.close();

        const helloFromC = c_deps.lookup(*const fn () callconv(.c) void, "hello_from_c").?;
        helloFromC();
    }
};

build.zig.zon:

.{
    [...]
    .dependencies = .{
        .c_dep = .{
            .path = "c_dep",
        },
    },
    [...]
}

c_dep/hello.h:

#pragma once

void hello_from_c();

c_dep/hello.c:

#include <stdio.h>

void hello_from_c() {
    printf("Hello from C!\n");
}

zig build output:

$ zig build
Hello from C!
4 Likes