add compiler flag for selecting C frontend
This commit is contained in:
@@ -32,7 +32,6 @@ const Module = @import("Module.zig");
|
||||
const InternPool = @import("InternPool.zig");
|
||||
const BuildId = std.Build.CompileStep.BuildId;
|
||||
const Cache = std.Build.Cache;
|
||||
const translate_c = @import("translate_c.zig");
|
||||
const c_codegen = @import("codegen/c.zig");
|
||||
const libtsan = @import("libtsan.zig");
|
||||
const Zir = @import("Zir.zig");
|
||||
@@ -88,7 +87,7 @@ failed_win32_resources: if (build_options.only_core_functionality) void else std
|
||||
misc_failures: std.AutoArrayHashMapUnmanaged(MiscTask, MiscError) = .{},
|
||||
|
||||
keep_source_files_loaded: bool,
|
||||
use_clang: bool,
|
||||
c_frontend: CFrontend,
|
||||
sanitize_c: bool,
|
||||
/// When this is `true` it means invoking clang as a sub-process is expected to inherit
|
||||
/// stdin, stdout, stderr, and if it returns non success, to forward the exit code.
|
||||
@@ -515,6 +514,8 @@ pub const cache_helpers = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const CFrontend = enum { clang, aro };
|
||||
|
||||
pub const ClangPreprocessorMode = enum {
|
||||
no,
|
||||
/// This means we are doing `zig cc -E -o <path>`.
|
||||
@@ -1046,14 +1047,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
||||
break :pic explicit;
|
||||
} else pie or must_pic;
|
||||
|
||||
// Make a decision on whether to use Clang for translate-c and compiling C files.
|
||||
const use_clang = if (options.use_clang) |explicit| explicit else blk: {
|
||||
if (build_options.have_llvm) {
|
||||
// Can't use it if we don't have it!
|
||||
break :blk false;
|
||||
}
|
||||
// It's not planned to do our own translate-c or C compilation.
|
||||
break :blk true;
|
||||
// Make a decision on whether to use Clang or Aro for translate-c and compiling C files.
|
||||
const c_frontend: CFrontend = blk: {
|
||||
if (!build_options.have_llvm) break :blk .aro;
|
||||
if (options.use_clang) |explicit| if (explicit) break :blk .clang;
|
||||
break :blk .clang;
|
||||
};
|
||||
|
||||
const is_safe_mode = switch (options.optimize_mode) {
|
||||
@@ -1677,7 +1675,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
||||
.astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa),
|
||||
.embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa),
|
||||
.keep_source_files_loaded = options.keep_source_files_loaded,
|
||||
.use_clang = use_clang,
|
||||
.c_frontend = c_frontend,
|
||||
.clang_argv = options.clang_argv,
|
||||
.c_source_files = options.c_source_files,
|
||||
.rc_source_files = options.rc_source_files,
|
||||
@@ -3918,9 +3916,7 @@ pub const CImportResult = struct {
|
||||
/// This API is currently coupled pretty tightly to stage1's needs; it will need to be reworked
|
||||
/// a bit when we want to start using it from self-hosted.
|
||||
pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
|
||||
if (!build_options.have_llvm)
|
||||
return error.ZigCompilerNotBuiltWithLLVMExtensions;
|
||||
|
||||
if (build_options.only_c) unreachable; // @cImport is not needed for bootstrapping
|
||||
const tracy_trace = trace(@src());
|
||||
defer tracy_trace.end();
|
||||
|
||||
@@ -3967,7 +3963,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
|
||||
var argv = std.ArrayList([]const u8).init(comp.gpa);
|
||||
defer argv.deinit();
|
||||
|
||||
try argv.append(""); // argv[0] is program name, actual args start at [1]
|
||||
try argv.append(@tagName(comp.c_frontend)); // argv[0] is program name, actual args start at [1]
|
||||
try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path);
|
||||
|
||||
try argv.append(out_h_path);
|
||||
@@ -3975,31 +3971,43 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
|
||||
if (comp.verbose_cc) {
|
||||
dump_argv(argv.items);
|
||||
}
|
||||
var tree = switch (comp.c_frontend) {
|
||||
.aro => tree: {
|
||||
if (builtin.zig_backend == .stage2_c) @panic("the CBE cannot compile Aro yet!");
|
||||
const translate_c = @import("aro_translate_c.zig");
|
||||
_ = translate_c;
|
||||
break :tree undefined;
|
||||
},
|
||||
.clang => tree: {
|
||||
if (!build_options.have_llvm) unreachable;
|
||||
const translate_c = @import("translate_c.zig");
|
||||
|
||||
// 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];
|
||||
for (argv.items, 0..) |arg, i| {
|
||||
new_argv[i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
// 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];
|
||||
for (argv.items, 0..) |arg, i| {
|
||||
new_argv[i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
|
||||
const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
|
||||
var errors = std.zig.ErrorBundle.empty;
|
||||
errdefer errors.deinit(comp.gpa);
|
||||
var tree = translate_c.translate(
|
||||
comp.gpa,
|
||||
new_argv.ptr,
|
||||
new_argv.ptr + new_argv.len,
|
||||
&errors,
|
||||
c_headers_dir_path_z,
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.SemanticAnalyzeFail => {
|
||||
return CImportResult{
|
||||
.out_zig_path = "",
|
||||
.cache_hit = actual_hit,
|
||||
.errors = errors,
|
||||
const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
|
||||
var errors = std.zig.ErrorBundle.empty;
|
||||
errdefer errors.deinit(comp.gpa);
|
||||
break :tree translate_c.translate(
|
||||
comp.gpa,
|
||||
new_argv.ptr,
|
||||
new_argv.ptr + new_argv.len,
|
||||
&errors,
|
||||
c_headers_dir_path_z,
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.SemanticAnalyzeFail => {
|
||||
return CImportResult{
|
||||
.out_zig_path = "",
|
||||
.cache_hit = actual_hit,
|
||||
.errors = errors,
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -4249,6 +4257,9 @@ fn reportRetryableEmbedFileError(
|
||||
}
|
||||
|
||||
fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.Progress.Node) !void {
|
||||
if (comp.c_frontend == .aro) {
|
||||
return comp.failCObj(c_object, "aro does not support compiling C objects yet", .{});
|
||||
}
|
||||
if (!build_options.have_llvm) {
|
||||
return comp.failCObj(c_object, "clang not available: compiler built without LLVM extensions", .{});
|
||||
}
|
||||
|
||||
77
src/main.zig
77
src/main.zig
@@ -20,7 +20,6 @@ const build_options = @import("build_options");
|
||||
const introspect = @import("introspect.zig");
|
||||
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
||||
const wasi_libc = @import("wasi_libc.zig");
|
||||
const translate_c = @import("translate_c.zig");
|
||||
const BuildId = std.Build.CompileStep.BuildId;
|
||||
const Cache = std.Build.Cache;
|
||||
const target_util = @import("target.zig");
|
||||
@@ -4204,9 +4203,7 @@ fn updateModule(comp: *Compilation) !void {
|
||||
}
|
||||
|
||||
fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilation.CImportResult) !void {
|
||||
if (!build_options.have_llvm)
|
||||
fatal("cannot translate-c: compiler built without LLVM extensions", .{});
|
||||
|
||||
if (build_options.only_c) unreachable; // translate-c is not needed for bootstrapping
|
||||
assert(comp.c_source_files.len == 1);
|
||||
const c_source_file = comp.c_source_files[0];
|
||||
|
||||
@@ -4225,7 +4222,7 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
|
||||
const digest = if (try man.hit()) man.final() else digest: {
|
||||
if (fancy_output) |p| p.cache_hit = false;
|
||||
var argv = std.ArrayList([]const u8).init(arena);
|
||||
try argv.append(""); // argv[0] is program name, actual args start at [1]
|
||||
try argv.append(@tagName(comp.c_frontend)); // argv[0] is program name, actual args start at [1]
|
||||
|
||||
var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{});
|
||||
defer zig_cache_tmp_dir.close();
|
||||
@@ -4245,40 +4242,52 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
|
||||
try argv.append(c_source_file.src_path);
|
||||
|
||||
if (comp.verbose_cc) {
|
||||
std.debug.print("clang ", .{});
|
||||
Compilation.dump_argv(argv.items);
|
||||
}
|
||||
|
||||
// Convert to null terminated args.
|
||||
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, 0..) |arg, i| {
|
||||
new_argv[i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
for (c_source_file.extra_flags, 0..) |arg, i| {
|
||||
new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
var tree = switch (comp.c_frontend) {
|
||||
.aro => tree: {
|
||||
if (builtin.zig_backend == .stage2_c) @panic("the CBE cannot compile Aro yet!");
|
||||
const translate_c = @import("aro_translate_c.zig");
|
||||
_ = translate_c;
|
||||
break :tree undefined;
|
||||
},
|
||||
.clang => tree: {
|
||||
if (!build_options.have_llvm) unreachable;
|
||||
const translate_c = @import("translate_c.zig");
|
||||
|
||||
const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
|
||||
var errors = std.zig.ErrorBundle.empty;
|
||||
var tree = translate_c.translate(
|
||||
comp.gpa,
|
||||
new_argv.ptr,
|
||||
new_argv.ptr + new_argv.len,
|
||||
&errors,
|
||||
c_headers_dir_path_z,
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.SemanticAnalyzeFail => {
|
||||
if (fancy_output) |p| {
|
||||
p.errors = errors;
|
||||
return;
|
||||
} else {
|
||||
errors.renderToStdErr(renderOptions(comp.color));
|
||||
process.exit(1);
|
||||
// Convert to null terminated args.
|
||||
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, 0..) |arg, i| {
|
||||
new_argv[i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
for (c_source_file.extra_flags, 0..) |arg, i| {
|
||||
new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
|
||||
const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
|
||||
var errors = std.zig.ErrorBundle.empty;
|
||||
break :tree translate_c.translate(
|
||||
comp.gpa,
|
||||
new_argv.ptr,
|
||||
new_argv.ptr + new_argv.len,
|
||||
&errors,
|
||||
c_headers_dir_path_z,
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.SemanticAnalyzeFail => {
|
||||
if (fancy_output) |p| {
|
||||
p.errors = errors;
|
||||
return;
|
||||
} else {
|
||||
errors.renderToStdErr(renderOptions(comp.color));
|
||||
process.exit(1);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
defer tree.deinit(comp.gpa);
|
||||
|
||||
Reference in New Issue
Block a user