139 lines
4.0 KiB
Zig
139 lines
4.0 KiB
Zig
//! Introspection and determination of system libraries needed by zig.
|
|
|
|
const std = @import("std");
|
|
const mem = std.mem;
|
|
const fs = std.fs;
|
|
const CacheHash = std.cache_hash.CacheHash;
|
|
|
|
/// Caller must free result
|
|
pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 {
|
|
{
|
|
const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib", "zig" });
|
|
errdefer allocator.free(test_zig_dir);
|
|
|
|
const test_index_file = try fs.path.join(allocator, &[_][]const u8{ test_zig_dir, "std", "std.zig" });
|
|
defer allocator.free(test_index_file);
|
|
|
|
if (fs.cwd().openFile(test_index_file, .{})) |file| {
|
|
file.close();
|
|
return test_zig_dir;
|
|
} else |err| switch (err) {
|
|
error.FileNotFound => {
|
|
allocator.free(test_zig_dir);
|
|
},
|
|
else => |e| return e,
|
|
}
|
|
}
|
|
|
|
// Also try without "zig"
|
|
const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib" });
|
|
errdefer allocator.free(test_zig_dir);
|
|
|
|
const test_index_file = try fs.path.join(allocator, &[_][]const u8{ test_zig_dir, "std", "std.zig" });
|
|
defer allocator.free(test_index_file);
|
|
|
|
const file = try fs.cwd().openFile(test_index_file, .{});
|
|
file.close();
|
|
|
|
return test_zig_dir;
|
|
}
|
|
|
|
/// Caller must free result
|
|
pub fn findZigLibDir(allocator: *mem.Allocator) ![]u8 {
|
|
const self_exe_path = try fs.selfExePathAlloc(allocator);
|
|
defer allocator.free(self_exe_path);
|
|
|
|
var cur_path: []const u8 = self_exe_path;
|
|
while (true) {
|
|
const test_dir = fs.path.dirname(cur_path) orelse ".";
|
|
|
|
if (mem.eql(u8, test_dir, cur_path)) {
|
|
break;
|
|
}
|
|
|
|
return testZigInstallPrefix(allocator, test_dir) catch |err| {
|
|
cur_path = test_dir;
|
|
continue;
|
|
};
|
|
}
|
|
|
|
return error.FileNotFound;
|
|
}
|
|
|
|
pub fn resolveZigLibDir(allocator: *mem.Allocator) ![]u8 {
|
|
return findZigLibDir(allocator) catch |err| {
|
|
std.debug.print(
|
|
\\Unable to find zig lib directory: {}.
|
|
\\Reinstall Zig or use --zig-install-prefix.
|
|
\\
|
|
, .{@errorName(err)});
|
|
|
|
return error.ZigLibDirNotFound;
|
|
};
|
|
}
|
|
|
|
/// Caller owns returned memory.
|
|
pub fn resolveGlobalCacheDir(allocator: *mem.Allocator) ![]u8 {
|
|
const appname = "zig";
|
|
|
|
if (std.Target.current.os.tag != .windows) {
|
|
if (std.os.getenv("XDG_CACHE_HOME")) |cache_root| {
|
|
return fs.path.join(allocator, &[_][]const u8{ cache_root, appname });
|
|
} else if (std.os.getenv("HOME")) |home| {
|
|
return fs.path.join(allocator, &[_][]const u8{ home, ".cache", appname });
|
|
}
|
|
}
|
|
|
|
return fs.getAppDataDir(allocator, appname);
|
|
}
|
|
|
|
pub fn openGlobalCacheDir() !fs.Dir {
|
|
var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
|
|
var fba = std.heap.FixedBufferAllocator.init(&buf);
|
|
const path_name = try resolveGlobalCacheDir(&fba.allocator);
|
|
return fs.cwd().makeOpenPath(path_name, .{});
|
|
}
|
|
|
|
var compiler_id_mutex = std.Mutex{};
|
|
var compiler_id: [16]u8 = undefined;
|
|
var compiler_id_computed = false;
|
|
|
|
pub fn resolveCompilerId(gpa: *mem.Allocator) ![16]u8 {
|
|
const held = compiler_id_mutex.acquire();
|
|
defer held.release();
|
|
|
|
if (compiler_id_computed)
|
|
return compiler_id;
|
|
compiler_id_computed = true;
|
|
|
|
var cache_dir = try openGlobalCacheDir();
|
|
defer cache_dir.close();
|
|
|
|
var ch = try CacheHash.init(gpa, cache_dir, "exe");
|
|
defer ch.release();
|
|
|
|
const self_exe_path = try fs.selfExePathAlloc(gpa);
|
|
defer gpa.free(self_exe_path);
|
|
|
|
_ = try ch.addFile(self_exe_path, null);
|
|
|
|
if (try ch.hit()) |digest| {
|
|
compiler_id = digest[0..16].*;
|
|
return compiler_id;
|
|
}
|
|
|
|
const libs = try std.process.getSelfExeSharedLibPaths(gpa);
|
|
defer {
|
|
for (libs) |lib| gpa.free(lib);
|
|
gpa.free(libs);
|
|
}
|
|
|
|
for (libs) |lib| {
|
|
try ch.addFilePost(lib);
|
|
}
|
|
|
|
const digest = ch.final();
|
|
compiler_id = digest[0..16].*;
|
|
return compiler_id;
|
|
}
|