#Get build artifact name
1 messages · Page 1 of 1 (latest)
are you building SDL and linking against an Artifact generated by the zig build system?
Or are you just trying to use the system library?
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});
Building against an artifact generated by Zig
The systems library works fine for Linux
then youd just do exe.linkLibrary(sdl2_artifact)
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
What does your build.zig.zon look like? What sdl package are you using
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
You cant build sdl2 automatically like that
Theres no point in using the build system to fetch it if youre not building it with it
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
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);
}
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).
I found this fork which has 2.30
https://github.com/pwbh/SDL
My only issue is that it doesn't have SDL_image and other extensions
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);
stb has quite a few header-only libraries for C that are really useful.
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!