#Get build artifact name

1 messages · Page 1 of 1 (latest)

tall perch
#

I'm trying to use SDL in zig, but I don't know the artifact name to link against the library. How can I get the SDL artifact name when building?

quaint flower
#

For system library you just do exe.linkSystemLibrary("SDL2")
Although iirc SDL2 requires some pkg-config flags
So you probably have to do
exe.linkSystemLibrary2("SDL2", .{.use_pkg_config = .force});

tall perch
#

Building against an artifact generated by Zig

#

The systems library works fine for Linux

quaint flower
#

then youd just do exe.linkLibrary(sdl2_artifact)

tall perch
#

I tried this

const sdl_dep = b.dependency("sdl", .{
            .optimize = .ReleaseFast,
            .target = target,
});
        exe.linkLibrary(sdl_dep.artifact("SDL2"));

But it couldn't find the artifact

quaint flower
tall perch
#

build.zig.zon

.{
    .dependencies = .{
        .sdl2 = .{
            .url = "https://github.com/libsdl-org/SDL/archive/6e931bee01b34a9f7a51579bcaf9a95f7f9451ce.tar.gz",
            .hash = "1220ec85d374ee88bef257d568087e2ce633e47b66fe82ae4bfd4f8341cf55b3c53d",
        },
    },
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
        // For example...
        //"LICENSE",
        //"README.md",
    },
}

Build.zig

const std = @import("std");

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

    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "zig-sdl2",
        .root_source_file = .{ .cwd_relative = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });

    if (target.result.os.tag == .linux) {
        exe.linkSystemLibrary("SDL2");
        exe.linkLibC();
    } else {
        const sdl2_dep = b.dependency("sdl2", .{
            .target = target,
            .optimize = .ReleaseFast,
        });

        const sdl2 = sdl2_dep.artifact("SDL2");
        exe.linkLibrary(sdl2);
    }
    b.installArtifact(exe);
    const run_cmd = b.addRunArtifact(exe);

    run_cmd.step.dependOn(b.getInstallStep());

    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

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

Building on Ubuntu 22.04, zig 0.13 with zig build -Dtarget=x86_64-windows

quaint flower
tall perch
#

How can I build it then?

quaint flower
# tall perch How can I build it then?

Not very easily
Would require a lot of work
But youd basically translate the cmake files manually into zig code
Or you can just call cmake using the zig build system and use exe.addObjectFile to statically link it

#

Id highly recommend just dynamically linking it

tall perch
#

I see

#

I'll try to find some zig bindings then

tall perch
#

New question, can I cross compile to windows if I dynamically link my SDL install? As in, how to make this work when cross-compiling?

const std = @import("std");

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

    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "zig-sdl2",
        .root_source_file = .{ .cwd_relative = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });

    exe.linkSystemLibrary("SDL2");
    exe.linkSystemLibrary("SDL2_image");
    exe.linkLibC();
    b.installArtifact(exe);
    const run_cmd = b.addRunArtifact(exe);

    run_cmd.step.dependOn(b.getInstallStep());

    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}
granite valley
#

There is a fork of SDL2 from Andrew Kelly with the build system rewritten to use Zig's, though it is at version 2.26 instead of the latest version 2.30 (there is a PR for 2.30.5 which you could use instead):
https://github.com/andrewrk/SDL which redirects to https://github.com/allyourcodebase/SDL

Add it to your build.zig.zon under the "sdl2" dependency name:

.{
    // ...
    .dependencies = .{
        // ...
        .sdl2 = .{
            .url = "https://github.com/allyourcodebases/SDL/archive/ccb56626ec75638457ed36d45a53683371d909c5.tar.gz",
            // .hash = "<let zig tell you about the hash the first time>"
        },
        // ...
    },
    // ...
}

You simply need the following to link against SDL2 for any platform:

const sdl2_dep = b.dependency("sdl2", .{.target = target, .optimize = optimize});
exe.linkLibrary(sdl2_dep.artifact("SDL2"));

This will build and link against a static version of SDL2, meaning you will have less problems packaging you application for Windows (no need to copy DLLs next to your executable).

tall perch
granite valley
#

You can always add stb_image instead.
I use it often because it is a header-only C library that I can quickly and legally (public domain) copy into my projects:

// build.zig
exe.addCSourceFile(.{.file = b.path("src/stb_image.h"), .flags = &.{"-DSTB_IMAGE_IMPLEMENTATION"}});

// some-code.zig
const c = @cImport({
    @cInclude("./stb_image.h");
});

const path = "./image.png";
var width: c_int = undefined;
var height: c_int = undefined;
var channels: c_int = undefined;
const requested_channels: c_int = 4;
var pixels: [*c]c.stbi_uc = c.stbi_load(path, &width, &height, &channels, requested_channels) orelse {
    std.log.warn("failed to load image at: {s}", .{path});
    return error.UnloadableImage;
};
defer c.stbi_image_free(pixels);
tall perch
#

How do I load it on SDL? I managed to compile stb_image it adding
exe.addIncludePath(.{ .cwd_relative = "src/c" });
To my build,zig

#

Nvm, got build errors for stb_image

install
└─ install zig-sdl2
   └─ zig build-exe zig-sdl2 Debug native 1 errors
error: ld.lld: /home/cuc/git/sdl-zig-test/.zig-cache/o/fd73dbeaea7dbd8f5b4e5bc38dc0ac27/stb_image.o: unknown file type
error: the following command failed with 1 compilation errors:
/snap/zig/11625/zig build-exe -cflags -DSTB_IMAGE_IMPLEMENTATION -- /home/cuc/git/sdl-zig-test/src/c/stb_image.h -D_REENTRANT -I/usr/include/SDL2 -lSDL2 -ODebug -I /home/cuc/git/sdl-zig-test/src/c -Mroot=/home/cuc/git/sdl-zig-test/src/main.zig -lc --cache-dir /home/cuc/git/sdl-zig-test/.zig-cache --global-cache-dir /home/cuc/.cache/zig --name zig-sdl2 --listen=- 
Build Summary: 0/3 steps succeeded; 1 failed (disable with --summary none)
install transitive failure
└─ install zig-sdl2 transitive failure
   └─ zig build-exe zig-sdl2 Debug native 1 errors
error: the following build command failed with exit code 1:
/home/cuc/git/sdl-zig-test/.zig-cache/o/7982b0cbe8eb1fb1e41c7b5b8e5fc3de/build /snap/zig/11625/zig /home/cuc/git/sdl-zig-test /home/cuc/git/sdl-zig-test/.zig-cache /home/cuc/.cache/zig --seed 0xa3d10900 -Z935dbe42c00bc7bb
#

build.zig

const std = @import("std");

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

    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "zig-sdl2",
        .root_source_file = .{ .cwd_relative = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });

    exe.addIncludePath(.{ .cwd_relative = "src/c" });
    exe.addCSourceFile(.{ .file = b.path("src/c/stb_image.h"), .flags = &.{"-DSTB_IMAGE_IMPLEMENTATION"} });

    if (target.result.os.tag == .linux) {
        exe.linkSystemLibrary("SDL2");
        exe.linkLibC();
    } else {
        const sdl2_dep = b.dependency("sdl2", .{
            .target = target,
            .optimize = .ReleaseFast,
        });

        const sdl2 = sdl2_dep.artifact("SDL2");
        exe.linkLibrary(sdl2);
    }
    b.installArtifact(exe);
    const run_cmd = b.addRunArtifact(exe);

    run_cmd.step.dependOn(b.getInstallStep());

    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

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

Managed to get it running, but no image is displayed on screen. Code:

const c = @cImport({
    @cInclude("SDL2/SDL.h");
    @cInclude("stb_image.h");
});

pub fn main() !void {
    // init sdl
    const path = "sprites/mc.png";
    var width: c_int = undefined;
    var height: c_int = undefined;
    var channels: c_int = undefined;
    const requested_channels: c_int = 4;
    const pixels = c.stbi_load(path, &width, &height, &channels, requested_channels) orelse {
        return error.UnloadableImage;
    };
    defer c.stbi_image_free(pixels);
    const surface = c.SDL_CreateRGBSurfaceWithFormatFrom(pixels, 64, 32, 4 * 8, 4 * 64, c.SDL_PIXELFORMAT_RGBA32);
    const texture = c.SDL_CreateTextureFromSurface(renderer, surface);
    const src = c.SDL_Rect{ .x = 0, .y = 0, .w = 32, .h = 32 };
    const position = c.SDL_Rect{ .x = 400, .y = 300, .w = 32, .h = 32 };

    var quit = false;

    var dt: f32 = 0;
    var lastTime = c.SDL_GetTicks();
    while (!quit) {
        var event: c.SDL_Event = undefined;
        while (c.SDL_PollEvent(&event) != 0) {
            switch (event.type) {
                c.SDL_QUIT => {
                    quit = true;
                },
                c.SDL_KEYDOWN => {
                    switch (event.key.keysym.sym) {
                        c.SDLK_ESCAPE => {
                            quit = true;
                        },
                        else => {},
                    }
                },
                else => {},
            }
        }

        _ = c.SDL_RenderClear(renderer);
        _ = c.SDL_RenderCopy(renderer, texture, &src, &position);
        c.SDL_RenderPresent(renderer);

        c.SDL_Delay(10);
        const currentTime = c.SDL_GetTicks();
        dt = @as(f32, @floatFromInt(currentTime - lastTime)) / 1000.0;
        lastTime = currentTime;
    }
}
#

Everything works, edited the code with the fix

#

Thank you guys!