From 2b9302107fdd4adbbcfc2735afd7f2e4cd4c6769 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 12 Dec 2017 16:03:20 -0500 Subject: [PATCH] self-hosted: cleanup build looking for llvm-config --- build.zig | 88 ++++++++----------------------------------------- std/buf_map.zig | 5 +++ std/build.zig | 57 ++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 74 deletions(-) diff --git a/build.zig b/build.zig index 223c225383..2ac98634ae 100644 --- a/build.zig +++ b/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), diff --git a/std/buf_map.zig b/std/buf_map.zig index e913b8765d..2a9bd77660 100644 --- a/std/buf_map.zig +++ b/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); diff --git a/std/build.zig b/std/build.zig index 532eca1cc9..63d635de70 100644 --- a/std/build.zig +++ b/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 {