How to get the header files from a C library packaged with build.zig module?

Hi everyone, I need some help regarding the zig build system and how to setup things properly. So currently I’m trying to leverage the Zig build system in order to create a library that’s easy to install across platform for my users. The library is a thin wrapper around Raylib. It’s written in C (but I will also have bindings for Zig but right now the C part is the main focus). So the library build system should.

1 - fetch raylib if it’s not already cached
2 - build raylib
3 - emit the header files of the raylib library.
4 - build my wrapper
5 - emit the header files of my wrapper

So I Figured that in both case the header files for both raylib and my library are defined and written, they don’t need to be “autogenerated” I just need to be able to install them alongside the zig-out output.

So far I’m able to build raylib, call it from both Zig and C, even run test etc. The library compile just fines, but I can’t find a way to get the header files from raylib, and I can’t export my header file that I have defined.

here is the build.zig file

const std = @import("std");
const rlz = @import("raylib-zig");

pub const c_source_files = &[_][]const u8{
    "src/mlx.c",
};

pub const c_debug_flags = &[_][]const u8{
    "-Wall",
    "-Werror",
    "-Wextra",
    "-fno-omit-frame-pointer",
    "-g3",
};

pub const c_release_flags = &[_][]const u8{
    "-O3",
    "-mtune=native",
};

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

    const raylib_dep = b.dependency("raylib-zig", .{
        .target = target,
        .optimize = optimize,
    });
    const raylib = raylib_dep.module("raylib");
    const raylib_artifact = raylib_dep.artifact("raylib");

    const lib = b.addStaticLibrary(.{
        .name = "mlx",
        .root_source_file = b.path("src/mlx.zig"),
        .optimize = optimize,
        .target = target,
    });

    lib.addIncludePath(b.path("src"));
    inline for (c_source_files) |source| {
        lib.addCSourceFile(.{ .file = b.path(source), .flags = switch (optimize) {
            .Debug => c_debug_flags,
            else => c_release_flags,
        } });
    }

    lib.linkLibrary(raylib_artifact);
    lib.root_module.addImport("raylib", raylib);
    b.installArtifact(lib);

    const lib_unit_test = b.addTest(.{
        .root_source_file = b.path("src/mlx.zig"),
        .optimize = optimize,
        .target = target,
    });

    lib_unit_test.addIncludePath(b.path("src"));
    inline for (c_source_files) |source| {
        lib_unit_test.addCSourceFile(.{ .file = b.path(source), .flags = switch (optimize) {
            .Debug => c_debug_flags,
            else => c_release_flags,
        } });
    }

    lib_unit_test.linkLibrary(raylib_artifact);
    lib_unit_test.root_module.addImport("raylib", raylib);

    const lib_run_unit_test = b.addRunArtifact(lib_unit_test);
    const test_step = b.step("test", "test mlx");
    test_step.dependOn(&lib_run_unit_test.step);
}

the build.zig.zon

.{
    .name = "minilibx",
    .version = "0.0.1",
    .dependencies = .{
        .@"raylib-zig" = .{
            .url = "https://github.com/Not-Nik/raylib-zig/archive/devel.tar.gz",
            .hash = "1220ff1a9e774784fe3f11ffe71bc0186f9e62eb0fe1727f676d038b62665a5c74c5",
        },
    },
    .paths = .{""},
}

and the file structure

.
├── build.zig
├── build.zig.zon
└── src
   ├── mlx.c
   ├── mlx.h
   └── mlx.zig

the main goal is that after some update to the build system the file structure once compiled should look like this :

.
├── build.zig
├── build.zig.zon
├── src
│  ├── mlx.c
│  ├── mlx.h
│  └── mlx.zig
└── zig-out
   └── lib
      ├── libmlx.a
      ├── mlx.h
      └── raylib.h

Voila I’m sure this is possible, but I can’t seem to find a way to express it properly

EDIT : looking on github I have found the way to do it for my own header but I’m still looking how to do it for raylib’s header

1 Like

Ok I have found the solution, I forgot to also do

b.installArtifact(raylib_artifact);

and for my own library header it was simply

lib.installHeadersDirectory(b.path("src"), "", .{});

So anyway problem solved :slight_smile:

1 Like