glfw: fix caching bug in system_sdk that prevents cross-compilation in some situations
Prior to this change, cross-compiling Mach to other OSes was not working due to a regression. e.g. to windows: ``` zig build -Dtarget=x86_64-windows run-example-boids LLD Link... error(link): DLL import library for -ldxguid not found error: DllImportLibraryNotFound error: example-boids... ``` The problem was that one build step may invoke `getSdkRoot` and the target might be for say macOS, since it's building e.g. GLFW for macOS as the target of tests, and `getSdkRoot` would cache the SDK root _forever_ as being the macOS SDK (in an attempt to avoid running the various git commands needed to resolve the SDK root multiple times, which slows builds down.) We instead need to cache the SDK root per step, because the target may not be the same. Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
a7a7362848
commit
bf445c448b
1 changed files with 15 additions and 9 deletions
|
@ -80,7 +80,7 @@ fn includeSdkMacOS(b: *Builder, step: *std.build.LibExeObjStep, options: Options
|
||||||
const mac_12 = target.os.version_range.semver.isAtLeast(.{ .major = 12, .minor = 0 }) orelse false;
|
const mac_12 = target.os.version_range.semver.isAtLeast(.{ .major = 12, .minor = 0 }) orelse false;
|
||||||
const sdk_name = if (mac_12) options.macos_sdk_12 else options.macos_sdk_11;
|
const sdk_name = if (mac_12) options.macos_sdk_12 else options.macos_sdk_11;
|
||||||
const sdk_revision = if (mac_12) options.macos_sdk_12_revision else options.macos_sdk_11_revision;
|
const sdk_revision = if (mac_12) options.macos_sdk_12_revision else options.macos_sdk_11_revision;
|
||||||
const sdk_root_dir = getSdkRoot(b.allocator, options.github_org, sdk_name, sdk_revision) catch unreachable;
|
const sdk_root_dir = getSdkRoot(b.allocator, step, options.github_org, sdk_name, sdk_revision) catch unreachable;
|
||||||
|
|
||||||
if (options.set_sysroot) {
|
if (options.set_sysroot) {
|
||||||
step.addFrameworkDir("/System/Library/Frameworks");
|
step.addFrameworkDir("/System/Library/Frameworks");
|
||||||
|
@ -103,7 +103,7 @@ fn includeSdkMacOS(b: *Builder, step: *std.build.LibExeObjStep, options: Options
|
||||||
}
|
}
|
||||||
|
|
||||||
fn includeSdkLinuxX8664(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void {
|
fn includeSdkLinuxX8664(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void {
|
||||||
const sdk_root_dir = getSdkRoot(b.allocator, options.github_org, options.linux_x86_64, options.linux_x86_64_revision) catch unreachable;
|
const sdk_root_dir = getSdkRoot(b.allocator, step, options.github_org, options.linux_x86_64, options.linux_x86_64_revision) catch unreachable;
|
||||||
|
|
||||||
if (options.set_sysroot) {
|
if (options.set_sysroot) {
|
||||||
var sdk_sysroot = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "root/" }) catch unreachable;
|
var sdk_sysroot = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "root/" }) catch unreachable;
|
||||||
|
@ -125,7 +125,7 @@ fn includeSdkLinuxX8664(b: *Builder, step: *std.build.LibExeObjStep, options: Op
|
||||||
}
|
}
|
||||||
|
|
||||||
fn includeSdkLinuxAarch64(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void {
|
fn includeSdkLinuxAarch64(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void {
|
||||||
const sdk_root_dir = getSdkRoot(b.allocator, options.github_org, options.linux_aarch64, options.linux_aarch64_revision) catch unreachable;
|
const sdk_root_dir = getSdkRoot(b.allocator, step, options.github_org, options.linux_aarch64, options.linux_aarch64_revision) catch unreachable;
|
||||||
|
|
||||||
if (options.set_sysroot) {
|
if (options.set_sysroot) {
|
||||||
var sdk_sysroot = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "root/" }) catch unreachable;
|
var sdk_sysroot = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "root/" }) catch unreachable;
|
||||||
|
@ -147,7 +147,7 @@ fn includeSdkLinuxAarch64(b: *Builder, step: *std.build.LibExeObjStep, options:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn includeSdkWindowsX8664(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void {
|
fn includeSdkWindowsX8664(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void {
|
||||||
const sdk_root_dir = getSdkRoot(b.allocator, options.github_org, options.windows_x86_64, options.windows_x86_64_revision) catch unreachable;
|
const sdk_root_dir = getSdkRoot(b.allocator, step, options.github_org, options.windows_x86_64, options.windows_x86_64_revision) catch unreachable;
|
||||||
|
|
||||||
if (options.set_sysroot) {
|
if (options.set_sysroot) {
|
||||||
// We have no sysroot for Windows, but we still set one to prevent inclusion of other system
|
// We have no sysroot for Windows, but we still set one to prevent inclusion of other system
|
||||||
|
@ -167,16 +167,22 @@ fn includeSdkWindowsX8664(b: *Builder, step: *std.build.LibExeObjStep, options:
|
||||||
step.addLibPath(sdk_libs);
|
step.addLibPath(sdk_libs);
|
||||||
}
|
}
|
||||||
|
|
||||||
var cached_sdk_root: ?[]const u8 = null;
|
var cached_sdk_roots: ?std.AutoHashMap(*std.build.LibExeObjStep, []const u8) = null;
|
||||||
|
|
||||||
/// returns the SDK root path, determining it iff necessary. In a real application, this may be
|
/// returns the SDK root path, determining it iff necessary. In a real application, this may be
|
||||||
/// tens or hundreds of times and so the result is cached in-memory (this also means the result
|
/// tens or hundreds of times and so the result is cached in-memory (this also means the result
|
||||||
/// cannot be freed until the result will never be used again, which is fine as the Zig build system
|
/// cannot be freed until the result will never be used again, which is fine as the Zig build system
|
||||||
/// Builder.allocator is an arena, you don't need to free.)
|
/// Builder.allocator is an arena, you don't need to free.)
|
||||||
fn getSdkRoot(allocator: std.mem.Allocator, org: []const u8, name: []const u8, revision: []const u8) ![]const u8 {
|
fn getSdkRoot(allocator: std.mem.Allocator, step: *std.build.LibExeObjStep, org: []const u8, name: []const u8, revision: []const u8) ![]const u8 {
|
||||||
if (cached_sdk_root) |cached| return cached;
|
if (cached_sdk_roots == null) {
|
||||||
cached_sdk_root = try determineSdkRoot(allocator, org, name, revision);
|
cached_sdk_roots = std.AutoHashMap(*std.build.LibExeObjStep, []const u8).init(allocator);
|
||||||
return cached_sdk_root.?;
|
}
|
||||||
|
|
||||||
|
var entry = try cached_sdk_roots.?.getOrPut(step);
|
||||||
|
if (entry.found_existing) return entry.value_ptr.*;
|
||||||
|
const sdk_root = try determineSdkRoot(allocator, org, name, revision);
|
||||||
|
entry.value_ptr.* = sdk_root;
|
||||||
|
return sdk_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn determineSdkRoot(allocator: std.mem.Allocator, org: []const u8, name: []const u8, revision: []const u8) ![]const u8 {
|
fn determineSdkRoot(allocator: std.mem.Allocator, org: []const u8, name: []const u8, revision: []const u8) ![]const u8 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue