Commit 447a89cd4d

Andrew Kelley <andrew@ziglang.org>
2020-03-04 07:05:42
update self-hosted `zig targets` to print correct glibc availability
1 parent b21d44f
Changed files (3)
lib/std/fs.zig
@@ -663,11 +663,14 @@ pub const Dir = struct {
             return self.openFileW(&path_w, flags);
         }
         const path_c = try os.toPosixPath(sub_path);
-        return self.openFileC(&path_c, flags);
+        return self.openFileZ(&path_c, flags);
     }
 
+    /// Deprecated; use `openFileZ`.
+    pub const openFileC = openFileZ;
+
     /// Same as `openFile` but the path parameter is null-terminated.
-    pub fn openFileC(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {
+    pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {
         if (builtin.os.tag == .windows) {
             const path_w = try os.windows.cStrToPrefixedFileW(sub_path);
             return self.openFileW(&path_w, flags);
@@ -753,9 +756,9 @@ pub const Dir = struct {
         return self.openFile(sub_path, .{});
     }
 
-    /// Deprecated; call `openFileC` directly.
+    /// Deprecated; call `openFileZ` directly.
     pub fn openReadC(self: Dir, sub_path: [*:0]const u8) File.OpenError!File {
-        return self.openFileC(sub_path, .{});
+        return self.openFileZ(sub_path, .{});
     }
 
     /// Deprecated; call `openFileW` directly.
@@ -1403,7 +1406,7 @@ pub fn openFileAbsolute(absolute_path: []const u8, flags: File.OpenFlags) File.O
 /// Same as `openFileAbsolute` but the path parameter is null-terminated.
 pub fn openFileAbsoluteC(absolute_path_c: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {
     assert(path.isAbsoluteC(absolute_path_c));
-    return cwd().openFileC(absolute_path_c, flags);
+    return cwd().openFileZ(absolute_path_c, flags);
 }
 
 /// Same as `openFileAbsolute` but the path parameter is WTF-16 encoded.
src-self-hosted/introspect.zig
@@ -8,13 +8,32 @@ const warn = std.debug.warn;
 
 /// 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" });
+    {
+        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);
 
-    var file = try fs.cwd().openRead(test_index_file);
+    const file = try fs.cwd().openFile(test_index_file, .{});
     file.close();
 
     return test_zig_dir;
src-self-hosted/print_targets.zig
@@ -4,6 +4,9 @@ const io = std.io;
 const mem = std.mem;
 const Allocator = mem.Allocator;
 const Target = std.Target;
+const assert = std.debug.assert;
+
+const introspect = @import("introspect.zig");
 
 // TODO this is hard-coded until self-hosted gains this information canonically
 const available_libcs = [_][]const u8{
@@ -55,57 +58,40 @@ const available_libcs = [_][]const u8{
     "x86_64-windows-gnu",
 };
 
-// TODO this is hard-coded until self-hosted gains this information canonically
-const available_glibcs = [_][]const u8{
-    "2.0",
-    "2.1",
-    "2.1.1",
-    "2.1.2",
-    "2.1.3",
-    "2.2",
-    "2.2.1",
-    "2.2.2",
-    "2.2.3",
-    "2.2.4",
-    "2.2.5",
-    "2.2.6",
-    "2.3",
-    "2.3.2",
-    "2.3.3",
-    "2.3.4",
-    "2.4",
-    "2.5",
-    "2.6",
-    "2.7",
-    "2.8",
-    "2.9",
-    "2.10",
-    "2.11",
-    "2.12",
-    "2.13",
-    "2.14",
-    "2.15",
-    "2.16",
-    "2.17",
-    "2.18",
-    "2.19",
-    "2.22",
-    "2.23",
-    "2.24",
-    "2.25",
-    "2.26",
-    "2.27",
-    "2.28",
-    "2.29",
-    "2.30",
-};
-
 pub fn cmdTargets(
     allocator: *Allocator,
     args: []const []const u8,
     stdout: *io.OutStream(fs.File.WriteError),
     native_target: Target,
 ) !void {
+    const available_glibcs = blk: {
+        const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch |err| {
+            std.debug.warn("unable to find zig installation directory: {}\n", .{@errorName(err)});
+            std.process.exit(1);
+        };
+        defer allocator.free(zig_lib_dir);
+
+        var dir = try std.fs.cwd().openDirList(zig_lib_dir);
+        defer dir.close();
+
+        const vers_txt = try dir.readFileAlloc(allocator, "libc/glibc/vers.txt", 10 * 1024);
+        defer allocator.free(vers_txt);
+
+        var list = std.ArrayList(std.builtin.Version).init(allocator);
+        defer list.deinit();
+
+        var it = mem.tokenize(vers_txt, "\r\n");
+        while (it.next()) |line| {
+            const prefix = "GLIBC_";
+            assert(mem.startsWith(u8, line, prefix));
+            const adjusted_line = line[prefix.len..];
+            const ver = try std.builtin.Version.parse(adjusted_line);
+            try list.append(ver);
+        }
+        break :blk list.toOwnedSlice();
+    };
+    defer allocator.free(available_glibcs);
+
     const BOS = io.BufferedOutStream(fs.File.WriteError);
     var bos = BOS.init(stdout);
     var jws = std.json.WriteStream(BOS.Stream, 6).init(&bos.stream);
@@ -150,7 +136,10 @@ pub fn cmdTargets(
     try jws.beginArray();
     for (available_glibcs) |glibc| {
         try jws.arrayElem();
-        try jws.emitString(glibc);
+
+        const tmp = try std.fmt.allocPrint(allocator, "{}", .{glibc});
+        defer allocator.free(tmp);
+        try jws.emitString(tmp);
     }
     try jws.endArray();