C import not found

I am trying to refactor my game engine, but I am not quite sure on how to setup the build script properly.
Here is my tree:

│   .gitattributes
│   .gitignore
│   build.zig
│   build.zig.zon
│   README.md
│
├───deps
│   │   gl41.zig
│   │   stb_image.c
│   │   stb_image.h
│   │
│   └───math
│           collision.zig
│           main.zig
│           mat.zig
│           quat.zig
│           ray.zig
│           vec.zig
│
├───examples
│   ├───game1
│   │       main.zig
│   │
│   └───sandbox
│           frag.glsl
│           main.zig
│           vert.glsl
│
├───src
│   │   c.zig
│   │   color.zig
│   │   engine.zig
│   │
│   ├───assets
│   │       doubleTexture.glsl
│   │       prototype.png
│   │       wall.jpg
│   │
│   └───core
│           input.zig
│           primitives.zig
│           resources.zig
│           zorion.zig
│
└───zig-out

And here is my build script:

const std = @import("std");

const mach_glfw = @import("mach_glfw");

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

    buildExamples(b, target, optimize);
}

// Add examples to the build system
// Copied from mach
fn buildExamples(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) void {
    for ([_]struct { name: []const u8 }{
        .{ .name = "sandbox" },
        .{ .name = "game1" },
    }) |example| {
        const exe = b.addExecutable(.{
            .name = example.name,
            .root_source_file = b.path(b.fmt("examples/{s}/main.zig", .{example.name})),
            .target = target,
            .optimize = optimize,
        });

        addDependencies(exe, b, target, optimize);
        b.installArtifact(exe);

        const run_cmd = b.addRunArtifact(exe);
        run_cmd.step.dependOn(b.getInstallStep());
        if (b.args) |args| {
            run_cmd.addArgs(args);
        }

        const run_step = b.step(b.fmt("run-{s}", .{example.name}), b.fmt("Run {s}", .{example.name}));
        run_step.dependOn(&run_cmd.step);
    }
}

fn addDependencies(
    exe: *std.Build.Step.Compile,
    b: *std.Build,
    target: std.Build.ResolvedTarget,
    optimize: std.builtin.OptimizeMode,
) void {
    // Use mach-glfw
    const glfw_dep = b.dependency("mach_glfw", .{
        .target = target,
        .optimize = optimize,
    });
    exe.root_module.addImport("mach-glfw", glfw_dep.module("mach-glfw"));

    // gl
    const glModule = b.createModule(.{
        .root_source_file = b.path("deps/gl41.zig"),
    });
    exe.root_module.addImport("gl", glModule);

    // mach math
    const mathModule = b.createModule(.{ .root_source_file = b.path("deps/math/main.zig") });
    exe.root_module.addImport("math", mathModule);

    exe.root_module.addImport("engine", b.createModule(.{
        .root_source_file = b.path("src/engine.zig"),
        .imports = &.{
            .{ .name = "mach-glfw", .module = glfw_dep.module("mach-glfw") },
            .{ .name = "gl", .module = glModule },
            .{ .name = "math", .module = mathModule },
        },
        .link_libc = true,
    }));

    // Include C
    exe.linkLibC();
    exe.addCSourceFile(.{ .file = b.path("deps/stb_image.c"), .flags = &.{} });

    exe.addIncludePath(b.path("deps"));
}

This seems fine to me but when I try to import c.zig : pub usingnamespace @cImport({ @cInclude("stb_image.h"); });

I get the following error:

src\c.zig:1:20: error: C import failed
pub usingnamespace @cImport({
                   ^~~~~~~~
C:\Programming\Zig\Projects\Zorion\.zig-cache\o\403edccba46a0519cd979dbadb159793\cimport.h:1:10: error: 'stb_image.h' file not found
#include <stb_image.h>

My first question, is how to fix the error above.
My second quesion is, more about the build.zig file. Would this be a ‘good’ way of doing this or not?

Thanks in advance.

Also here is a link to the github

hmm, built it just fine on linux

fridge@partlyfridge[~/d/zorion]:zig build --summary all                                                                                                                                master 
Build Summary: 11/11 steps succeeded
install cached
└─ install glfw-test cached
   └─ zig build-exe glfw-test Debug native cached 26ms MaxRSS:110M
      ├─ zig build-lib glfw Debug native cached 26ms MaxRSS:109M
      │  ├─ zig build-lib x11-headers Debug native cached 16ms MaxRSS:108M
      │  │  └─ WriteFile empty.c cached
      │  ├─ WriteFile GL cached
      │  ├─ zig build-lib wayland-headers Debug native cached 16ms MaxRSS:109M
      │  │  └─ WriteFile empty.c cached
      │  └─ WriteFile . cached
      └─ WriteFile GLFW cached

I havent pushed this change yet, since it doesnt work. I will push now so you can try again

1 Like

Add include search path for the module

// build.zig
...
    const engine_module = b.createModule(.{
        .root_source_file = b.path("src/engine.zig"),
        .imports = &.{
            .{ .name = "mach-glfw", .module = glfw_dep.module("mach-glfw") },
            .{ .name = "gl", .module = glModule },
            .{ .name = "math", .module = mathModule },
        },
        .link_libc = true,
    });
    engine_module.addIncludePath(b.path("deps"));

    exe.root_module.addImport("engine", engine_module);

Add reexports for modules

// src/engine.zig
...
pub const math = @import("math");
pub const glfw = @import("mach-glfw");
pub const gl = @import("gl");
3 Likes

This is perfect, many thanks!