Commit 2b9302107f

Andrew Kelley <superjoe30@gmail.com>
2017-12-12 22:03:20
self-hosted: cleanup build looking for llvm-config
1 parent cd5fd65
Changed files (3)
std/buf_map.zig
@@ -42,6 +42,11 @@ pub const BufMap = struct {
         }
     }
 
+    pub fn get(self: &BufMap, key: []const u8) -> ?[]const u8 {
+        const entry = self.hash_map.get(key) ?? return null;
+        return entry.value;
+    }
+
     pub fn delete(self: &BufMap, key: []const u8) {
         const entry = self.hash_map.remove(key) ?? return;
         self.free(entry.key);
std/build.zig
@@ -671,6 +671,63 @@ pub const Builder = struct {
             };
         }
     }
+
+    pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) -> %[]const u8 {
+        if (self.env_map.get("PATH")) |PATH| {
+            for (names) |name| {
+                if (os.path.isAbsolute(name)) {
+                    return name;
+                }
+                var it = mem.split(PATH, []u8{os.path.delimiter});
+                while (it.next()) |path| {
+                    const full_path = %return os.path.join(self.allocator, path, name);
+                    if (os.path.real(self.allocator, full_path)) |real_path| {
+                        return real_path;
+                    } else |_| {
+                        continue;
+                    }
+                }
+            }
+        }
+        for (names) |name| {
+            if (os.path.isAbsolute(name)) {
+                return name;
+            }
+            for (paths) |path| {
+                const full_path = %return os.path.join(self.allocator, path, name);
+                if (os.path.real(self.allocator, full_path)) |real_path| {
+                    return real_path;
+                } else |_| {
+                    continue;
+                }
+            }
+        }
+        return error.FileNotFound;
+    }
+
+    pub fn exec(self: &Builder, argv: []const []const u8) -> []u8 {
+        const max_output_size = 100 * 1024;
+        const result = os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size) %% |err| {
+            std.debug.panic("Unable to spawn {}: {}", argv[0], @errorName(err));
+        };
+        switch (result.term) {
+            os.ChildProcess.Term.Exited => |code| {
+                if (code != 0) {
+                    warn("The following command exited with error code {}:\n", code);
+                    printCmd(null, argv);
+                    warn("stderr:{}\n", result.stderr);
+                    std.debug.panic("command failed");
+                }
+                return result.stdout;
+            },
+            else => {
+                warn("The following command terminated unexpectedly:\n");
+                printCmd(null, argv);
+                warn("stderr:{}\n", result.stderr);
+                std.debug.panic("command failed");
+            },
+        }
+    }
 };
 
 const Version = struct {
build.zig
@@ -92,81 +92,21 @@ const LibraryDep = struct {
 };
 
 fn findLLVM(b: &Builder) -> LibraryDep {
-    const libs_output = {
-        const args1 = [][]const u8{"llvm-config-5.0", "--libs", "--system-libs"};
-        const args2 = [][]const u8{"llvm-config", "--libs", "--system-libs"};
-        const max_output_size = 10 * 1024;
-        const good_result = os.ChildProcess.exec(b.allocator, args1, null, null, max_output_size) %% |err| {
-            if (err == error.FileNotFound) {
-                os.ChildProcess.exec(b.allocator, args2, null, null, max_output_size) %% |err2| {
-                    std.debug.panic("unable to spawn {}: {}\n", args2[0], err2);
-                }
-            } else {
-                std.debug.panic("unable to spawn {}: {}\n", args1[0], err);
-            }
-        };
-        switch (good_result.term) {
-            os.ChildProcess.Term.Exited => |code| {
-                if (code != 0) {
-                    std.debug.panic("llvm-config exited with {}:\n{}\n", code, good_result.stderr);
-                }
-            },
-            else => {
-                std.debug.panic("llvm-config failed:\n{}\n", good_result.stderr);
-            },
-        }
-        good_result.stdout
-    };
-    const includes_output = {
-        const args1 = [][]const u8{"llvm-config-5.0", "--includedir"};
-        const args2 = [][]const u8{"llvm-config", "--includedir"};
-        const max_output_size = 10 * 1024;
-        const good_result = os.ChildProcess.exec(b.allocator, args1, null, null, max_output_size) %% |err| {
-            if (err == error.FileNotFound) {
-                os.ChildProcess.exec(b.allocator, args2, null, null, max_output_size) %% |err2| {
-                    std.debug.panic("unable to spawn {}: {}\n", args2[0], err2);
-                }
-            } else {
-                std.debug.panic("unable to spawn {}: {}\n", args1[0], err);
-            }
-        };
-        switch (good_result.term) {
-            os.ChildProcess.Term.Exited => |code| {
-                if (code != 0) {
-                    std.debug.panic("llvm-config --includedir exited with {}:\n{}\n", code, good_result.stderr);
-                }
-            },
-            else => {
-                std.debug.panic("llvm-config failed:\n{}\n", good_result.stderr);
-            },
-        }
-        good_result.stdout
-    };
-    const libdir_output = {
-        const args1 = [][]const u8{"llvm-config-5.0", "--libdir"};
-        const args2 = [][]const u8{"llvm-config", "--libdir"};
-        const max_output_size = 10 * 1024;
-        const good_result = os.ChildProcess.exec(b.allocator, args1, null, null, max_output_size) %% |err| {
-            if (err == error.FileNotFound) {
-                os.ChildProcess.exec(b.allocator, args2, null, null, max_output_size) %% |err2| {
-                    std.debug.panic("unable to spawn {}: {}\n", args2[0], err2);
-                }
-            } else {
-                std.debug.panic("unable to spawn {}: {}\n", args1[0], err);
-            }
-        };
-        switch (good_result.term) {
-            os.ChildProcess.Term.Exited => |code| {
-                if (code != 0) {
-                    std.debug.panic("llvm-config --libdir exited with {}:\n{}\n", code, good_result.stderr);
-                }
-            },
-            else => {
-                std.debug.panic("llvm-config failed:\n{}\n", good_result.stderr);
-            },
-        }
-        good_result.stdout
+    const llvm_config_exe = b.findProgram(
+        [][]const u8{"llvm-config-5.0", "llvm-config"},
+        [][]const u8{
+            "/usr/local/opt/llvm@5/",
+            "/mingw64/bin",
+            "/c/msys64/mingw64/bin",
+            "c:/msys64/mingw64/bin",
+            "C:/Libraries/llvm-5.0.0/bin",
+        }) %% |err|
+    {
+        std.debug.panic("unable to find llvm-config: {}\n", err);
     };
+    const libs_output = b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"});
+    const includes_output = b.exec([][]const u8{llvm_config_exe, "--includedir"});
+    const libdir_output = b.exec([][]const u8{llvm_config_exe, "--libdir"});
 
     var result = LibraryDep {
         .libs = ArrayList([]const u8).init(b.allocator),