# Link against static C library with zig 0.16

**URL:** <https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234>\
**Category:** Help\
**Tags:** c\
**Created:** [April 29, 2026, 2:39pm UTC](https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234 "2026-04-29T14:39:19Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![gonzo](https://ziggit.dev/user_avatar/ziggit.dev/gonzo/32/54_2.png) [@gonzo](https://ziggit.dev/u/gonzo)\
**Post date:** [April 29, 2026, 2:39pm UTC](https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234/1 "2026-04-29T14:39:19Z")

</div>

As I mentioned on [another post I made](https://ziggit.dev/t/jetzig-and-http-zig-with-zig-0-16/15229/8), I am just starting to jump onboard zig 0.16. Can anybody point me to the current, recommended way to link against a simple C static library? I have files `gonzo.h` and `libgonzo.a`, and I’m looking for the correct incantation to place in my `build.zig` that will link the library into my executable, and make all of the library’s functions available to my zig code.

I would hope that the answer points me to the right, supported (let’s say, “future proof”) way of doing this – I remember doing it with `@cImport` / `@cInclude` in the past, but these are deprecated now, right?

I also would not mind if some generous soul explains how I might go about creating a “ziggier” wrapper for a C library. Perhaps pointing me to a nice (0.16) example?

Many thanks in advance!

---

<div class="post-metadata">

**Author:** ![spiffyk](https://ziggit.dev/user_avatar/ziggit.dev/spiffyk/32/7202_2.png) [@spiffyk](https://ziggit.dev/u/spiffyk)\
**Post date:** [April 29, 2026, 2:48pm UTC](https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234/2 "2026-04-29T14:48:05Z")

</div>

I believe the _linking_ API is the same.

As for headers, you’ll want to replace `@cImport` and `@cInclude` with [`std.Build.addTranslateC`](https://ziglang.org/documentation/0.16.0/std/#std.Build.addTranslateC). Make a small C header file (e.g. `imports.h`) that `#include`s everything you need, then translate it using the build system into a Zig module, e.g. [like so](https://ziggit.dev/t/0-16-0-released/14930/68).

---

<div class="post-metadata">

**Author:** ![spiffyk](https://ziggit.dev/user_avatar/ziggit.dev/spiffyk/32/7202_2.png) [@spiffyk](https://ziggit.dev/u/spiffyk)\
**Post date:** [April 29, 2026, 2:55pm UTC](https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234/3 "2026-04-29T14:55:20Z")

</div>

To provide more context, `addTranslateC` is basically what `@cImport` and `@cInclude` did in prior versions, but is now removed from the language itself and was instead moved out into the build system. This allows Zig to not be so tightly coupled to LLVM to ease development\[1\].

* * *

1. But LLVM should AFAIU still remain a very important part of the pipeline, it’s **not getting removed** , just less tightly coupled – people keep panicking about this every time it’s mentioned, so just to be clear

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [April 29, 2026, 3:13pm UTC](https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234/4 "2026-04-29T15:13:05Z")

</div>

Translate C is planned to be distributed as a package.

The most “future proof” solution is to depend on the translate C package:

[https://codeberg.org/ziglang/translate-c](https://codeberg.org/ziglang/translate-c)

Here is an example of linking a precompiled library (I don’t personally have an example for compiling the c files)  
[https://codeberg.org/jeffective/zenoh-zig/src/branch/main/build.zig](https://codeberg.org/jeffective/zenoh-zig/src/branch/main/build.zig)

And for a (maybe bad) example of wrapping the c API in a zig API:  
[https://codeberg.org/jeffective/zenoh-zig/src/commit/e7351b65a768127a1f46a6b3e1a20c31c58b93d5/src/Session.zig#L35](https://codeberg.org/jeffective/zenoh-zig/src/commit/e7351b65a768127a1f46a6b3e1a20c31c58b93d5/src/Session.zig#L35)

---

<div class="post-metadata">

**Author:** ![gonzo](https://ziggit.dev/user_avatar/ziggit.dev/gonzo/32/54_2.png) [@gonzo](https://ziggit.dev/u/gonzo)\
**Post date:** [April 29, 2026, 3:53pm UTC](https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234/5 "2026-04-29T15:53:47Z")

</div>

I managed to link my library. In the end I did this:

```zig
    exe.root_module.linkSystemLibrary("gonzo", .{});
    exe.root_module.linkSystemLibrary("crypto", .{});

```

However, that’s not exactly what I think I need. `libcrypto.so` lives in `/usr/lib`, so it is a proper system library. But `libgonzo.a` lives on its own directory, a sibling of my zig project; if I were linking with `cc`, I would add `... -L../gonzo -lgonzo` to the compilation line. To make this work with my `build.zig`, I had to hack it and copy `libgonzo.a` to `/usr/local/lib`.

What is the correct solution for this? If it is passing the correct `-L` flag, how would I do that in `build.zig`? Or should I do this differently?

---

<div class="post-metadata">

**Author:** ![dimdin](https://ziggit.dev/user_avatar/ziggit.dev/dimdin/32/1457_2.png) [@dimdin](https://ziggit.dev/u/dimdin)\
**Post date:** [April 29, 2026, 7:14pm UTC](https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234/6 "2026-04-29T19:14:35Z")

</div>

Install the `gonzo` library using `installArtifact` for `libgonzo.a` and `installHeader` for `gonzo.h`.

```zig
    const lib = b.addLibrary(.{
        .name = "gonzo", // library artifact name
        ...
    });
    // copy from src/ to $install_prefix/include/
    lib.installHeader(b.path("src/gonzo.h"), "gonzo.h");
    // copy a library artifact to $install_prefix/lib, an executable artifact to $install_prefix/bin
    b.installArtifact(lib);

```

After running `zig build install` the files must be in `$install_prefix/include/gonzo.h` and `$install_prefix/lib/libgonzo.a`

* * *

To link with the artifact `libgonzo.a`, load it from the dependency with `artifact` and then use `linkLibrary`. To include `gonzo.h` use `addIncludePath` with the dependency `include` path.

```zig
    const gonzo = b.dependency("gonzo", .{ // name of the dependency in build.zig.zon
        ...
     });

    exe.root_module.addIncludePath(gonzo.path("include")); // directory in $install_prefix
    const gonzo_lib = gonzo.artifact("gonzo"); // artifact name used in addLibrary
    exe.root_module.linkLibrary(gonzo_lib);

```

---

<div class="post-metadata">

**Author:** ![cornhusk](https://ziggit.dev/letter_avatar_proxy/v4/letter/c/b487fb/32.png) [@cornhusk](https://ziggit.dev/u/cornhusk)\
**Post date:** [May 2, 2026, 4:34pm UTC](https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234/7 "2026-05-02T16:34:01Z")

</div>

Hi, here is another example, static linking to a (pre compliled) C library, works on 0.16.0 and master 0.17\*-dev

> <https://github.com/doums/nvuv/blob/fe58955b0e030bc810122b9cfb76a053546ed0c2/build.zig#L13>

Key points are

1. use the `addTranslateC()` function to translate C library header(s) to zig
2. from the translated header, create a module and add it as an import in the binary module, so from zig code, you can `@import()` it
3. call `addObjectFile()` to “inject” into the binary module the C library (`.a`) (if you want static linking)

---

<div class="post-metadata">

**Author:** ![gonzo](https://ziggit.dev/user_avatar/ziggit.dev/gonzo/32/54_2.png) [@gonzo](https://ziggit.dev/u/gonzo)\
**Post date:** [May 4, 2026, 7:53am UTC](https://ziggit.dev/t/link-against-static-c-library-with-zig-0-16/15234/8 "2026-05-04T07:53:35Z")

</div>

Thank you everybody for their suggestions. This is what worked for me in the end:

```zig
const std = @import("std");

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

    // we get this from our build.zig.zon file
    const httpz = b.dependency("httpz", .{
        .target = target,
        .optimize = optimize,
    });

    const gonzo = b.addTranslateC(.{
        .root_source_file = b.path("../gonzo/include/gonzo.h"),
        .target = target,
        .optimize = optimize,
        .link_libc = true, // Required for most headers
    });

    const exe = b.addExecutable(.{
        .name = "server",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/server.zig"),
            .target = target,
            .optimize = optimize,
            .link_libc = true, // due to using libgonzo.a
            .imports = &.{
                .{ .name = "httpz", .module = httpz.module("httpz") },
                .{ .name = "gonzo", .module = gonzo.createModule() },
            },
        }),
    });

    // add gonzo library
    exe.root_module.addObjectFile(b.path("../gonzo/lib/libgonzo.a"));

    b.installArtifact(exe);

    const run_cmd = b.addRunArtifact(exe);
    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}

```
