authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-07-15 17:25:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-29 11:38:58-07:00
log4fc2acdaa4f2b649b17ddf958d2608abc4787a4e
tree4a76dfdd61ae7f39bd53fd6fb8cacd63a92c203d
parentb3d0694fc53e2fc7c7c412d68e2f82315070ddfd

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.

1 files changed, 55 insertions(+), 25 deletions(-)

build.zig+55-25
...@@ -238,7 +238,15 @@ pub fn build(b: *Builder) !void {...@@ -238,7 +238,15 @@ pub fn build(b: *Builder) !void {
238 exe_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));238 exe_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
239239
240 if (enable_llvm) {240 if (enable_llvm) {
241 const cmake_cfg = if (static_llvm) null else findAndParseConfigH(b, config_h_path_option);241 const cmake_cfg = if (static_llvm) null else blk: {
242 if (findConfigH(b, config_h_path_option)) |config_h_path| {
243 const file_contents = fs.cwd().readFileAlloc(b.allocator, config_h_path, max_config_h_bytes) catch unreachable;
244 break :blk parseConfigH(b, file_contents);
245 } else {
246 std.log.warn("config.h could not be located automatically. Consider providing it explicitly via \"-Dconfig_h\"", .{});
247 break :blk null;
248 }
249 };
242250
243 if (is_stage1) {251 if (is_stage1) {
244 const softfloat = b.addStaticLibrary("softfloat", null);252 const softfloat = b.addStaticLibrary("softfloat", null);
...@@ -689,31 +697,53 @@ const CMakeConfig = struct {...@@ -689,31 +697,53 @@ const CMakeConfig = struct {
689697
690const max_config_h_bytes = 1 * 1024 * 1024;698const max_config_h_bytes = 1 * 1024 * 1024;
691699
692fn findAndParseConfigH(b: *Builder, config_h_path_option: ?[]const u8) ?CMakeConfig {700fn findConfigH(b: *Builder, config_h_path_option: ?[]const u8) ?[]const u8 {
693 const config_h_text: []const u8 = if (config_h_path_option) |config_h_path| blk: {701 if (config_h_path_option) |path| {
694 break :blk fs.cwd().readFileAlloc(b.allocator, config_h_path, max_config_h_bytes) catch unreachable;702 var config_h_or_err = fs.cwd().openFile(path, .{});
695 } else blk: {703 if (config_h_or_err) |*file| {
696 // TODO this should stop looking for config.h once it detects we hit the704 file.close();
697 // zig source root directory.705 return path;
698 var check_dir = fs.path.dirname(b.zig_exe).?;706 } else |_| {
699 while (true) {707 std.log.err("Could not open provided config.h: \"{s}\"", .{path});
700 var dir = fs.cwd().openDir(check_dir, .{}) catch unreachable;708 std.os.exit(1);
701 defer dir.close();709 }
702710 }
703 break :blk dir.readFileAlloc(b.allocator, "config.h", max_config_h_bytes) catch |err| switch (err) {711
704 error.FileNotFound => {712 var check_dir = fs.path.dirname(b.zig_exe).?;
705 const new_check_dir = fs.path.dirname(check_dir);713 while (true) {
706 if (new_check_dir == null or mem.eql(u8, new_check_dir.?, check_dir)) {714 var dir = fs.cwd().openDir(check_dir, .{}) catch unreachable;
707 return null;715 defer dir.close();
708 }716
709 check_dir = new_check_dir.?;717 // Check if config.h is present in dir
710 continue;718 var config_h_or_err = dir.openFile("config.h", .{});
711 },719 if (config_h_or_err) |*file| {
712 else => unreachable,720 file.close();
713 };721 return fs.path.join(
714 } else unreachable; // TODO should not need `else unreachable`.722 b.allocator,
715 };723 &[_][]const u8{ check_dir, "config.h" },
724 ) catch unreachable;
725 } else |e| switch (e) {
726 error.FileNotFound => {},
727 else => unreachable,
728 }
729
730 // Check if we reached the source root by looking for .git, and bail if so
731 var git_dir_or_err = dir.openDir(".git", .{});
732 if (git_dir_or_err) |*git_dir| {
733 git_dir.close();
734 return null;
735 } else |_| {}
736
737 // Otherwise, continue search in the parent directory
738 const new_check_dir = fs.path.dirname(check_dir);
739 if (new_check_dir == null or mem.eql(u8, new_check_dir.?, check_dir)) {
740 return null;
741 }
742 check_dir = new_check_dir.?;
743 } else unreachable; // TODO should not need `else unreachable`.
744}
716745
746fn parseConfigH(b: *Builder, config_h_text: []const u8) ?CMakeConfig {
717 var ctx: CMakeConfig = .{747 var ctx: CMakeConfig = .{
718 .llvm_linkage = undefined,748 .llvm_linkage = undefined,
719 .cmake_binary_dir = undefined,749 .cmake_binary_dir = undefined,