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");
3232const InternPool = @import("InternPool.zig");
3333const BuildId = std.Build.CompileStep.BuildId;
3434const Cache = std.Build.Cache;
35const translate_c = @import("translate_c.zig");
3635const c_codegen = @import("codegen/c.zig");
3736const libtsan = @import("libtsan.zig");
3837const Zir = @import("Zir.zig");
......@@ -88,7 +87,7 @@ failed_win32_resources: if (build_options.only_core_functionality) void else std
8887misc_failures: std.AutoArrayHashMapUnmanaged(MiscTask, MiscError) = .{},
8988
9089keep_source_files_loaded: bool,
91use_clang: bool,
90c_frontend: CFrontend,
9291sanitize_c: bool,
9392/// When this is `true` it means invoking clang as a sub-process is expected to inherit
9493/// stdin, stdout, stderr, and if it returns non success, to forward the exit code.
......@@ -515,6 +514,8 @@ pub const cache_helpers = struct {
515514 }
516515};
517516
517pub const CFrontend = enum { clang, aro };
518
518519pub const ClangPreprocessorMode = enum {
519520 no,
520521 /// This means we are doing `zig cc -E -o <path>`.
......@@ -1046,14 +1047,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
10461047 break :pic explicit;
10471048 } else pie or must_pic;
10481049
1049 // Make a decision on whether to use Clang for translate-c and compiling C files.
1050 const use_clang = if (options.use_clang) |explicit| explicit else blk: {
1051 if (build_options.have_llvm) {
1052 // Can't use it if we don't have it!
1053 break :blk false;
1054 }
1055 // It's not planned to do our own translate-c or C compilation.
1056 break :blk true;
1050 // Make a decision on whether to use Clang or Aro for translate-c and compiling C files.
1051 const c_frontend: CFrontend = blk: {
1052 if (!build_options.have_llvm) break :blk .aro;
1053 if (options.use_clang) |explicit| if (explicit) break :blk .clang;
1054 break :blk .clang;
10571055 };
10581056
10591057 const is_safe_mode = switch (options.optimize_mode) {
......@@ -1677,7 +1675,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
16771675 .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa),
16781676 .embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa),
16791677 .keep_source_files_loaded = options.keep_source_files_loaded,
1680 .use_clang = use_clang,
1678 .c_frontend = c_frontend,
16811679 .clang_argv = options.clang_argv,
16821680 .c_source_files = options.c_source_files,
16831681 .rc_source_files = options.rc_source_files,
......@@ -3918,9 +3916,7 @@ pub const CImportResult = struct {
39183916/// This API is currently coupled pretty tightly to stage1's needs; it will need to be reworked
39193917/// a bit when we want to start using it from self-hosted.
39203918pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
3921 if (!build_options.have_llvm)
3922 return error.ZigCompilerNotBuiltWithLLVMExtensions;
3923
3919 if (build_options.only_c) unreachable; // @cImport is not needed for bootstrapping
39243920 const tracy_trace = trace(@src());
39253921 defer tracy_trace.end();
39263922
......@@ -3967,7 +3963,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
39673963 var argv = std.ArrayList([]const u8).init(comp.gpa);
39683964 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]
39713967 try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path);
39723968
39733969 try argv.append(out_h_path);
......@@ -3975,31 +3971,43 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
39753971 if (comp.verbose_cc) {
39763972 dump_argv(argv.items);
39773973 }
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.
3980 const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1);
3981 new_argv_with_sentinel[argv.items.len] = null;
3982 const new_argv = new_argv_with_sentinel[0..argv.items.len :null];
3983 for (argv.items, 0..) |arg, i| {
3984 new_argv[i] = try arena.dupeZ(u8, arg);
3985 }
3986
3987 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
3988 var errors = std.zig.ErrorBundle.empty;
3989 errdefer errors.deinit(comp.gpa);
3990 var tree = translate_c.translate(
3991 comp.gpa,
3992 new_argv.ptr,
3993 new_argv.ptr + new_argv.len,
3994 &errors,
3995 c_headers_dir_path_z,
3996 ) catch |err| switch (err) {
3997 error.OutOfMemory => return error.OutOfMemory,
3998 error.SemanticAnalyzeFail => {
3999 return CImportResult{
4000 .out_zig_path = "",
4001 .cache_hit = actual_hit,
4002 .errors = errors,
3993 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
3994 var errors = std.zig.ErrorBundle.empty;
3995 errdefer errors.deinit(comp.gpa);
3996 break :tree translate_c.translate(
3997 comp.gpa,
3998 new_argv.ptr,
3999 new_argv.ptr + new_argv.len,
4000 &errors,
4001 c_headers_dir_path_z,
4002 ) catch |err| switch (err) {
4003 error.OutOfMemory => return error.OutOfMemory,
4004 error.SemanticAnalyzeFail => {
4005 return CImportResult{
4006 .out_zig_path = "",
4007 .cache_hit = actual_hit,
4008 .errors = errors,
4009 };
4010 },
40034011 };
40044012 },
40054013 };
......@@ -4249,6 +4257,9 @@ fn reportRetryableEmbedFileError(
42494257}
42504258
42514259fn 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 }
42524263 if (!build_options.have_llvm) {
42534264 return comp.failCObj(c_object, "clang not available: compiler built without LLVM extensions", .{});
42544265 }
src/main.zig+44-35
......@@ -20,7 +20,6 @@ const build_options = @import("build_options");
2020const introspect = @import("introspect.zig");
2121const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
2222const wasi_libc = @import("wasi_libc.zig");
23const translate_c = @import("translate_c.zig");
2423const BuildId = std.Build.CompileStep.BuildId;
2524const Cache = std.Build.Cache;
2625const target_util = @import("target.zig");
......@@ -4204,9 +4203,7 @@ fn updateModule(comp: *Compilation) !void {
42044203}
42054204
42064205fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilation.CImportResult) !void {
4207 if (!build_options.have_llvm)
4208 fatal("cannot translate-c: compiler built without LLVM extensions", .{});
4209
4206 if (build_options.only_c) unreachable; // translate-c is not needed for bootstrapping
42104207 assert(comp.c_source_files.len == 1);
42114208 const c_source_file = comp.c_source_files[0];
42124209
......@@ -4225,7 +4222,7 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
42254222 const digest = if (try man.hit()) man.final() else digest: {
42264223 if (fancy_output) |p| p.cache_hit = false;
42274224 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
42304227 var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{});
42314228 defer zig_cache_tmp_dir.close();
......@@ -4245,40 +4242,52 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
42454242 try argv.append(c_source_file.src_path);
42464243
42474244 if (comp.verbose_cc) {
4248 std.debug.print("clang ", .{});
42494245 Compilation.dump_argv(argv.items);
42504246 }
42514247
4252 // Convert to null terminated args.
4253 const clang_args_len = argv.items.len + c_source_file.extra_flags.len;
4254 const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, clang_args_len + 1);
4255 new_argv_with_sentinel[clang_args_len] = null;
4256 const new_argv = new_argv_with_sentinel[0..clang_args_len :null];
4257 for (argv.items, 0..) |arg, i| {
4258 new_argv[i] = try arena.dupeZ(u8, arg);
4259 }
4260 for (c_source_file.extra_flags, 0..) |arg, i| {
4261 new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);
4262 }
4263
4264 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
4265 var errors = std.zig.ErrorBundle.empty;
4266 var tree = translate_c.translate(
4267 comp.gpa,
4268 new_argv.ptr,
4269 new_argv.ptr + new_argv.len,
4270 &errors,
4271 c_headers_dir_path_z,
4272 ) catch |err| switch (err) {
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);
4248 var tree = switch (comp.c_frontend) {
4249 .aro => tree: {
4250 if (builtin.zig_backend == .stage2_c) @panic("the CBE cannot compile Aro yet!");
4251 const translate_c = @import("aro_translate_c.zig");
4252 _ = translate_c;
4253 break :tree undefined;
4254 },
4255 .clang => tree: {
4256 if (!build_options.have_llvm) unreachable;
4257 const translate_c = @import("translate_c.zig");
4258
4259 // Convert to null terminated args.
4260 const clang_args_len = argv.items.len + c_source_file.extra_flags.len;
4261 const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, clang_args_len + 1);
4262 new_argv_with_sentinel[clang_args_len] = null;
4263 const new_argv = new_argv_with_sentinel[0..clang_args_len :null];
4264 for (argv.items, 0..) |arg, i| {
4265 new_argv[i] = try arena.dupeZ(u8, arg);
4266 }
4267 for (c_source_file.extra_flags, 0..) |arg, i| {
4268 new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);
42814269 }
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 };
42824291 },
42834292 };
42844293 defer tree.deinit(comp.gpa);