diff options
| author | Cody Tapscott <topolarity@tapscott.me> | 2022-07-15 17:25:38 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-07-29 11:38:58 -0700 |
| commit | 4fc2acdaa4f2b649b17ddf958d2608abc4787a4e (patch) | |
| tree | 4a76dfdd61ae7f39bd53fd6fb8cacd63a92c203d | |
| parent | b3d0694fc53e2fc7c7c412d68e2f82315070ddfd (diff) | |
| download | zig-4fc2acdaa4f2b649b17ddf958d2608abc4787a4e.tar.gz zig-4fc2acdaa4f2b649b17ddf958d2608abc4787a4e.zip | |
build.zig: Emit warning if "config.h" cannot be found
We now warn the user if config.h could not be located.
This also updates the search to stop early upon encountering a
`.git` directory, so that we avoid recursing outside of the zig
source if possible.
| -rw-r--r-- | build.zig | 80 |
1 files changed, 55 insertions, 25 deletions
@@ -238,7 +238,15 @@ pub fn build(b: *Builder) !void { exe_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version)); if (enable_llvm) { - const cmake_cfg = if (static_llvm) null else findAndParseConfigH(b, config_h_path_option); + const cmake_cfg = if (static_llvm) null else blk: { + if (findConfigH(b, config_h_path_option)) |config_h_path| { + const file_contents = fs.cwd().readFileAlloc(b.allocator, config_h_path, max_config_h_bytes) catch unreachable; + break :blk parseConfigH(b, file_contents); + } else { + std.log.warn("config.h could not be located automatically. Consider providing it explicitly via \"-Dconfig_h\"", .{}); + break :blk null; + } + }; if (is_stage1) { const softfloat = b.addStaticLibrary("softfloat", null); @@ -689,31 +697,53 @@ const CMakeConfig = struct { const max_config_h_bytes = 1 * 1024 * 1024; -fn findAndParseConfigH(b: *Builder, config_h_path_option: ?[]const u8) ?CMakeConfig { - const config_h_text: []const u8 = if (config_h_path_option) |config_h_path| blk: { - break :blk fs.cwd().readFileAlloc(b.allocator, config_h_path, max_config_h_bytes) catch unreachable; - } else blk: { - // TODO this should stop looking for config.h once it detects we hit the - // zig source root directory. - var check_dir = fs.path.dirname(b.zig_exe).?; - while (true) { - var dir = fs.cwd().openDir(check_dir, .{}) catch unreachable; - defer dir.close(); - - break :blk dir.readFileAlloc(b.allocator, "config.h", max_config_h_bytes) catch |err| switch (err) { - error.FileNotFound => { - const new_check_dir = fs.path.dirname(check_dir); - if (new_check_dir == null or mem.eql(u8, new_check_dir.?, check_dir)) { - return null; - } - check_dir = new_check_dir.?; - continue; - }, - else => unreachable, - }; - } else unreachable; // TODO should not need `else unreachable`. - }; +fn findConfigH(b: *Builder, config_h_path_option: ?[]const u8) ?[]const u8 { + if (config_h_path_option) |path| { + var config_h_or_err = fs.cwd().openFile(path, .{}); + if (config_h_or_err) |*file| { + file.close(); + return path; + } else |_| { + std.log.err("Could not open provided config.h: \"{s}\"", .{path}); + std.os.exit(1); + } + } + + var check_dir = fs.path.dirname(b.zig_exe).?; + while (true) { + var dir = fs.cwd().openDir(check_dir, .{}) catch unreachable; + defer dir.close(); + + // Check if config.h is present in dir + var config_h_or_err = dir.openFile("config.h", .{}); + if (config_h_or_err) |*file| { + file.close(); + return fs.path.join( + b.allocator, + &[_][]const u8{ check_dir, "config.h" }, + ) catch unreachable; + } else |e| switch (e) { + error.FileNotFound => {}, + else => unreachable, + } + + // Check if we reached the source root by looking for .git, and bail if so + var git_dir_or_err = dir.openDir(".git", .{}); + if (git_dir_or_err) |*git_dir| { + git_dir.close(); + return null; + } else |_| {} + + // Otherwise, continue search in the parent directory + const new_check_dir = fs.path.dirname(check_dir); + if (new_check_dir == null or mem.eql(u8, new_check_dir.?, check_dir)) { + return null; + } + check_dir = new_check_dir.?; + } else unreachable; // TODO should not need `else unreachable`. +} +fn parseConfigH(b: *Builder, config_h_text: []const u8) ?CMakeConfig { var ctx: CMakeConfig = .{ .llvm_linkage = undefined, .cmake_binary_dir = undefined, |
