Can't find imported module

here’s my build.zig file, in which i just added "ini" as one of my dependencies:

const std = @import("std");

const DEPS = [_][]const u8{
    "ini",
    "zig-cli",
};

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});
    const exe = b.addExecutable(.{
        .name = "zig-em",
        .root_source_file = std.Build.path(b, "src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    for (DEPS) |name| {
        const dep = b.dependency(name, .{
            .target = target,
            .optimize = optimize,
        });
        exe.root_module.addImport(name, dep.module(name));
    }

    b.installArtifact(exe);
}

and here’s my build.zig.zon file, which references both of dependencies:

.{
    .name = "zig-em",
    .version = "0.24.0",
    .paths = .{"./src"},
    .dependencies = .{
        .ini = .{
            .url = "https://github.com/ziglibs/ini/archive/e18d36665905c1e7ba0c1ce3e8780076b33e3002.tar.gz", // 0.13.0
            .hash = "1220ab73fb7cc11b2308edc3364988e05efcddbcac31b707f55e6216d1b9c0da13f1" , // a temporary "wrong" hash,
        },
        .@"zig-cli" = .{
            .url = "https://github.com/sam701/zig-cli/archive/9a94c4803a52e54c26b198096d63fb5bde752da2.tar.gz", // 0.9.0
            .hash = "1220ab73fb7cc11b2308edc3364988e05efcddbcac31b707f55e6216d1b9c0da13f1"
        },
    },
}

not known the actual hash for the new ini module, i was hoping to get an earlier error from zig build which would inform me of the expected value…

when i build, however, it doesn’t appear to even process ini upfront… and later in the build, i receive the following error:

$ zig build
thread 18468 panic: unable to find module 'ini'
C:\tools\zig-windows-x86_64-0.13.0\lib\std\Build.zig:1857:18: 0xdac1a9 in module (build.exe.obj)
            panic("unable to find module '{s}'", .{name});
                 ^
C:\Users\biosb\zig\zig-em-dev\build.zig:23:51: 0xd64e3e in build (build.exe.obj)
        exe.root_module.addImport(name, dep.module(name));
                                                  ^
C:\tools\zig-windows-x86_64-0.13.0\lib\std\Build.zig:2116:33: 0xd4d955 in runBuild__anon_8953 (build.exe.obj)
        .Void => build_zig.build(b),
                                ^
C:\tools\zig-windows-x86_64-0.13.0\lib\compiler\build_runner.zig:301:29: 0xd48cec in main (build.exe.obj)
        try builder.runBuild(root);
                            ^
C:\tools\zig-windows-x86_64-0.13.0\lib\std\start.zig:363:53: 0xd4fb8c in WinStartup (build.exe.obj)
    std.os.windows.ntdll.RtlExitUserProcess(callMain());
                                                    ^
???:?:?: 0x7ff84da67373 in ??? (KERNEL32.DLL)
???:?:?: 0x7ff84f95cc90 in ??? (ntdll.dll)

i’m still learning about build.zig and may be missing something obvious…

You can’t use the hash from another dependency, because it will find a match for it, the wrong one. Try changing at least one digit.

2 Likes

The following statement is going to download and produce or update the entry in build.zig.zon:

zig fetch --save https://github.com/ziglibs/ini/archive/e18d36665905c1e7ba0c1ce3e8780076b33e3002.tar.gz

The hash of the dependency is its primary key. Zig looks in cache for this hash and expects to find it. You can use an empty string but the best way is the zig fetch --save

1 Like

this should be the “preferred way” – but it turns out that there was no build.zig.zon file hence it couldn’t determine the module’s name…

is there a command-line way to supply a module name???

i was, however, able to follow the advice of @LucasSantos91 to allow the build to succeed…

1 Like

If the dependency that you’re importing doesn’t have other dependencies in turn, then it’s not a problem if it doesn’t have a zon file.

The name of things is determined through other mechanisms.

To make sure we all share the same terminology:

  • Through the package manager you can depend on packages.
  • A package can export any of the following things:
    • Modules (Zig source code that can be imported)
    • Artifacts (executables, static libraries, etc)
    • Files (can be anything)

So, when you add a package to your dependencies, the name is defined in your zon file. The package can advertize a name of its own, but IIRC zig fetch by default uses the repo’s name (maybe somebody can correct me if it works differently), but regardless this is ultimately up to the consumer to set the name of their dependency to something they like.

This is how you can make zig fetch set a custom name:

zig fetch --save=foo git+https://github.com/bar/baz

Editing after the fact your zon file yields the same end result.

Now, once you have a dependency on a package, then you can reference it in your build.zig, using b.dependency().

From a dependency you can then extract modules, artifacts and files. When grabbing a module from a dependency, you have to use the same name they used in their build.zig.

Their build.zig:

_ = b.addModule("bananabread", .{ ... });

Your build.zig:

const foo = b.dependency("foo");
const bread = foo.module("bananabread");

That said you can rename modules when adding them as an import to your modules:

const my_program = b.addExecutable(.{...});
my_program.root_module.addImport("bb", bread);

Here I imported “bananabread” as “bb” for convenience.

For a dependency name, yes, I’ve showed that earlier in this post.

Sorry for the pedantry but I think it’s necessary to have clear communication about the package manager. Hopefully this post will help somebody who didn’t have a clear picture of where names are taken from.

5 Likes