spl3g
April 26, 2026, 7:52pm
1
I am transferring my project to zig 0.16.0 and since the @cImport is being depricated, i decided to move to addTranslateC.
Before, i just imported the dependency, added it’s include headers, and linked it with my executable:
build.zig
const libssh_dep = b.dependency("libssh", .{
.target = target,
.optimize = optimize,
.link_system_openssl = true,
});
exe.root_module.linkLibrary(libssh_dep.artifact("ssh"));
exe.root_module.addIncludePath(libssh_dep.path("include"));
main.zig
const c = @cImport({
@cInclude("libssh/libssh.h");
@cInclude("libssh/server.h");
@cInclude("libssh/callbacks.h");
});
And it worked perfectly.
Now, when i moved to addTranslateC, it just can’t find the headers.
build.zig
const libssh_dep = b.dependency("libssh", .{
.target = target,
.optimize = optimize,
.link_system_openssl = true,
});
exe.root_module.linkLibrary(libssh_dep.artifact("ssh"));
const translate_c = b.addTranslateC(.{
.root_source_file = b.path("src/c.h"),
.optimize = optimize,
.target = target,
.link_libc = true,
});
translate_c.addIncludePath(libssh_dep.path("include"));
exe_mod.addImport("c", translate_c.createModule());
$ zig build
install
└─ install meerkat
└─ compile exe meerkat Debug native
└─ translate-c 2 errors
error: translation failure
/.../src/c.h:1:10: error: 'libssh/libssh.h' not found
#include <libssh/libssh.h>
^
error: 2 compilation errors
failed command: /nix/store/5x5y75rc3l43ic0lwal6wzk7wi1ga3m1-zig-0.16.0/bin/zig translate-c -lc --cache-dir .zig-cache --global-cache-dir /home/jerpo/.cache/zig -I /.../zig-pkg/libssh-0.12.0-c_992s9iAABRROd8wCozUJ5-nnJdZhL9_wt1KqluuTlX/include /.../src/c.h --listen=-
I think you need to link the library with the translate_c module as well.
alanza
April 26, 2026, 9:12pm
3
Because your C file has
#include <libssh/libssh.h>
I believe your addIncludePath call should instead be an addSystemIncludePath call. I believe that’s the main way Zig distinguishes the way the <filename.h> specifier differs from the "filename.h".
2 Likes
dimdin
April 26, 2026, 10:08pm
4
In your c.h use "" instead of <> to include the files:
#include "libssh/libssh.h"
#include "libssh/server.h"
#include "libssh/callbacks.h"
When using <> the C compiler looks for the file in the system locations.
2 Likes
spl3g
April 27, 2026, 8:31am
5
Hi, @abdullah-b-al @dimdin @alanza , thanks for your answers but neither of them worked.
I believe that TranslateC does not have a linkLIbrary() method, only linkSystemLibrary(), which can’t find libssh because it is not installed on my system.
I have also tried using addSystemIncludePath with #include <libssh/libssh.h> and addIncludePath with #include "libssh/libssh.h", but to no avail.
I think i found the main problem here, the failed command points to the source code of the libssh dependency, not the output.
zig translate-c ... -I /.../meerkat/zig-pkg/libssh-0.12.0-c_992s9iAABRROd8wCozUJ5-nnJdZhL9_wt1KqluuTlX/include /.../meerkat/src/c.h --listen=-
$ ls zig-pkg/libssh-0.12.0-c_992s9iAABRROd8wCozUJ5-nnJdZhL9_wt1KqluuTlX
LICENSE README.md build.zig build.zig.zon zig-pkg
If that was always the case, i don’t know how the @cImport variant worked.
alanza
April 27, 2026, 10:41am
6
that was probably always the case, yeah. dependency.path() goes into the source tree of your dependency, just like b.path(). if you want to import the compiled artifact path, you’d modify that call.
spl3g
April 27, 2026, 10:49am
7
So, the solution for me is this:
const translate_c = b.addTranslateC(.{
.root_source_file = b.path("src/c.h"),
.optimize = optimize,
.target = target,
.link_libc = true,
});
translate_c.addIncludePath(libssh_dep.artifact("ssh").getEmittedIncludeTree());
exe_mod.addImport("c", translate_c.createModule());
2 Likes