If you use build.zig, then this is fine. But using a simple zig run main.zig, where main.zig uses @cImport is not possible anymore as far as I understand?
zero’th: zig is not a scripting language!!!
first: @cImport still exists, it is just deprecated, you are free to use it just expect it to be gone next release.
seccond: you can combind build.zig and main.zig to be the same file
zig build --build-file ./script.zig
copied from earlier msg in this topic by @tsdtas
code
const std = @import("std");
pub fn main() void {
const c = @import("c");
const log = std.log.scoped(.main);
log.info("running '{s}'", .{@src().file});
log.info("imported {d} declarations from c", .{std.meta.declarations(c).len});
log.info("strerror(0) = {s}", .{c.strerror(0)}); // for demo purposes
}
pub fn build(b: *std.Build) void {
const src = @src();
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const headers =
\\#include <string.h>
;
const write_tmp_file = b.addWriteFiles();
const tmp_file = write_tmp_file.add(src.module ++ ".h", headers);
const translate_c = b.addTranslateC(.{
.optimize = optimize,
.target = target,
.root_source_file = tmp_file,
});
const exe = b.addExecutable(.{
.name = src.module,
.root_module = b.createModule(.{
.root_source_file = b.path(src.file),
.target = target,
.optimize = optimize,
.imports = &.{.{
.name = "c",
.module = translate_c.createModule(),
}},
}),
});
const run_cmd = b.addRunArtifact(exe);
b.getInstallStep().dependOn(&run_cmd.step);
if (b.args) |args| {
run_cmd.addArgs(args);
}
}
though it would probably be easier to zig translate-c my_header.h then @import("my_header.zig") in your script
if you only want a script than sure its less convenient, but that use case of easily using C dode in Zig will always be supported, simply because it’s so fundamental to the language, and it’s ergonomic.
It also has the great advantage that you can subsequently make your own optimizations.
I got prompted to update my implementation of the Open Sound Control protocol to 0.16.0 and I just wanted to share that it felt great to get rid of std.posix calls for working with UDP sockets in favor of std.Io.net calls for the same.
That gives:
error: unused local constant
const translate_c = b.addTranslateC(.{
How is this expected to be used in a build script?
E.g.:
const c = b.addTranslateC(.{
.root_source_file = b.path("src/c.c"),
.link_libc = true,
.target = target,
.optimize = optimize,
});
const exe = b.addExecutable(.{
.name = "my-program",
.root_module = b.createModule(.{
.root_source_file = b.path("src/root.zig"),
.target = target,
.optimize = optimize,
.imports = &.{
.{ .name = "c", .module = c.createModule() },
},
}),
});
Then you do const c = @import("c"); wherever you want to use the translated headers.