Repository navigation
SDL callbacks and iOS simulator support #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ba81850
1cd7a14
781ef70
d7bbda8
7ecdd9d
d9969ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,14 +51,22 @@ pub fn build(b: *std.Build) !void { | |
| , | ||
| ) orelse .static; | ||
|
|
||
| const main_callbacks = b.option(bool, "main_callbacks", | ||
| \\build SDL3_main to enter the app through SDL_AppInit/Iterate/Event/Quit rather | ||
| \\than a classic SDL_main, defaults to false | ||
| ) orelse false; | ||
|
|
||
| const can_san = target.result.os.tag != .ios; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What triggers the sanitizer to fail? Instead of turning it off, maybe we can patch SDL to fix the UB. I've landed other UBSAN related fixes in SDL and they've been happy to merge them. |
||
|
|
||
| // Cross-compiling to a target whose SDK isn't bundled with Zig (iOS, Android) needs the | ||
| // SDK's headers/frameworks/libs passed in explicitly. Scoped to the SDL library only, unlike | ||
| // `--sysroot` this does not re-roots paths across the whole build graph. | ||
| const system_paths: SystemPaths = .{ | ||
| // On Apple, if paths are not passed explicitly then fall back to the SDK found via `xcrun`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
You can leave the translate C change here for now though since IIUC that's necessary for this to work at all.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that I ported my game to macOS, I understand why we're taking these paths in as build options. However, we shouldn't need to do any fixups on the paths here. If you're cross compiling then the caller needs to provide these paths, if you're not cross compiling they can all be left off. I suspect what's happening on your end is you're technically cross compiling to mac from mac because you set -Dtarget explicitly, and this is causing you to need to find the paths yourself, but I could be mistaken. If that's not the case let me know and I can help you figure out why it's not working for you without these changes. Good call on the translate C changes though, I just fixed those in master because I was blocked on them and credited you in the commit message.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, this is helpful for me (not much experience with this kind of thing, probably overcomplicating it). I'll work on understanding what's going on better and see if I can remove my SDK path stuff. |
||
| const system_paths = withAppleSdkFallback(b, target.result, .{ | ||
| .include = b.option(std.Build.LazyPath, "include_path", "SDK include dir, e.g. $(xcrun --sdk iphoneos --show-sdk-path)/usr/include or <ndk sysroot>/usr/include"), | ||
| .framework = b.option(std.Build.LazyPath, "framework_path", "SDK framework dir, e.g. $(xcrun --sdk iphoneos --show-sdk-path)/System/Library/Frameworks"), | ||
| .library = b.option(std.Build.LazyPath, "library_path", "SDK library dir, e.g. $(xcrun --sdk iphoneos --show-sdk-path)/usr/lib"), | ||
| }; | ||
| }); | ||
|
|
||
| // Get the SO version. This is the same as the SDL version, but the major version is elided | ||
| // since it's baked into the name. This mirrors the official build process. | ||
|
|
@@ -73,6 +81,7 @@ pub fn build(b: *std.Build) !void { | |
| .target = target, | ||
| .optimize = optimize, | ||
| .link_libc = true, | ||
| .sanitize_c = if (can_san) null else .off, | ||
| }), | ||
| .linkage = linkage, | ||
| .version = sdl_so_version, | ||
|
|
@@ -103,6 +112,24 @@ pub fn build(b: *std.Build) !void { | |
| .flags = flags, | ||
| }); | ||
|
|
||
| const main_lib = b.addLibrary(.{ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be a separate static library, or could we instead configure the existing SDL library differently depending on whether or not the callbacks feature is enabled? |
||
| .name = "SDL3_main", | ||
| .root_module = b.createModule(.{ | ||
| .target = target, | ||
| .optimize = optimize, | ||
| .link_libc = true, | ||
| .sanitize_c = if (can_san) null else .off, | ||
| }), | ||
| .linkage = .static, | ||
| }); | ||
| main_lib.root_module.addIncludePath(upstream.path("include")); | ||
| if (main_callbacks) { | ||
| main_lib.root_module.addCMacro("SDL_MAIN_USE_CALLBACKS", "1"); | ||
| } | ||
| main_lib.root_module.addCSourceFile(.{ .file = b.path("src/sdl_main.c") }); | ||
| addSystemPathsToModule(b, main_lib.root_module, system_paths); | ||
| b.installArtifact(main_lib); | ||
|
|
||
| if (default_target_config) { | ||
| const build_config_h = b.addConfigHeader(.{ | ||
| .style = .{ .cmake = upstream.path("include/build_config/SDL_build_config.h.cmake") }, | ||
|
|
@@ -152,6 +179,7 @@ pub fn build(b: *std.Build) !void { | |
| translate_c.defineCMacro("USING_GENERATED_CONFIG_H", "1"); | ||
| translate_c.addIncludePath(upstream.path("include")); | ||
| translate_c.addIncludePath(upstream.path("src/video/khronos")); | ||
| addSystemPathsToTranslateC(b, translate_c, system_paths); | ||
| const module = translate_c.addModule("sdl3"); | ||
| module.linkLibrary(lib); | ||
|
|
||
|
|
@@ -206,3 +234,46 @@ pub fn addDepIncludePath( | |
| lib.root_module.addIncludePath(dep.path(sub_path)); | ||
| } | ||
| } | ||
|
|
||
| /// Fill in any of `paths` from the SDK found with `xcrun`. Left unset outside Apple or if no SDK is found. | ||
| pub fn withAppleSdkFallback(b: *std.Build, target: std.Target, paths: SystemPaths) SystemPaths { | ||
| if (!target.os.tag.isDarwin()) return paths; | ||
| if (paths.include != null and paths.framework != null) return paths; | ||
|
|
||
| const sdk = std.zig.system.darwin.getSdk(b.allocator, b.graph.io, &target) orelse return paths; | ||
|
|
||
| return .{ | ||
| .include = paths.include orelse .{ .cwd_relative = b.pathJoin(&.{ sdk, "usr/include" }) }, | ||
| .framework = paths.framework orelse .{ .cwd_relative = b.pathJoin(&.{ sdk, "System/Library/Frameworks" }) }, | ||
| .library = paths.library orelse .{ .cwd_relative = b.pathJoin(&.{ sdk, "usr/lib" }) }, | ||
| }; | ||
| } | ||
|
|
||
| fn addSystemPathsToModule(b: *std.Build, module: *std.Build.Module, paths: SystemPaths) void { | ||
| if (paths.include) |p| module.addSystemIncludePath(p); | ||
| if (paths.framework) |p| { | ||
| module.addSystemFrameworkPath(p); | ||
| module.addSystemFrameworkPath(p.dirname().path(b, "SubFrameworks")); | ||
| } | ||
| if (paths.library) |p| module.addLibraryPath(p); | ||
| } | ||
|
|
||
| fn addSystemPathsToTranslateC(b: *std.Build, translate_c: *std.Build.Step.TranslateC, paths: SystemPaths) void { | ||
| if (paths.include) |p| translate_c.addSystemIncludePath(p); | ||
| if (paths.framework) |p| { | ||
| translate_c.addSystemFrameworkPath(p); | ||
| translate_c.addSystemFrameworkPath(p.dirname().path(b, "SubFrameworks")); | ||
| } | ||
| } | ||
|
|
||
| pub fn addAppleSdkPathsToModule(b: *std.Build, target: std.Target, module: *std.Build.Module) void { | ||
| if (!target.os.tag.isDarwin()) return; | ||
|
|
||
| const sdk = std.zig.system.darwin.getSdk(b.allocator, b.graph.io, &target) orelse | ||
| @panic("Couldn't detect Apple SDK"); | ||
|
|
||
| module.addSystemIncludePath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "usr/include" }) }); | ||
| module.addSystemFrameworkPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "System/Library/Frameworks" }) }); | ||
| module.addSystemFrameworkPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "System/Library/SubFrameworks" }) }); | ||
| module.addLibraryPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "usr/lib" }) }); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| #ifdef SDL_MAIN_USE_CALLBACKS | ||
| #include <SDL3/SDL_main.h> | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be reasonable to duplicate the example program and rename it to
callbacks_example, and make use of this feature there.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do!