0.16.0 Released

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?

1 Like

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

3 Likes

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.

1 Like

It also has the great advantage that you can subsequently make your own optimizations.

1 Like

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.

7 Likes

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.

2 Likes