From 0e9eed4eadee2fca58696f47c99ede9c34709665 Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Fri, 30 Apr 2021 23:07:40 -0700 Subject: [PATCH] translate-c: Ensure extra_cflags are passed to clang Additionally ensure that the Zig cache incorporates any extra cflags when using translate-c. Fixes the issue identified in #8662 --- src/Cache.zig | 21 ++++++++++++++++++++- src/Compilation.zig | 18 +----------------- src/main.zig | 12 ++++++++---- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/Cache.zig b/src/Cache.zig index f2fdafff9b36..42acaf376096 100644 --- a/src/Cache.zig +++ b/src/Cache.zig @@ -11,6 +11,7 @@ const testing = std.testing; const mem = std.mem; const fmt = std.fmt; const Allocator = std.mem.Allocator; +const Compilation = @import("Compilation.zig"); /// Be sure to call `Manifest.deinit` after successful initialization. pub fn obtain(cache: *const Cache) Manifest { @@ -61,7 +62,7 @@ pub const File = struct { pub const HashHelper = struct { hasher: Hasher = hasher_init, - const EmitLoc = @import("Compilation.zig").EmitLoc; + const EmitLoc = Compilation.EmitLoc; /// Record a slice of bytes as an dependency of the process being cached pub fn addBytes(hh: *HashHelper, bytes: []const u8) void { @@ -220,6 +221,24 @@ pub const Manifest = struct { return idx; } + pub fn hashCSource(self: *Manifest, c_source: Compilation.CSourceFile) !void { + _ = try self.addFile(c_source.src_path, null); + // Hash the extra flags, with special care to call addFile for file parameters. + // TODO this logic can likely be improved by utilizing clang_options_data.zig. + const file_args = [_][]const u8{"-include"}; + var arg_i: usize = 0; + while (arg_i < c_source.extra_flags.len) : (arg_i += 1) { + const arg = c_source.extra_flags[arg_i]; + self.hash.addBytes(arg); + for (file_args) |file_arg| { + if (mem.eql(u8, file_arg, arg) and arg_i + 1 < c_source.extra_flags.len) { + arg_i += 1; + _ = try self.addFile(c_source.extra_flags[arg_i], null); + } + } + } + } + pub fn addOptionalFile(self: *Manifest, optional_file_path: ?[]const u8) !void { self.hash.add(optional_file_path != null); const file_path = optional_file_path orelse return; diff --git a/src/Compilation.zig b/src/Compilation.zig index 7ff7ef137453..3b43408acc29 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2261,23 +2261,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: * man.hash.add(comp.clang_preprocessor_mode); - _ = try man.addFile(c_object.src.src_path, null); - { - // Hash the extra flags, with special care to call addFile for file parameters. - // TODO this logic can likely be improved by utilizing clang_options_data.zig. - const file_args = [_][]const u8{"-include"}; - var arg_i: usize = 0; - while (arg_i < c_object.src.extra_flags.len) : (arg_i += 1) { - const arg = c_object.src.extra_flags[arg_i]; - man.hash.addBytes(arg); - for (file_args) |file_arg| { - if (mem.eql(u8, file_arg, arg) and arg_i + 1 < c_object.src.extra_flags.len) { - arg_i += 1; - _ = try man.addFile(c_object.src.extra_flags[arg_i], null); - } - } - } - } + try man.hashCSource(c_object.src); { const is_collision = blk: { diff --git a/src/main.zig b/src/main.zig index a0a11bbbbcb4..6de98c3a3581 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2172,7 +2172,7 @@ fn cmdTranslateC(comp: *Compilation, arena: *Allocator, enable_cache: bool) !voi defer if (enable_cache) man.deinit(); man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects - _ = man.addFile(c_source_file.src_path, null) catch |err| { + man.hashCSource(c_source_file) catch |err| { fatal("unable to process '{s}': {s}", .{ c_source_file.src_path, @errorName(err) }); }; @@ -2202,12 +2202,16 @@ fn cmdTranslateC(comp: *Compilation, arena: *Allocator, enable_cache: bool) !voi } // Convert to null terminated args. - const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1); - new_argv_with_sentinel[argv.items.len] = null; - const new_argv = new_argv_with_sentinel[0..argv.items.len :null]; + const clang_args_len = argv.items.len + c_source_file.extra_flags.len; + const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, clang_args_len + 1); + new_argv_with_sentinel[clang_args_len] = null; + const new_argv = new_argv_with_sentinel[0..clang_args_len :null]; for (argv.items) |arg, i| { new_argv[i] = try arena.dupeZ(u8, arg); } + for (c_source_file.extra_flags) |arg, i| { + new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg); + } const c_headers_dir_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"include"}); const c_headers_dir_path_z = try arena.dupeZ(u8, c_headers_dir_path);