authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-05-25 12:30:02+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-10-01 23:51:54+03:00
logfef94da958c92e59ad277b6934a337b6fb45396c
treed377dbc41267d7c9d24727238747c32ef3766e54
parentaf40bce08adf232c9f6b9016810a24f7d0260399

add compiler flag for selecting C frontend


2 files changed, 94 insertions(+), 74 deletions(-)

src/Compilation.zig+50-39
...@@ -32,7 +32,6 @@ const Module = @import("Module.zig");...@@ -32,7 +32,6 @@ const Module = @import("Module.zig");
32const InternPool = @import("InternPool.zig");32const InternPool = @import("InternPool.zig");
33const BuildId = std.Build.CompileStep.BuildId;33const BuildId = std.Build.CompileStep.BuildId;
34const Cache = std.Build.Cache;34const Cache = std.Build.Cache;
35const translate_c = @import("translate_c.zig");
36const c_codegen = @import("codegen/c.zig");35const c_codegen = @import("codegen/c.zig");
37const libtsan = @import("libtsan.zig");36const libtsan = @import("libtsan.zig");
38const Zir = @import("Zir.zig");37const Zir = @import("Zir.zig");
...@@ -88,7 +87,7 @@ failed_win32_resources: if (build_options.only_core_functionality) void else std...@@ -88,7 +87,7 @@ failed_win32_resources: if (build_options.only_core_functionality) void else std
88misc_failures: std.AutoArrayHashMapUnmanaged(MiscTask, MiscError) = .{},87misc_failures: std.AutoArrayHashMapUnmanaged(MiscTask, MiscError) = .{},
8988
90keep_source_files_loaded: bool,89keep_source_files_loaded: bool,
91use_clang: bool,90c_frontend: CFrontend,
92sanitize_c: bool,91sanitize_c: bool,
93/// When this is `true` it means invoking clang as a sub-process is expected to inherit92/// When this is `true` it means invoking clang as a sub-process is expected to inherit
94/// stdin, stdout, stderr, and if it returns non success, to forward the exit code.93/// stdin, stdout, stderr, and if it returns non success, to forward the exit code.
...@@ -515,6 +514,8 @@ pub const cache_helpers = struct {...@@ -515,6 +514,8 @@ pub const cache_helpers = struct {
515 }514 }
516};515};
517516
517pub const CFrontend = enum { clang, aro };
518
518pub const ClangPreprocessorMode = enum {519pub const ClangPreprocessorMode = enum {
519 no,520 no,
520 /// This means we are doing `zig cc -E -o <path>`.521 /// This means we are doing `zig cc -E -o <path>`.
...@@ -1046,14 +1047,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1046,14 +1047,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1046 break :pic explicit;1047 break :pic explicit;
1047 } else pie or must_pic;1048 } else pie or must_pic;
10481049
1049 // Make a decision on whether to use Clang for translate-c and compiling C files.1050 // Make a decision on whether to use Clang or Aro for translate-c and compiling C files.
1050 const use_clang = if (options.use_clang) |explicit| explicit else blk: {1051 const c_frontend: CFrontend = blk: {
1051 if (build_options.have_llvm) {1052 if (!build_options.have_llvm) break :blk .aro;
1052 // Can't use it if we don't have it!1053 if (options.use_clang) |explicit| if (explicit) break :blk .clang;
1053 break :blk false;1054 break :blk .clang;
1054 }
1055 // It's not planned to do our own translate-c or C compilation.
1056 break :blk true;
1057 };1055 };
10581056
1059 const is_safe_mode = switch (options.optimize_mode) {1057 const is_safe_mode = switch (options.optimize_mode) {
...@@ -1677,7 +1675,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1677,7 +1675,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1677 .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa),1675 .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa),
1678 .embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa),1676 .embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa),
1679 .keep_source_files_loaded = options.keep_source_files_loaded,1677 .keep_source_files_loaded = options.keep_source_files_loaded,
1680 .use_clang = use_clang,1678 .c_frontend = c_frontend,
1681 .clang_argv = options.clang_argv,1679 .clang_argv = options.clang_argv,
1682 .c_source_files = options.c_source_files,1680 .c_source_files = options.c_source_files,
1683 .rc_source_files = options.rc_source_files,1681 .rc_source_files = options.rc_source_files,
...@@ -3918,9 +3916,7 @@ pub const CImportResult = struct {...@@ -3918,9 +3916,7 @@ pub const CImportResult = struct {
3918/// This API is currently coupled pretty tightly to stage1's needs; it will need to be reworked3916/// This API is currently coupled pretty tightly to stage1's needs; it will need to be reworked
3919/// a bit when we want to start using it from self-hosted.3917/// a bit when we want to start using it from self-hosted.
3920pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {3918pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
3921 if (!build_options.have_llvm)3919 if (build_options.only_c) unreachable; // @cImport is not needed for bootstrapping
3922 return error.ZigCompilerNotBuiltWithLLVMExtensions;
3923
3924 const tracy_trace = trace(@src());3920 const tracy_trace = trace(@src());
3925 defer tracy_trace.end();3921 defer tracy_trace.end();
39263922
...@@ -3967,7 +3963,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {...@@ -3967,7 +3963,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
3967 var argv = std.ArrayList([]const u8).init(comp.gpa);3963 var argv = std.ArrayList([]const u8).init(comp.gpa);
3968 defer argv.deinit();3964 defer argv.deinit();
39693965
3970 try argv.append(""); // argv[0] is program name, actual args start at [1]3966 try argv.append(@tagName(comp.c_frontend)); // argv[0] is program name, actual args start at [1]
3971 try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path);3967 try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path);
39723968
3973 try argv.append(out_h_path);3969 try argv.append(out_h_path);
...@@ -3975,31 +3971,43 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {...@@ -3975,31 +3971,43 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
3975 if (comp.verbose_cc) {3971 if (comp.verbose_cc) {
3976 dump_argv(argv.items);3972 dump_argv(argv.items);
3977 }3973 }
3974 var tree = switch (comp.c_frontend) {
3975 .aro => tree: {
3976 if (builtin.zig_backend == .stage2_c) @panic("the CBE cannot compile Aro yet!");
3977 const translate_c = @import("aro_translate_c.zig");
3978 _ = translate_c;
3979 break :tree undefined;
3980 },
3981 .clang => tree: {
3982 if (!build_options.have_llvm) unreachable;
3983 const translate_c = @import("translate_c.zig");
3984
3985 // Convert to null terminated args.
3986 const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1);
3987 new_argv_with_sentinel[argv.items.len] = null;
3988 const new_argv = new_argv_with_sentinel[0..argv.items.len :null];
3989 for (argv.items, 0..) |arg, i| {
3990 new_argv[i] = try arena.dupeZ(u8, arg);
3991 }
39783992
3979 // Convert to null terminated args.3993 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
3980 const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1);3994 var errors = std.zig.ErrorBundle.empty;
3981 new_argv_with_sentinel[argv.items.len] = null;3995 errdefer errors.deinit(comp.gpa);
3982 const new_argv = new_argv_with_sentinel[0..argv.items.len :null];3996 break :tree translate_c.translate(
3983 for (argv.items, 0..) |arg, i| {3997 comp.gpa,
3984 new_argv[i] = try arena.dupeZ(u8, arg);3998 new_argv.ptr,
3985 }3999 new_argv.ptr + new_argv.len,
39864000 &errors,
3987 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});4001 c_headers_dir_path_z,
3988 var errors = std.zig.ErrorBundle.empty;4002 ) catch |err| switch (err) {
3989 errdefer errors.deinit(comp.gpa);4003 error.OutOfMemory => return error.OutOfMemory,
3990 var tree = translate_c.translate(4004 error.SemanticAnalyzeFail => {
3991 comp.gpa,4005 return CImportResult{
3992 new_argv.ptr,4006 .out_zig_path = "",
3993 new_argv.ptr + new_argv.len,4007 .cache_hit = actual_hit,
3994 &errors,4008 .errors = errors,
3995 c_headers_dir_path_z,4009 };
3996 ) catch |err| switch (err) {4010 },
3997 error.OutOfMemory => return error.OutOfMemory,
3998 error.SemanticAnalyzeFail => {
3999 return CImportResult{
4000 .out_zig_path = "",
4001 .cache_hit = actual_hit,
4002 .errors = errors,
4003 };4011 };
4004 },4012 },
4005 };4013 };
...@@ -4249,6 +4257,9 @@ fn reportRetryableEmbedFileError(...@@ -4249,6 +4257,9 @@ fn reportRetryableEmbedFileError(
4249}4257}
42504258
4251fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.Progress.Node) !void {4259fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.Progress.Node) !void {
4260 if (comp.c_frontend == .aro) {
4261 return comp.failCObj(c_object, "aro does not support compiling C objects yet", .{});
4262 }
4252 if (!build_options.have_llvm) {4263 if (!build_options.have_llvm) {
4253 return comp.failCObj(c_object, "clang not available: compiler built without LLVM extensions", .{});4264 return comp.failCObj(c_object, "clang not available: compiler built without LLVM extensions", .{});
4254 }4265 }
src/main.zig+44-35
...@@ -20,7 +20,6 @@ const build_options = @import("build_options");...@@ -20,7 +20,6 @@ const build_options = @import("build_options");
20const introspect = @import("introspect.zig");20const introspect = @import("introspect.zig");
21const LibCInstallation = @import("libc_installation.zig").LibCInstallation;21const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
22const wasi_libc = @import("wasi_libc.zig");22const wasi_libc = @import("wasi_libc.zig");
23const translate_c = @import("translate_c.zig");
24const BuildId = std.Build.CompileStep.BuildId;23const BuildId = std.Build.CompileStep.BuildId;
25const Cache = std.Build.Cache;24const Cache = std.Build.Cache;
26const target_util = @import("target.zig");25const target_util = @import("target.zig");
...@@ -4204,9 +4203,7 @@ fn updateModule(comp: *Compilation) !void {...@@ -4204,9 +4203,7 @@ fn updateModule(comp: *Compilation) !void {
4204}4203}
42054204
4206fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilation.CImportResult) !void {4205fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilation.CImportResult) !void {
4207 if (!build_options.have_llvm)4206 if (build_options.only_c) unreachable; // translate-c is not needed for bootstrapping
4208 fatal("cannot translate-c: compiler built without LLVM extensions", .{});
4209
4210 assert(comp.c_source_files.len == 1);4207 assert(comp.c_source_files.len == 1);
4211 const c_source_file = comp.c_source_files[0];4208 const c_source_file = comp.c_source_files[0];
42124209
...@@ -4225,7 +4222,7 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati...@@ -4225,7 +4222,7 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
4225 const digest = if (try man.hit()) man.final() else digest: {4222 const digest = if (try man.hit()) man.final() else digest: {
4226 if (fancy_output) |p| p.cache_hit = false;4223 if (fancy_output) |p| p.cache_hit = false;
4227 var argv = std.ArrayList([]const u8).init(arena);4224 var argv = std.ArrayList([]const u8).init(arena);
4228 try argv.append(""); // argv[0] is program name, actual args start at [1]4225 try argv.append(@tagName(comp.c_frontend)); // argv[0] is program name, actual args start at [1]
42294226
4230 var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{});4227 var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{});
4231 defer zig_cache_tmp_dir.close();4228 defer zig_cache_tmp_dir.close();
...@@ -4245,40 +4242,52 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati...@@ -4245,40 +4242,52 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
4245 try argv.append(c_source_file.src_path);4242 try argv.append(c_source_file.src_path);
42464243
4247 if (comp.verbose_cc) {4244 if (comp.verbose_cc) {
4248 std.debug.print("clang ", .{});
4249 Compilation.dump_argv(argv.items);4245 Compilation.dump_argv(argv.items);
4250 }4246 }
42514247
4252 // Convert to null terminated args.4248 var tree = switch (comp.c_frontend) {
4253 const clang_args_len = argv.items.len + c_source_file.extra_flags.len;4249 .aro => tree: {
4254 const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, clang_args_len + 1);4250 if (builtin.zig_backend == .stage2_c) @panic("the CBE cannot compile Aro yet!");
4255 new_argv_with_sentinel[clang_args_len] = null;4251 const translate_c = @import("aro_translate_c.zig");
4256 const new_argv = new_argv_with_sentinel[0..clang_args_len :null];4252 _ = translate_c;
4257 for (argv.items, 0..) |arg, i| {4253 break :tree undefined;
4258 new_argv[i] = try arena.dupeZ(u8, arg);4254 },
4259 }4255 .clang => tree: {
4260 for (c_source_file.extra_flags, 0..) |arg, i| {4256 if (!build_options.have_llvm) unreachable;
4261 new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);4257 const translate_c = @import("translate_c.zig");
4262 }4258
42634259 // Convert to null terminated args.
4264 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});4260 const clang_args_len = argv.items.len + c_source_file.extra_flags.len;
4265 var errors = std.zig.ErrorBundle.empty;4261 const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, clang_args_len + 1);
4266 var tree = translate_c.translate(4262 new_argv_with_sentinel[clang_args_len] = null;
4267 comp.gpa,4263 const new_argv = new_argv_with_sentinel[0..clang_args_len :null];
4268 new_argv.ptr,4264 for (argv.items, 0..) |arg, i| {
4269 new_argv.ptr + new_argv.len,4265 new_argv[i] = try arena.dupeZ(u8, arg);
4270 &errors,4266 }
4271 c_headers_dir_path_z,4267 for (c_source_file.extra_flags, 0..) |arg, i| {
4272 ) catch |err| switch (err) {4268 new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);
4273 error.OutOfMemory => return error.OutOfMemory,
4274 error.SemanticAnalyzeFail => {
4275 if (fancy_output) |p| {
4276 p.errors = errors;
4277 return;
4278 } else {
4279 errors.renderToStdErr(renderOptions(comp.color));
4280 process.exit(1);
4281 }4269 }
4270
4271 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
4272 var errors = std.zig.ErrorBundle.empty;
4273 break :tree translate_c.translate(
4274 comp.gpa,
4275 new_argv.ptr,
4276 new_argv.ptr + new_argv.len,
4277 &errors,
4278 c_headers_dir_path_z,
4279 ) catch |err| switch (err) {
4280 error.OutOfMemory => return error.OutOfMemory,
4281 error.SemanticAnalyzeFail => {
4282 if (fancy_output) |p| {
4283 p.errors = errors;
4284 return;
4285 } else {
4286 errors.renderToStdErr(renderOptions(comp.color));
4287 process.exit(1);
4288 }
4289 },
4290 };
4282 },4291 },
4283 };4292 };
4284 defer tree.deinit(comp.gpa);4293 defer tree.deinit(comp.gpa);