How to properly add C library to build.zig - Zig 0.13

Hey, I’m trying to add imlib2 to my project and I’m running into issues trying to compile. Here is the lines in my build.zig that I’m having issues with.

    exe.linkLibC();
    const imlib_dep = b.dependency("imlib2", .{
        .target = target,
        .optimize = optimize,
    });
    const imlib = imlib_dep.module("imlib2");
    exe.root_module.addImport("imlib2", imlib);
    exe.linkLibrary(imlib_dep.artifact("imlib2"));

Here is my build.zig.zon

    .dependencies = .{
        .zigx = .{
            .url = "https://github.com/marler8997/zigx/archive/854457eebd5f8106b7f5e72edaad71c9bc1f23f5.tar.gz",
            .hash = "122015319638676bf011816f83c25550bfd5dd55abb1ce3bd1a0b1dcb31b727f54da",
        },
        .imlib2 = .{
            .url = "https://github.com/deepin-community/imlib2/archive/f549bce0a94f65f29809334b3a5efc96fd2c7aee.tar.gz",
            .hash = "1220f784b38b675d4670d9afc8eceddcca8cf834bfb8bdd757241e7f46614cef8feb",
            // more updated non-GitHub link and hash
            //.url = "https://sourceforge.net/projects/enlightenment/files/imlib2-src/1.12.2/imlib2-1.12.2.tar.gz/download",
            //.hash = "122058bccbe0f3d2af4715a0f488a48ccb0b33e25600bc4a6753c8c1d1688adc7df4",
        },
    },

    .paths = .{
        //"",
        "build.zig",
        "build.zig.zon",
        "src",
    },

compiler error:

thread 21041 panic: unable to find module 'imlib2'
/usr/lib64/zig/9999/lib/std/Build.zig:1820:18: 0x1131337 in module (build)
            panic("unable to find module '{s}'", .{name});
                 ^
/home/wizard/fun/zig/learn/ziv/build.zig:26:35: 0x10e9bd9 in build (build)
    const imlib = imlib_dep.module("imlib2");
                                  ^
/usr/lib64/zig/9999/lib/std/Build.zig:2079:33: 0x10cf283 in runBuild__anon_8755 (build)
        .Void => build_zig.build(b),
                                ^
/usr/lib64/zig/9999/lib/compiler/build_runner.zig:300:29: 0x10ca6c2 in main (build)
        try builder.runBuild(root);
                            ^
/usr/lib64/zig/9999/lib/std/start.zig:511:37: 0x10b2105 in posixCallMainAndExit (build)
            const result = root.main() catch |err| {
                                    ^
/usr/lib64/zig/9999/lib/std/start.zig:253:5: 0x10b1c21 in _start (build)
    asm volatile (switch (native_arch) {
    ^

Both links do not work and I also tried to use “” in the zon file but that didn’t help. I also tried zig build fetch. Tried zig fetch --save "https://github.com/deepin-community/imlib2/archive/f549bce0a94f65f29809334b3a5efc96fd2c7aee.tar.gz"
and got:
error: unable to determine name; fetched package has no build.zig.zon file
same error with the sourceforge link as well.

tried some other things still no luck and still getting the same error:

    exe.addCSourceFiles(.{
        .root = imlib_dep.path(""),
        .files = &.{"imlib2.c"},
    });
    exe.installHeadersDirectory(imlib_dep.path(""), "", .{
        .include_extensions = &.{"Imlib2.h"},
    });

I also get the same error using 0.12.0.

Please let me know if I’m omitting important information.
Any help would be greatly appreciated! Thanks!

GitHub - deepin-community/imlib2 does not have a build.zig/build.zig.zon and is thus a “dumb tarball package” which the Zig build system treats as a simple tree of files. This is why imlib_dep.module("imlib2") won’t ever work (because the package doesn’t export any modules) and why zig fetch --save without explicitly specifying a name with --save=imlib2 fails (because there’s no build.zig.zon file declaring the package’s canonical name).

Resolving paths to files like imlib_dep.path("foo.c") should still work, you just need to remove any code that tries to resolve modules or artifacts.

However, if you are trying to build Imlib2 from source and link your artifacts with it, I suspect that what you are trying to do by adding C source files to your executable isn’t going to work. You need to actually build Imlib2 somehow, replicating everything that Imlib2’s makefiles do, and accomplishing all of that is usually a non-trivial task. Unless you want to put a lot of time into forking Imlib2 and porting it to the Zig build system, you’re probably going to have a much easier time if you instead install it to your host system and link with it as a regular system library.

4 Likes

Thank you this was super helpful. It works for me now.

For inspiration, you can find here a list of projects that has been “zigged”.