Open ghostbutter-games opened 1 year ago
Firstly, if we cross-compile, Zig doesn't autodetect sysroot and system include paths. It is up to the user to provide all of those via build.zig
or otherwise. However, this has currently regressed as far as I can tell, but with https://github.com/ziglang/zig/pull/16818, here's how this would work (please note this is a working diff I was testing my changes against so it all works for me on M1 mac with Zig in cross-compilation mode):
diff --git a/build.zig b/build.zig
index fdaf678..201e341 100644
--- a/build.zig
+++ b/build.zig
@@ -34,7 +34,16 @@ pub fn build(b: *std.Build) void {
const raylib = raylib_build.addRaylib(b, target, optimize, .{});
exe.linkLibC();
exe.linkLibrary(raylib);
- exe.addIncludePath("deps/raylib/src");
+ exe.addIncludePath(.{ .cwd_relative = "deps/raylib/src" });
+
+ if (target.isDarwin() and !target.isNative()) {
+ if (b.sysroot == null) {
+ @panic(" Pass --sysroot <path/to/macOS/SDK>");
+ }
+ exe.addSystemIncludePath(.{ .path = b.pathJoin(&.{ b.sysroot.?, "/usr/include" }) });
+ exe.addLibraryPath(.{ .path = b.pathJoin(&.{ b.sysroot.?, "/usr/lib" }) });
+ exe.addFrameworkPath(.{ .path = b.pathJoin(&.{ b.sysroot.?, "/System/Library/Frameworks" }) });
+ }
// This *creates* a Run step in the build graph, to be executed when another
// step is evaluated that depends on it. The next line below will establish
And changes to the raylib
wrapper:
diff --git a/src/build.zig b/src/build.zig
index 64480a4f..e6c80e9b 100644
--- a/src/build.zig
+++ b/src/build.zig
@@ -1,4 +1,5 @@
const std = @import("std");
+const builtin = @import("builtin");
// This has been tested to work with zig master branch as of commit 87de821 or May 14 2023
pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.builtin.OptimizeMode, options: Options) *std.Build.CompileStep {
@@ -18,7 +19,7 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
// No GLFW required on PLATFORM_DRM
if (!options.platform_drm) {
- raylib.addIncludePath(srcdir ++ "/external/glfw/include");
+ raylib.addIncludePath(.{ .cwd_relative = srcdir ++ "/external/glfw/include" });
}
raylib.addCSourceFiles(&.{
@@ -36,9 +37,9 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
if (options.raygui) {
_ = gen_step.add(srcdir ++ "/raygui.c", "#define RAYGUI_IMPLEMENTATION\n#include \"raygui.h\"\n");
- raylib.addCSourceFile(srcdir ++ "/raygui.c", raylib_flags);
- raylib.addIncludePath(srcdir);
- raylib.addIncludePath(srcdir ++ "/../../raygui/src");
+ raylib.addCSourceFile(.{ .file = .{ .cwd_relative = srcdir ++ "/raygui.c" }, .flags = raylib_flags });
+ raylib.addIncludePath(.{ .cwd_relative = srcdir });
+ raylib.addIncludePath(.{ .cwd_relative = srcdir ++ "/../../raygui/src" });
}
switch (target.getOsTag()) {
@@ -47,7 +48,7 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
raylib.linkSystemLibrary("winmm");
raylib.linkSystemLibrary("gdi32");
raylib.linkSystemLibrary("opengl32");
- raylib.addIncludePath("external/glfw/deps/mingw");
+ raylib.addIncludePath(.{ .cwd_relative = "external/glfw/deps/mingw" });
raylib.defineCMacro("PLATFORM_DESKTOP", null);
},
@@ -59,7 +60,7 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
raylib.linkSystemLibrary("dl");
raylib.linkSystemLibrary("m");
raylib.linkSystemLibrary("X11");
- raylib.addIncludePath("/usr/include");
+ raylib.addIncludePath(.{ .cwd_relative = "/usr/include" });
raylib.defineCMacro("PLATFORM_DESKTOP", null);
} else {
@@ -71,7 +72,7 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
raylib.linkSystemLibrary("rt");
raylib.linkSystemLibrary("m");
raylib.linkSystemLibrary("dl");
- raylib.addIncludePath("/usr/include/libdrm");
+ raylib.addIncludePath(.{ .cwd_relative = "/usr/include/libdrm" });
raylib.defineCMacro("PLATFORM_DRM", null);
raylib.defineCMacro("GRAPHICS_API_OPENGL_ES2", null);
@@ -95,6 +96,14 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
raylib.defineCMacro("PLATFORM_DESKTOP", null);
},
.macos => {
+ if (!target.isNative()) {
+ if (b.sysroot == null) {
+ @panic(" Pass --sysroot <path/to/macOS/SDK>");
+ }
+ raylib.addSystemIncludePath(.{ .path = b.pathJoin(&.{ b.sysroot.?, "/usr/include" }) });
+ raylib.addLibraryPath(.{ .path = b.pathJoin(&.{ b.sysroot.?, "/usr/lib" }) });
+ raylib.addFrameworkPath(.{ .path = b.pathJoin(&.{ b.sysroot.?, "/System/Library/Frameworks" }) });
+ }
// On macos rglfw.c include Objective-C files.
const raylib_flags_extra_macos = &[_][]const u8{
"-ObjC",
@@ -125,7 +134,7 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!");
dir.close();
- raylib.addIncludePath(cache_include);
+ raylib.addIncludePath(.{ .path = cache_include });
},
else => {
@panic("Unsupported OS");
Andrew was right when commenting on my diff above that explicit paths should not be needed, and indeed #16836 ensures this is the case. I will need to discuss the changes and the way forward with Andrew before it lands but I hope the general direction will hold in that targeting any Apple platform from a macOS host will autodetect the SDK for the user making specifying explicit search paths unneeded.
OK, I was wrong with the last comment too, and my diff stands. Here's the current status quo that I think is correct.
When we force the compiler to target a specific target triple, e.g., zig build -Dtarget=aarch64-macos
, we enter cross-compilation mode which means we do not treat the target of the compilation as native regardless of the host we are compiling on. This then implies that we do not detect the macOS SDK automatically in case when we issue zig build -Dtarget=aarch64-macos
on an arm64 macOS host. I have now convinced myself that this is a desired behavior, and here's why. Consider this situation executed on the latest macOS 13: zig build -Dtarget=aarch64-macos.11.0.0
. If we auto-detected the SDK we would most likely detect a mismatching one as by default, the active SDK on the user's host on macOS will match their OS version and hence the native target. In this situation, it should be up to the user to set the correct search paths and SDK via the build system. The same story applies to targeting remaining Apple platforms (iOS, watchOS, tvOS) from macOS host - the user ought to point at the right SDK one way or another. Note that issuing zig build
on macOS will correctly detect the SDK if available since we indeed want to target the host's version and SDK.
@andrewrk and @konsuko let me know your thoughts about this please!
@kubkon Thanks a lot for your help and input, I really appreciate it and understand the issue better now. Your last comment makes a lot of sense: It would probably make things worse if the SDK gets auto-detected in that case.
The most robust path seems to be to leave this up to the developer, even though it's not the most convenient way.
I just stumbled upon this issue but in my case it has nothing to do with cross-compiling to MacOS. In my case I'm using MacOS to cross-compile to Raspberry PI and I'm trying to use build.zig (to replace Makefile) and it fails to compile with -Dtarget=arm-linux-gnueabihf
. The interesting part is that Zig cross-compile with --target=arm-linux-gnueabihf
when I use it as drop in C compiler.
Here is my project's link https://github.com/marrony/canon-intervalometer
This is the output of my Makefile with cross-compile enabled to Raspberry PI:
make all OS=Linux ARCH=armv7l
cp canon-sdk/EDSDK/Library/ARM32/libEDSDK.so bin/
mkdir -p bin/web_root/assets
rm -rf bin/web_root/assets/*
cp -R web-ui/* bin/web_root/assets/
zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/main.o -c src/main.c
zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/camera.o -c src/camera.c
zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/http.o -c src/http.c
zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/queue.o -c src/queue.c
zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/timer.o -c src/timer.c
zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/mongoose.o -c src/mongoose.c
zig cc -o bin/canon-intervalometer bin/main.o bin/camera.o bin/http.o bin/queue.o bin/timer.o bin/mongoose.o -lpthread '-Wl,-rpath,\$ORIGIN' '-Wl,-rpath,.' -Lcanon-sdk/EDSDK/Library/ARM32 -l :libEDSDK.so --target=arm-linux-gnueabihf
cp run-canon.sh bin/run-canon.sh
it worked just fine.
Here is the output of zig build
:
zig build -Dtarget=arm-linux-gnueabihf
zig build-exe canon-intervalometer Debug arm-linux-gnueabihf: error: error(compilation): clang failed with stderr: /Users/marrony/Development/canon-intervalometer/src/timer.c:3:10: fatal error: 'errno.h' file not found
error(compilation): clang failed with stderr: In file included from /Users/marrony/Development/canon-intervalometer/src/queue.c:1:
/Users/marrony/Development/canon-intervalometer/src/queue.h:4:10: fatal error: 'pthread.h' file not found
error(compilation): clang failed with stderr: /Users/marrony/Development/canon-intervalometer/src/main.c:1:10: fatal error: 'getopt.h' file not found
error(compilation): clang failed with stderr: /Users/marrony/Development/canon-intervalometer/src/http.c:1:10: fatal error: 'stdio.h' file not found
error(compilation): clang failed with stderr: /Users/marrony/Development/canon-intervalometer/src/camera.c:6:10: fatal error: 'assert.h' file not found
error(compilation): clang failed with stderr: In file included from /Users/marrony/Development/canon-intervalometer/src/mongoose.c:20:
/Users/marrony/Development/canon-intervalometer/src/mongoose.h:359:10: fatal error: 'arpa/inet.h' file not found
zig build-exe canon-intervalometer Debug arm-linux-gnueabihf: error: the following command failed with 6 compilation errors:
/opt/homebrew/Cellar/zig/0.11.0/bin/zig build-exe -cflags -std=gnu17 -- /Users/marrony/Development/canon-intervalometer/src/camera.c /Users/marrony/Development/canon-intervalometer/src/http.c /Users/marrony/Development/canon-intervalometer/src/main.c /Users/marrony/Development/canon-intervalometer/src/mongoose.c /Users/marrony/Development/canon-intervalometer/src/queue.c /Users/marrony/Development/canon-intervalometer/src/timer.c -lEDSDK --cache-dir /Users/marrony/Development/canon-intervalometer/zig-cache --global-cache-dir /Users/marrony/.cache/zig --name canon-intervalometer -target arm-linux-gnueabihf -mcpu baseline -I /Users/marrony/Development/canon-intervalometer/src -I /Users/marrony/Development/canon-intervalometer/canon-sdk/EDSDK/Header -D TARGET_OS_LINUX -L /Users/marrony/Development/canon-intervalometer/canon-sdk/EDSDK/Library/ARM32 -rpath /Users/marrony/Development/canon-intervalometer/$ORIGIN -rpath /Users/marrony/Development/canon-intervalometer --listen=-
Build Summary: 0/3 steps succeeded; 1 failed (disable with --summary none)
install transitive failure
└─ install canon-intervalometer transitive failure
└─ zig build-exe canon-intervalometer Debug arm-linux-gnueabihf 6 errors
/Users/marrony/Development/canon-intervalometer/src/timer.c:1:1: error: unable to build C object: clang exited with code 1
/Users/marrony/Development/canon-intervalometer/src/queue.c:1:1: error: unable to build C object: clang exited with code 1
/Users/marrony/Development/canon-intervalometer/src/main.c:1:1: error: unable to build C object: clang exited with code 1
/Users/marrony/Development/canon-intervalometer/src/http.c:1:1: error: unable to build C object: clang exited with code 1
/Users/marrony/Development/canon-intervalometer/src/camera.c:1:1: error: unable to build C object: clang exited with code 1
/Users/marrony/Development/canon-intervalometer/src/mongoose.c:1:1: error: unable to build C object: clang exited with code 1
I really loved zig cc
because I'm now can cross-compile to Raspberry PI and just scp the binaries without having to install any compiler on Raspberry. On the other hand dealing with Makefiles is not fun so I'm trying to use zig build
to replace it and I was expecting to just work.
ps: I'm very new to Zig so I might be doing something wrong in my build.zig file.
ps 2: Surely I was doing something dummy with my build.zig
file, I fixed my issue by adding exe.linkLibC();
I just stumbled upon this issue but in my case it has nothing to do with cross-compiling to MacOS. In my case I'm using MacOS to cross-compile to Raspberry PI and I'm trying to use build.zig (to replace Makefile) and it fails to compile with
-Dtarget=arm-linux-gnueabihf
. The interesting part is that Zig cross-compile with--target=arm-linux-gnueabihf
when I use it as drop in C compiler.Here is my project's link https://github.com/marrony/canon-intervalometer
This is the output of my Makefile with cross-compile enabled to Raspberry PI:
make all OS=Linux ARCH=armv7l cp canon-sdk/EDSDK/Library/ARM32/libEDSDK.so bin/ mkdir -p bin/web_root/assets rm -rf bin/web_root/assets/* cp -R web-ui/* bin/web_root/assets/ zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/main.o -c src/main.c zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/camera.o -c src/camera.c zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/http.o -c src/http.c zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/queue.o -c src/queue.c zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/timer.o -c src/timer.c zig cc -isystem ./canon-sdk/EDSDK/Header -std=gnu17 -Wall -Werror -pedantic -DTARGET_OS_LINUX --target=arm-linux-gnueabihf -o bin/mongoose.o -c src/mongoose.c zig cc -o bin/canon-intervalometer bin/main.o bin/camera.o bin/http.o bin/queue.o bin/timer.o bin/mongoose.o -lpthread '-Wl,-rpath,\$ORIGIN' '-Wl,-rpath,.' -Lcanon-sdk/EDSDK/Library/ARM32 -l :libEDSDK.so --target=arm-linux-gnueabihf cp run-canon.sh bin/run-canon.sh
it worked just fine.
Here is the output of
zig build
:zig build -Dtarget=arm-linux-gnueabihf zig build-exe canon-intervalometer Debug arm-linux-gnueabihf: error: error(compilation): clang failed with stderr: /Users/marrony/Development/canon-intervalometer/src/timer.c:3:10: fatal error: 'errno.h' file not found error(compilation): clang failed with stderr: In file included from /Users/marrony/Development/canon-intervalometer/src/queue.c:1: /Users/marrony/Development/canon-intervalometer/src/queue.h:4:10: fatal error: 'pthread.h' file not found error(compilation): clang failed with stderr: /Users/marrony/Development/canon-intervalometer/src/main.c:1:10: fatal error: 'getopt.h' file not found error(compilation): clang failed with stderr: /Users/marrony/Development/canon-intervalometer/src/http.c:1:10: fatal error: 'stdio.h' file not found error(compilation): clang failed with stderr: /Users/marrony/Development/canon-intervalometer/src/camera.c:6:10: fatal error: 'assert.h' file not found error(compilation): clang failed with stderr: In file included from /Users/marrony/Development/canon-intervalometer/src/mongoose.c:20: /Users/marrony/Development/canon-intervalometer/src/mongoose.h:359:10: fatal error: 'arpa/inet.h' file not found zig build-exe canon-intervalometer Debug arm-linux-gnueabihf: error: the following command failed with 6 compilation errors: /opt/homebrew/Cellar/zig/0.11.0/bin/zig build-exe -cflags -std=gnu17 -- /Users/marrony/Development/canon-intervalometer/src/camera.c /Users/marrony/Development/canon-intervalometer/src/http.c /Users/marrony/Development/canon-intervalometer/src/main.c /Users/marrony/Development/canon-intervalometer/src/mongoose.c /Users/marrony/Development/canon-intervalometer/src/queue.c /Users/marrony/Development/canon-intervalometer/src/timer.c -lEDSDK --cache-dir /Users/marrony/Development/canon-intervalometer/zig-cache --global-cache-dir /Users/marrony/.cache/zig --name canon-intervalometer -target arm-linux-gnueabihf -mcpu baseline -I /Users/marrony/Development/canon-intervalometer/src -I /Users/marrony/Development/canon-intervalometer/canon-sdk/EDSDK/Header -D TARGET_OS_LINUX -L /Users/marrony/Development/canon-intervalometer/canon-sdk/EDSDK/Library/ARM32 -rpath /Users/marrony/Development/canon-intervalometer/$ORIGIN -rpath /Users/marrony/Development/canon-intervalometer --listen=- Build Summary: 0/3 steps succeeded; 1 failed (disable with --summary none) install transitive failure └─ install canon-intervalometer transitive failure └─ zig build-exe canon-intervalometer Debug arm-linux-gnueabihf 6 errors /Users/marrony/Development/canon-intervalometer/src/timer.c:1:1: error: unable to build C object: clang exited with code 1 /Users/marrony/Development/canon-intervalometer/src/queue.c:1:1: error: unable to build C object: clang exited with code 1 /Users/marrony/Development/canon-intervalometer/src/main.c:1:1: error: unable to build C object: clang exited with code 1 /Users/marrony/Development/canon-intervalometer/src/http.c:1:1: error: unable to build C object: clang exited with code 1 /Users/marrony/Development/canon-intervalometer/src/camera.c:1:1: error: unable to build C object: clang exited with code 1 /Users/marrony/Development/canon-intervalometer/src/mongoose.c:1:1: error: unable to build C object: clang exited with code 1
I really loved
zig cc
because I'm now can cross-compile to Raspberry PI and just scp the binaries without having to install any compiler on Raspberry. On the other hand dealing with Makefiles is not fun so I'm trying to usezig build
to replace it and I was expecting to just work.ps: I'm very new to Zig so I might be doing something wrong in my build.zig file.
ps 2: Surely I was doing something dummy with my
build.zig
file, I fixed my issue by addingexe.linkLibC();
The OP has a problem cross-compiling from macOS to macOS (i.e., explicitly putting Zig in cross-compilation mode via -Dtarget=aarch64-macos
). Your issue seems a problem cross-compiling from macOS to Raspberry Pie target, which will be a different issue and I believe warrants a new issue.
Hi @kubkon, is using exe.linkLibC()
not the correct thing to do when cross-compiling? I did this and it produced a working binary.
You misunderstood my comment. The OP's problem was specifically with cross-compiling to macOS, while yours is not.
@kubkon Does this apply to compiling to wasm on macOS or am I misunderstanding?
Zig Version
0.11.0-dev.4059+17255bed4
Steps to Reproduce and Observed Behavior
I uploaded a minimal example project that you can
git clone
to reproduce the issue: https://github.com/konsuko/zraylibtestPlease note that I am using macOS with the M1 CPU, version 13.3.1, but I believe this issues also appears on Windows (when a friend tested the same source code)
Expected Behavior
I am on macOS Ventura 13.3.1 (latest) and have a problem:
When compiling a minimal example project that uses Raylib (a C library for game development), I am encountering an error that I think might be a compiler bug:
When using
zig build
orzig build run
, everything works as expected and I have no errors: A window with a white background and an FPS counter opens up.When I try to (cross) compile from/to aarch64 macOS by using
zig build -Dtarget=aarch64-macos
, I am getting clang errors:I did some digging through other issues on Github and found this similar issue: https://github.com/ziglang/zig/issues/16235 I am not sure, but it looks like maybe the compiler is not finding macOS dylibs, even though they should exist on my machine (I have XCode command line tools installed and updated to the latest version).
Probably something that @kubkon would know more about?
I apologize if it's just me doing something dumb here and possibly an easy fix, I am very new to Zig and still learning :)