Skip to content

translate-c: Ensure extra_cflags are passed to clang #8664

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion src/Cache.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 1 addition & 17 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
12 changes: 8 additions & 4 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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) });
};

Expand Down Expand Up @@ -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);
Expand Down