Commit 3cbc244e98

Andrew Kelley <superjoe30@gmail.com>
2017-12-24 02:21:57
build: add --search-prefix option
1 parent 74a12d8
Changed files (3)
std/special/build_runner.zig
@@ -84,6 +84,12 @@ pub fn main() -> %void {
                     warn("Expected argument after --prefix\n\n");
                     return usageAndErr(&builder, false, %return stderr_stream);
                 });
+            } else if (mem.eql(u8, arg, "--search-prefix")) {
+                const search_prefix = %return unwrapArg(arg_it.next(allocator) ?? {
+                    warn("Expected argument after --search-prefix\n\n");
+                    return usageAndErr(&builder, false, %return stderr_stream);
+                });
+                builder.addSearchPrefix(search_prefix);
             } else if (mem.eql(u8, arg, "--verbose-tokenize")) {
                 builder.verbose_tokenize = true;
             } else if (mem.eql(u8, arg, "--verbose-ast")) {
@@ -145,6 +151,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
         \\  --help                 Print this help and exit
         \\  --verbose              Print commands before executing them
         \\  --prefix [path]        Override default install prefix
+        \\  --search-prefix [path] Add a path to look for binaries, libraries, headers
         \\
         \\Project-Specific Options:
         \\
std/build.zig
@@ -47,6 +47,7 @@ pub const Builder = struct {
     env_map: BufMap,
     top_level_steps: ArrayList(&TopLevelStep),
     prefix: []const u8,
+    search_prefixes: ArrayList([]const u8),
     lib_dir: []const u8,
     exe_dir: []const u8,
     installed_files: ArrayList([]const u8),
@@ -114,6 +115,7 @@ pub const Builder = struct {
             .default_step = undefined,
             .env_map = %%os.getEnvMap(allocator),
             .prefix = undefined,
+            .search_prefixes = ArrayList([]const u8).init(allocator),
             .lib_dir = undefined,
             .exe_dir = undefined,
             .installed_files = ArrayList([]const u8).init(allocator),
@@ -671,7 +673,22 @@ pub const Builder = struct {
     }
 
     pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) -> %[]const u8 {
+        // TODO report error for ambiguous situations
         const exe_extension = (Target { .Native = {}}).exeFileExt();
+        for (self.search_prefixes.toSliceConst()) |search_prefix| {
+            for (names) |name| {
+                if (os.path.isAbsolute(name)) {
+                    return name;
+                }
+                const full_path = %return os.path.join(self.allocator, search_prefix, "bin",
+                    self.fmt("{}{}", name, exe_extension));
+                if (os.path.real(self.allocator, full_path)) |real_path| {
+                    return real_path;
+                } else |_| {
+                    continue;
+                }
+            }
+        }
         if (self.env_map.get("PATH")) |PATH| {
             for (names) |name| {
                 if (os.path.isAbsolute(name)) {
@@ -727,6 +744,10 @@ pub const Builder = struct {
             },
         }
     }
+
+    pub fn addSearchPrefix(self: &Builder, search_prefix: []const u8) {
+        %%self.search_prefixes.append(search_prefix);
+    }
 };
 
 const Version = struct {
build.zig
@@ -80,9 +80,12 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {
     for (dep.libdirs.toSliceConst()) |lib_dir| {
         lib_exe_obj.addLibPath(lib_dir);
     }
-    for (dep.libs.toSliceConst()) |lib| {
+    for (dep.system_libs.toSliceConst()) |lib| {
         lib_exe_obj.linkSystemLibrary(lib);
     }
+    for (dep.libs.toSliceConst()) |lib| {
+        lib_exe_obj.addObjectFile(lib);
+    }
     for (dep.includes.toSliceConst()) |include_path| {
         lib_exe_obj.addIncludeDir(include_path);
     }
@@ -91,6 +94,7 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {
 const LibraryDep = struct {
     libdirs: ArrayList([]const u8),
     libs: ArrayList([]const u8),
+    system_libs: ArrayList([]const u8),
     includes: ArrayList([]const u8),
 };
 
@@ -98,11 +102,11 @@ fn findLLVM(b: &Builder) -> ?LibraryDep {
     const llvm_config_exe = b.findProgram(
         [][]const u8{"llvm-config-5.0", "llvm-config"},
         [][]const u8{
-            "/usr/local/opt/llvm@5/bin",
-            "/mingw64/bin",
+            "C:/Libraries/llvm-5.0.0/bin",
             "/c/msys64/mingw64/bin",
             "c:/msys64/mingw64/bin",
-            "C:/Libraries/llvm-5.0.0/bin",
+            "/usr/local/opt/llvm@5/bin",
+            "/mingw64/bin",
         }) %% |err|
     {
         warn("unable to find llvm-config: {}\n", err);
@@ -114,6 +118,7 @@ fn findLLVM(b: &Builder) -> ?LibraryDep {
 
     var result = LibraryDep {
         .libs = ArrayList([]const u8).init(b.allocator),
+        .system_libs = ArrayList([]const u8).init(b.allocator),
         .includes = ArrayList([]const u8).init(b.allocator),
         .libdirs = ArrayList([]const u8).init(b.allocator),
     };
@@ -121,7 +126,9 @@ fn findLLVM(b: &Builder) -> ?LibraryDep {
         var it = mem.split(libs_output, " \n");
         while (it.next()) |lib_arg| {
             if (mem.startsWith(u8, lib_arg, "-l")) {
-                %%result.libs.append(lib_arg[2..]);
+                %%result.system_libs.append(lib_arg[2..]);
+            } else {
+                %%result.libs.append(lib_arg);
             }
         }
     }