-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
OpenGL not found on newer macOS #2208
Comments
Just to add a few tidbits that might help in issues such as these: -H optionuse the -H option for gcc/clang and it will show you pathnames of resolved header files -v optionuse the -v option for gcc/clang to show sub-process launch args and include/framework search paths -F optionthis is like -L option for libraries but for apple frameworks only -f optionthis is like the -l option for libraries but for apple frameworks only #include <OpenGL/file.h>using frameworks, the include directive always is prefixed with framework's name, in this case What The Fun is going on with Apple toolchains?Apple tools coming from Apple's developer site come in 2 flavours; Xcode and Command Line Tools (CLT). CLT is the "unix" way to build stuff - that is tools, SDK, etc, is all placed in locations found in CLT is only required for unix-style development. If you only intend to use Xcode IDE-driven development, then there is no need for CLT. But things like building your own free software, homebrew, macports, all just work easier with CLT. Without it is possible but you need to be a build guru or a masochist. Be aware CLT has some subtle artifacts. macOS comes with Framework runtimes installed but not headers (analogous to -dev packages in linux land). Installing CLT will also populate things like Uninstall can usually be done by removing Xcode has everything CLT has and more. IDE, and other GUI tools. Technically Xcode doesn't depend on CLT (or at least it didn't last time I verified).
|
Here's my massively hacky solution:
That got the tetris example to run on macos. |
Related: #2041 |
Extension of Dave's workaround (so that you don't have to change
build.zig: const std = @import("std");
const Builder = std.build.Builder;
const fs = std.fs;
pub fn build(b: *Builder) !void {
const exe = b.addExecutable("main", "main.zig");
exe.setBuildMode(b.standardReleaseOptions());
b.default_step.dependOn(&exe.step);
exe.linkSystemLibrary("glfw3");
if (comptime std.Target.current.isDarwin()) {
if (!try fileExists("include")) {
try fs.makeDir("include");
}
if (!try fileExists("include/OpenGL")) {
const locations = [_][]const u8{
"/System/Library/Frameworks/OpenGL.framework/Headers",
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/OpenGL.framework/Headers",
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/OpenGL.framework/Headers",
};
blk: {
for (locations) |dir| {
if (try fileExists(dir)) {
try fs.symLink(dir, "include/OpenGL");
break :blk;
}
}
@panic("Could not find OpenGL headers");
}
}
exe.addIncludeDir("include");
}
const run_cmd = exe.run();
const run_step = b.step("run", "Run the program");
run_step.dependOn(&run_cmd.step);
}
fn fileExists(filename: []const u8) !bool {
fs.File.access(filename) catch |err| switch (err) {
error.FileNotFound => return false,
else => return err,
};
return true;
} And then run |
Some example source to help build an OpenGL app on macOS:
const std = @import("std");
const Builder = @import("std").build.Builder;
fn probeSdkPath(b: *Builder, buf: *std.Buffer) void {
const args: [][:0]const u8 = &[_][:0]const u8{ "xcrun", "-show-sdk-path" };
const child = std.ChildProcess.init(args, b.allocator) catch |err| {
std.debug.panic("Unable to initialize child process {}: {}\n", .{args[0], @errorName(err)});
};
defer child.deinit();
child.stdin_behavior = .Ignore;
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Ignore;
child.env_map = b.env_map;
child.spawn() catch |err| std.debug.panic("Unable to spawn {}: {}\n", .{args[0], @errorName(err)});
var stdout_file_in_stream = child.stdout.?.inStream();
stdout_file_in_stream.stream.readUntilDelimiterBuffer(buf, '\n', 256) catch {
std.debug.panic("Failed to read output from {}\n", .{ args[0] });
};
const term = child.wait() catch |err| {
std.debug.panic("Unable to spawn {}: {}\n", .{args[0], @errorName(err)});
};
switch (term) {
.Exited => |code| {
const expect_code: u32 = 0;
if (code != expect_code) {
std.debug.panic("Process {} exited with error code {} but expected code {}\n", .{
args[0],
code,
expect_code,
});
}
},
.Signal => |signum| {
std.debug.panic("Process {} terminated on signal {}\n", .{ args[0], signum });
},
.Stopped => |signum| {
std.debug.panic("Process {} stopped on signal {}\n", .{ args[0], signum });
},
.Unknown => |code| {
std.debug.panic("Process {} terminated unexpectedly with error code {}\n", .{ args[0], code });
},
}
}
pub fn build(b: *Builder) void {
var buf = std.Buffer.initSize(b.allocator, 0) catch unreachable;
probeSdkPath(b, &buf);
buf.append("/System/Library/Frameworks") catch unreachable;
const frameworks_path = buf.toSliceConst();
std.debug.warn("--> FRAMEWORKS: {}\n", .{frameworks_path});
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("opengl", "src/main.zig");
exe.setBuildMode(mode);
exe.install();
exe.addFrameworkDir(frameworks_path);
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
} |
I updated @mikdusan's function to work with Zig 0.7.1, which no longer has const std = @import("std");
const Builder = std.build.Builder;
pub fn build(b: *Builder) !void {
// ...
if (target.isDarwin()) {
exe.addFrameworkDir(try getMacFrameworksDir(b));
// These now work fine:
exe.linkFramework("CoreFoundation");
exe.linkFramework("Cocoa");
}
// ...
}
fn getMacFrameworksDir(b: *Builder) ![]u8 {
const sdk = try b.exec(&[_][]const u8{ "xcrun", "-show-sdk-path" });
const parts = &[_][]const u8{
std.mem.trimRight(u8, sdk, "\n"),
"/System/Library/Frameworks",
};
return std.mem.concat(b.allocator, u8, parts);
} |
I think this is fixed now:
$ sw_vers
ProductName: macOS
ProductVersion: 13.1
BuildVersion: 22C65
$ zig version
0.11.0-dev.1016+e2d7b2bf3
$ zig build-exe main.zig -framework OpenGL
$ otool -L ./main
./main:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0)
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) |
OpenGL on macOS seems to have moved recently, so projects that use it may fail to build:
The new path to the framework is:
...and seems to require XCode being fully installed.
See @mikdusan's workaround (I think using OpenGL from source rather than Homebrew): https://gist.github.com/mikdusan/0645a06f14c2167130ac4b00feed82ed#gistcomment-2883034
The text was updated successfully, but these errors were encountered: