Commit 21f5f06f1f
Changed files (2)
src/Compilation.zig
@@ -6608,14 +6608,43 @@ pub fn addTranslateCCArgs(
out_dep_path: ?[]const u8,
owner_mod: *Package.Module,
) !void {
+ const target = &owner_mod.resolved_target.result;
+
try argv.appendSlice(&.{ "-x", "c" });
- try comp.addCCArgs(arena, argv, ext, out_dep_path, owner_mod);
- // This gives us access to preprocessing entities, presumably at the cost of performance.
- try argv.appendSlice(&.{ "-Xclang", "-detailed-preprocessing-record" });
+
+ const resource_path = try comp.dirs.zig_lib.join(arena, &.{"compiler/aro/include"});
+ try argv.appendSlice(&.{ "-isystem", resource_path });
+
+ try comp.addCommonCCArgs(arena, argv, ext, out_dep_path, owner_mod);
+
+ try argv.appendSlice(&[_][]const u8{ "-target", try target.zigTriple(arena) });
+
+ const mcpu = mcpu: {
+ var buf: std.ArrayListUnmanaged(u8) = .empty;
+ defer buf.deinit(comp.gpa);
+
+ try buf.print(comp.gpa, "-mcpu={s}", .{target.cpu.model.name});
+
+ // TODO better serialization https://github.com/ziglang/zig/issues/4584
+ const all_features_list = target.cpu.arch.allFeaturesList();
+ try argv.ensureUnusedCapacity(all_features_list.len * 4);
+ for (all_features_list, 0..) |feature, index_usize| {
+ const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
+ const is_enabled = target.cpu.features.isEnabled(index);
+
+ const plus_or_minus = "-+"[@intFromBool(is_enabled)];
+ try buf.print(comp.gpa, "{c}{s}", .{ plus_or_minus, feature.name });
+ }
+ break :mcpu try buf.toOwnedSlice(arena);
+ };
+ try argv.append(mcpu);
+
+ try argv.appendSlice(comp.global_cc_argv);
+ try argv.appendSlice(owner_mod.cc_argv);
}
/// Add common C compiler args between translate-c and C object compilation.
-pub fn addCCArgs(
+fn addCommonCCArgs(
comp: *const Compilation,
arena: Allocator,
argv: *std.array_list.Managed([]const u8),
@@ -6625,32 +6654,13 @@ pub fn addCCArgs(
) !void {
const target = &mod.resolved_target.result;
- // As of Clang 16.x, it will by default read extra flags from /etc/clang.
- // I'm sure the person who implemented this means well, but they have a lot
- // to learn about abstractions and where the appropriate boundaries between
- // them are. The road to hell is paved with good intentions. Fortunately it
- // can be disabled.
- try argv.append("--no-default-config");
-
- // We don't ever put `-fcolor-diagnostics` or `-fno-color-diagnostics` because in passthrough mode
- // we want Clang to infer it, and in normal mode we always want it off, which will be true since
- // clang will detect stderr as a pipe rather than a terminal.
- if (!comp.clang_passthrough_mode and ext.clangSupportsDiagnostics()) {
- // Make stderr more easily parseable.
- try argv.append("-fno-caret-diagnostics");
- }
-
- // We never want clang to invoke the system assembler for anything. So we would want
- // this option always enabled. However, it only matters for some targets. To avoid
- // "unused parameter" warnings, and to keep CLI spam to a minimum, we only put this
- // flag on the command line if it is necessary.
- if (target_util.clangMightShellOutForAssembly(target)) {
- try argv.append("-integrated-as");
+ if (target_util.supports_fpic(target)) {
+ // PIE needs to go before PIC because Clang interprets `-fno-PIE` to imply `-fno-PIC`, which
+ // we don't necessarily want.
+ try argv.append(if (comp.config.pie) "-fPIE" else "-fno-PIE");
+ try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC");
}
- const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target);
- try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple });
-
switch (target.os.tag) {
.ios, .macos, .tvos, .watchos => |os| {
try argv.ensureUnusedCapacity(2);
@@ -6676,78 +6686,6 @@ pub fn addCCArgs(
else => {},
}
- const xclang_flag = switch (ext) {
- .assembly, .assembly_with_cpp => "-Xclangas",
- else => "-Xclang",
- };
-
- if (target_util.clangSupportsTargetCpuArg(target)) {
- if (target.cpu.model.llvm_name) |llvm_name| {
- try argv.appendSlice(&[_][]const u8{
- xclang_flag, "-target-cpu", xclang_flag, llvm_name,
- });
- }
- }
-
- // It would be really nice if there was a more compact way to communicate this info to Clang.
- const all_features_list = target.cpu.arch.allFeaturesList();
- try argv.ensureUnusedCapacity(all_features_list.len * 4);
- for (all_features_list, 0..) |feature, index_usize| {
- const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
- const is_enabled = target.cpu.features.isEnabled(index);
-
- if (feature.llvm_name) |llvm_name| {
- // We communicate float ABI to Clang through the dedicated options.
- if (std.mem.startsWith(u8, llvm_name, "soft-float") or
- std.mem.startsWith(u8, llvm_name, "hard-float"))
- continue;
-
- // Ignore these until we figure out how to handle the concept of omitting features.
- // See https://github.com/ziglang/zig/issues/23539
- if (target_util.isDynamicAMDGCNFeature(target, feature)) continue;
-
- argv.appendSliceAssumeCapacity(&[_][]const u8{ xclang_flag, "-target-feature", xclang_flag });
- const plus_or_minus = "-+"[@intFromBool(is_enabled)];
- const arg = try std.fmt.allocPrint(arena, "{c}{s}", .{ plus_or_minus, llvm_name });
- argv.appendAssumeCapacity(arg);
- }
- }
-
- if (target.cpu.arch.isThumb()) {
- try argv.append(switch (ext) {
- .assembly, .assembly_with_cpp => "-Wa,-mthumb",
- else => "-mthumb",
- });
- }
-
- if (target_util.llvmMachineAbi(target)) |mabi| {
- // Clang's integrated Arm assembler doesn't support `-mabi` yet...
- // Clang's FreeBSD driver doesn't support `-mabi` on PPC64 (ELFv2 is used anyway).
- if (!(target.cpu.arch.isArm() and (ext == .assembly or ext == .assembly_with_cpp)) and
- !(target.cpu.arch.isPowerPC64() and target.os.tag == .freebsd))
- {
- try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi}));
- }
- }
-
- // We might want to support -mfloat-abi=softfp for Arm and CSKY here in the future.
- if (target_util.clangSupportsFloatAbiArg(target)) {
- const fabi = @tagName(target.abi.float());
-
- try argv.append(switch (target.cpu.arch) {
- // For whatever reason, Clang doesn't support `-mfloat-abi` for s390x.
- .s390x => try std.fmt.allocPrint(arena, "-m{s}-float", .{fabi}),
- else => try std.fmt.allocPrint(arena, "-mfloat-abi={s}", .{fabi}),
- });
- }
-
- if (target_util.supports_fpic(target)) {
- // PIE needs to go before PIC because Clang interprets `-fno-PIE` to imply `-fno-PIC`, which
- // we don't necessarily want.
- try argv.append(if (comp.config.pie) "-fPIE" else "-fno-PIE");
- try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC");
- }
-
if (comp.mingw_unicode_entry_point) {
try argv.append("-municode");
}
@@ -6784,45 +6722,6 @@ pub fn addCCArgs(
if (ext != .assembly) {
try argv.append(if (target.os.tag == .freestanding) "-ffreestanding" else "-fhosted");
- if (target_util.clangSupportsNoImplicitFloatArg(target) and target.abi.float() == .soft) {
- try argv.append("-mno-implicit-float");
- }
-
- if (target_util.hasRedZone(target)) {
- try argv.append(if (mod.red_zone) "-mred-zone" else "-mno-red-zone");
- }
-
- try argv.append(if (mod.omit_frame_pointer) "-fomit-frame-pointer" else "-fno-omit-frame-pointer");
-
- const ssp_buf_size = mod.stack_protector;
- if (ssp_buf_size != 0) {
- try argv.appendSlice(&[_][]const u8{
- "-fstack-protector-strong",
- "--param",
- try std.fmt.allocPrint(arena, "ssp-buffer-size={d}", .{ssp_buf_size}),
- });
- } else {
- try argv.append("-fno-stack-protector");
- }
-
- try argv.append(if (mod.no_builtin) "-fno-builtin" else "-fbuiltin");
-
- try argv.append(if (comp.function_sections) "-ffunction-sections" else "-fno-function-sections");
- try argv.append(if (comp.data_sections) "-fdata-sections" else "-fno-data-sections");
-
- switch (mod.unwind_tables) {
- .none => {
- try argv.append("-fno-unwind-tables");
- try argv.append("-fno-asynchronous-unwind-tables");
- },
- .sync => {
- // Need to override Clang's convoluted default logic.
- try argv.append("-fno-asynchronous-unwind-tables");
- try argv.append("-funwind-tables");
- },
- .async => try argv.append("-fasynchronous-unwind-tables"),
- }
-
try argv.append("-nostdinc");
if (ext == .cpp or ext == .hpp) {
@@ -6961,80 +6860,6 @@ pub fn addCCArgs(
else => {},
}
- // Only assembly files support these flags.
- switch (ext) {
- .assembly,
- .assembly_with_cpp,
- => {
- // The Clang assembler does not accept the list of CPU features like the
- // compiler frontend does. Therefore we must hard-code the -m flags for
- // all CPU features here.
- switch (target.cpu.arch) {
- .riscv32, .riscv32be, .riscv64, .riscv64be => {
- const RvArchFeat = struct { char: u8, feat: std.Target.riscv.Feature };
- const letters = [_]RvArchFeat{
- .{ .char = 'm', .feat = .m },
- .{ .char = 'a', .feat = .a },
- .{ .char = 'f', .feat = .f },
- .{ .char = 'd', .feat = .d },
- .{ .char = 'c', .feat = .c },
- };
- const prefix: []const u8 = if (target.cpu.arch == .riscv64) "rv64" else "rv32";
- const prefix_len = 4;
- assert(prefix.len == prefix_len);
- var march_buf: [prefix_len + letters.len + 1]u8 = undefined;
- var march_index: usize = prefix_len;
- @memcpy(march_buf[0..prefix.len], prefix);
-
- if (target.cpu.has(.riscv, .e)) {
- march_buf[march_index] = 'e';
- } else {
- march_buf[march_index] = 'i';
- }
- march_index += 1;
-
- for (letters) |letter| {
- if (target.cpu.has(.riscv, letter.feat)) {
- march_buf[march_index] = letter.char;
- march_index += 1;
- }
- }
-
- const march_arg = try std.fmt.allocPrint(arena, "-march={s}", .{
- march_buf[0..march_index],
- });
- try argv.append(march_arg);
-
- if (target.cpu.has(.riscv, .relax)) {
- try argv.append("-mrelax");
- } else {
- try argv.append("-mno-relax");
- }
- if (target.cpu.has(.riscv, .save_restore)) {
- try argv.append("-msave-restore");
- } else {
- try argv.append("-mno-save-restore");
- }
- },
- .mips, .mipsel, .mips64, .mips64el => {
- if (target.cpu.model.llvm_name) |llvm_name| {
- try argv.append(try std.fmt.allocPrint(arena, "-march={s}", .{llvm_name}));
- }
- },
- else => {
- // TODO
- },
- }
-
- if (target_util.clangAssemblerSupportsMcpuArg(target)) {
- if (target.cpu.model.llvm_name) |llvm_name| {
- try argv.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{llvm_name}));
- }
- }
- },
- else => {},
- }
-
// Only compiled files support these flags.
switch (ext) {
.c,
@@ -7133,6 +6958,243 @@ pub fn addCCArgs(
},
else => {},
}
+}
+
+/// Add common C compiler args and Clang specific args.
+pub fn addCCArgs(
+ comp: *const Compilation,
+ arena: Allocator,
+ argv: *std.ArrayList([]const u8),
+ ext: FileExt,
+ out_dep_path: ?[]const u8,
+ mod: *Package.Module,
+) !void {
+ const target = &mod.resolved_target.result;
+
+ // As of Clang 16.x, it will by default read extra flags from /etc/clang.
+ // I'm sure the person who implemented this means well, but they have a lot
+ // to learn about abstractions and where the appropriate boundaries between
+ // them are. The road to hell is paved with good intentions. Fortunately it
+ // can be disabled.
+ try argv.append("--no-default-config");
+
+ // We don't ever put `-fcolor-diagnostics` or `-fno-color-diagnostics` because in passthrough mode
+ // we want Clang to infer it, and in normal mode we always want it off, which will be true since
+ // clang will detect stderr as a pipe rather than a terminal.
+ if (!comp.clang_passthrough_mode and ext.clangSupportsDiagnostics()) {
+ // Make stderr more easily parseable.
+ try argv.append("-fno-caret-diagnostics");
+ }
+
+ // We never want clang to invoke the system assembler for anything. So we would want
+ // this option always enabled. However, it only matters for some targets. To avoid
+ // "unused parameter" warnings, and to keep CLI spam to a minimum, we only put this
+ // flag on the command line if it is necessary.
+ if (target_util.clangMightShellOutForAssembly(target)) {
+ try argv.append("-integrated-as");
+ }
+
+ const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target);
+ try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple });
+
+ if (target.cpu.arch.isThumb()) {
+ try argv.append(switch (ext) {
+ .assembly, .assembly_with_cpp => "-Wa,-mthumb",
+ else => "-mthumb",
+ });
+ }
+
+ if (target_util.llvmMachineAbi(target)) |mabi| {
+ // Clang's integrated Arm assembler doesn't support `-mabi` yet...
+ // Clang's FreeBSD driver doesn't support `-mabi` on PPC64 (ELFv2 is used anyway).
+ if (!(target.cpu.arch.isArm() and (ext == .assembly or ext == .assembly_with_cpp)) and
+ !(target.cpu.arch.isPowerPC64() and target.os.tag == .freebsd))
+ {
+ try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi}));
+ }
+ }
+
+ // We might want to support -mfloat-abi=softfp for Arm and CSKY here in the future.
+ if (target_util.clangSupportsFloatAbiArg(target)) {
+ const fabi = @tagName(target.abi.float());
+
+ try argv.append(switch (target.cpu.arch) {
+ // For whatever reason, Clang doesn't support `-mfloat-abi` for s390x.
+ .s390x => try std.fmt.allocPrint(arena, "-m{s}-float", .{fabi}),
+ else => try std.fmt.allocPrint(arena, "-mfloat-abi={s}", .{fabi}),
+ });
+ }
+
+ try comp.addCommonCCArgs(arena, argv, ext, out_dep_path, mod);
+
+ // Only assembly files support these flags.
+ switch (ext) {
+ .assembly,
+ .assembly_with_cpp,
+ => {
+ // The Clang assembler does not accept the list of CPU features like the
+ // compiler frontend does. Therefore we must hard-code the -m flags for
+ // all CPU features here.
+ switch (target.cpu.arch) {
+ .riscv32, .riscv32be, .riscv64, .riscv64be => {
+ const RvArchFeat = struct { char: u8, feat: std.Target.riscv.Feature };
+ const letters = [_]RvArchFeat{
+ .{ .char = 'm', .feat = .m },
+ .{ .char = 'a', .feat = .a },
+ .{ .char = 'f', .feat = .f },
+ .{ .char = 'd', .feat = .d },
+ .{ .char = 'c', .feat = .c },
+ };
+ const prefix: []const u8 = if (target.cpu.arch == .riscv64) "rv64" else "rv32";
+ const prefix_len = 4;
+ assert(prefix.len == prefix_len);
+ var march_buf: [prefix_len + letters.len + 1]u8 = undefined;
+ var march_index: usize = prefix_len;
+ @memcpy(march_buf[0..prefix.len], prefix);
+
+ if (target.cpu.has(.riscv, .e)) {
+ march_buf[march_index] = 'e';
+ } else {
+ march_buf[march_index] = 'i';
+ }
+ march_index += 1;
+
+ for (letters) |letter| {
+ if (target.cpu.has(.riscv, letter.feat)) {
+ march_buf[march_index] = letter.char;
+ march_index += 1;
+ }
+ }
+
+ const march_arg = try std.fmt.allocPrint(arena, "-march={s}", .{
+ march_buf[0..march_index],
+ });
+ try argv.append(march_arg);
+
+ if (target.cpu.has(.riscv, .relax)) {
+ try argv.append("-mrelax");
+ } else {
+ try argv.append("-mno-relax");
+ }
+ if (target.cpu.has(.riscv, .save_restore)) {
+ try argv.append("-msave-restore");
+ } else {
+ try argv.append("-mno-save-restore");
+ }
+ },
+ .mips, .mipsel, .mips64, .mips64el => {
+ if (target.cpu.model.llvm_name) |llvm_name| {
+ try argv.append(try std.fmt.allocPrint(arena, "-march={s}", .{llvm_name}));
+ }
+ },
+ else => {
+ // TODO
+ },
+ }
+
+ if (target_util.clangAssemblerSupportsMcpuArg(target)) {
+ if (target.cpu.model.llvm_name) |llvm_name| {
+ try argv.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{llvm_name}));
+ }
+ }
+ },
+ else => {},
+ }
+
+ // Non-preprocessed assembly files don't support these flags.
+ if (ext != .assembly) {
+ if (target_util.clangSupportsNoImplicitFloatArg(target) and target.abi.float() == .soft) {
+ try argv.append("-mno-implicit-float");
+ }
+
+ if (target_util.hasRedZone(target)) {
+ try argv.append(if (mod.red_zone) "-mred-zone" else "-mno-red-zone");
+ }
+
+ try argv.append(if (mod.omit_frame_pointer) "-fomit-frame-pointer" else "-fno-omit-frame-pointer");
+
+ const ssp_buf_size = mod.stack_protector;
+ if (ssp_buf_size != 0) {
+ try argv.appendSlice(&[_][]const u8{
+ "-fstack-protector-strong",
+ "--param",
+ try std.fmt.allocPrint(arena, "ssp-buffer-size={d}", .{ssp_buf_size}),
+ });
+ } else {
+ try argv.append("-fno-stack-protector");
+ }
+
+ try argv.append(if (mod.no_builtin) "-fno-builtin" else "-fbuiltin");
+
+ try argv.append(if (comp.function_sections) "-ffunction-sections" else "-fno-function-sections");
+ try argv.append(if (comp.data_sections) "-fdata-sections" else "-fno-data-sections");
+
+ switch (mod.unwind_tables) {
+ .none => {
+ try argv.append("-fno-unwind-tables");
+ try argv.append("-fno-asynchronous-unwind-tables");
+ },
+ .sync => {
+ // Need to override Clang's convoluted default logic.
+ try argv.append("-fno-asynchronous-unwind-tables");
+ try argv.append("-funwind-tables");
+ },
+ .async => try argv.append("-fasynchronous-unwind-tables"),
+ }
+ }
+
+ // Only compiled files support these flags.
+ switch (ext) {
+ .c,
+ .h,
+ .cpp,
+ .hpp,
+ .m,
+ .hm,
+ .mm,
+ .hmm,
+ .ll,
+ .bc,
+ => {
+ const xclang_flag = switch (ext) {
+ .assembly, .assembly_with_cpp => "-Xclangas",
+ else => "-Xclang",
+ };
+
+ if (target_util.clangSupportsTargetCpuArg(target)) {
+ if (target.cpu.model.llvm_name) |llvm_name| {
+ try argv.appendSlice(&[_][]const u8{
+ xclang_flag, "-target-cpu", xclang_flag, llvm_name,
+ });
+ }
+ }
+
+ // It would be really nice if there was a more compact way to communicate this info to Clang.
+ const all_features_list = target.cpu.arch.allFeaturesList();
+ try argv.ensureUnusedCapacity(all_features_list.len * 4);
+ for (all_features_list, 0..) |feature, index_usize| {
+ const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
+ const is_enabled = target.cpu.features.isEnabled(index);
+
+ if (feature.llvm_name) |llvm_name| {
+ // We communicate float ABI to Clang through the dedicated options.
+ if (std.mem.startsWith(u8, llvm_name, "soft-float") or
+ std.mem.startsWith(u8, llvm_name, "hard-float"))
+ continue;
+
+ // Ignore these until we figure out how to handle the concept of omitting features.
+ // See https://github.com/ziglang/zig/issues/23539
+ if (target_util.isDynamicAMDGCNFeature(target, feature)) continue;
+
+ argv.appendSliceAssumeCapacity(&[_][]const u8{ xclang_flag, "-target-feature", xclang_flag });
+ const plus_or_minus = "-+"[@intFromBool(is_enabled)];
+ const arg = try std.fmt.allocPrint(arena, "{c}{s}", .{ plus_or_minus, llvm_name });
+ argv.appendAssumeCapacity(arg);
+ }
+ }
+ },
+ else => {},
+ }
try argv.appendSlice(comp.global_cc_argv);
try argv.appendSlice(mod.cc_argv);
src/main.zig
@@ -4555,7 +4555,6 @@ fn cmdTranslateC(
};
var argv = std.ArrayList([]const u8).init(arena);
- try argv.append("arocc");
try comp.addTranslateCCArgs(arena, &argv, ext, out_dep_path, comp.root_mod);
try argv.append(c_source_file.src_path);
if (comp.verbose_cc) Compilation.dump_argv(argv.items);