stage2: add CLI for `zig translate-c`
parent
a9b18023a4
commit
dc79651e6a
|
@ -1,4 +1,3 @@
|
||||||
* `zig translate-c`
|
|
||||||
* `zig test`
|
* `zig test`
|
||||||
* `zig build`
|
* `zig build`
|
||||||
* `-ftime-report`
|
* `-ftime-report`
|
||||||
|
|
|
@ -392,15 +392,18 @@ if(ZIG_TEST_COVERAGE)
|
||||||
set(EXE_LDFLAGS "${EXE_LDFLAGS} -fprofile-arcs -ftest-coverage")
|
set(EXE_LDFLAGS "${EXE_LDFLAGS} -fprofile-arcs -ftest-coverage")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(zig_cpp STATIC ${ZIG_CPP_SOURCES})
|
add_library(zig_cpp STATIC ${ZIG_SOURCES} ${ZIG_CPP_SOURCES})
|
||||||
set_target_properties(zig_cpp PROPERTIES
|
set_target_properties(zig_cpp PROPERTIES
|
||||||
COMPILE_FLAGS ${EXE_CFLAGS}
|
COMPILE_FLAGS ${EXE_CFLAGS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(zig_cpp LINK_PUBLIC
|
target_link_libraries(zig_cpp LINK_PUBLIC
|
||||||
|
opt_c_util
|
||||||
|
${SOFTFLOAT_LIBRARIES}
|
||||||
${CLANG_LIBRARIES}
|
${CLANG_LIBRARIES}
|
||||||
${LLD_LIBRARIES}
|
${LLD_LIBRARIES}
|
||||||
${LLVM_LIBRARIES}
|
${LLVM_LIBRARIES}
|
||||||
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
)
|
)
|
||||||
if(ZIG_WORKAROUND_POLLY_SO)
|
if(ZIG_WORKAROUND_POLLY_SO)
|
||||||
target_link_libraries(zig_cpp LINK_PUBLIC "-Wl,${ZIG_WORKAROUND_POLLY_SO}")
|
target_link_libraries(zig_cpp LINK_PUBLIC "-Wl,${ZIG_WORKAROUND_POLLY_SO}")
|
||||||
|
@ -411,27 +414,16 @@ set_target_properties(opt_c_util PROPERTIES
|
||||||
COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
|
COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(zigcompiler STATIC ${ZIG_SOURCES})
|
|
||||||
set_target_properties(zigcompiler PROPERTIES
|
|
||||||
COMPILE_FLAGS ${EXE_CFLAGS}
|
|
||||||
LINK_FLAGS ${EXE_LDFLAGS}
|
|
||||||
)
|
|
||||||
target_link_libraries(zigcompiler LINK_PUBLIC
|
|
||||||
zig_cpp
|
|
||||||
opt_c_util
|
|
||||||
${SOFTFLOAT_LIBRARIES}
|
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
|
||||||
)
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
target_link_libraries(zigcompiler LINK_PUBLIC ${LIBXML2})
|
target_link_libraries(zig_cpp LINK_PUBLIC ${LIBXML2})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ZIG_DIA_GUIDS_LIB)
|
if(ZIG_DIA_GUIDS_LIB)
|
||||||
target_link_libraries(zigcompiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
|
target_link_libraries(zig_cpp LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MSVC OR MINGW)
|
if(MSVC OR MINGW)
|
||||||
target_link_libraries(zigcompiler LINK_PUBLIC version)
|
target_link_libraries(zig_cpp LINK_PUBLIC version)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(zig0 ${ZIG0_SOURCES})
|
add_executable(zig0 ${ZIG0_SOURCES})
|
||||||
|
@ -439,7 +431,7 @@ set_target_properties(zig0 PROPERTIES
|
||||||
COMPILE_FLAGS ${EXE_CFLAGS}
|
COMPILE_FLAGS ${EXE_CFLAGS}
|
||||||
LINK_FLAGS ${EXE_LDFLAGS}
|
LINK_FLAGS ${EXE_LDFLAGS}
|
||||||
)
|
)
|
||||||
target_link_libraries(zig0 zigcompiler)
|
target_link_libraries(zig0 zig_cpp)
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
set(ZIG1_OBJECT "${CMAKE_BINARY_DIR}/zig1.obj")
|
set(ZIG1_OBJECT "${CMAKE_BINARY_DIR}/zig1.obj")
|
||||||
|
@ -493,7 +485,7 @@ set_target_properties(zig PROPERTIES
|
||||||
COMPILE_FLAGS ${EXE_CFLAGS}
|
COMPILE_FLAGS ${EXE_CFLAGS}
|
||||||
LINK_FLAGS ${EXE_LDFLAGS}
|
LINK_FLAGS ${EXE_LDFLAGS}
|
||||||
)
|
)
|
||||||
target_link_libraries(zig zigcompiler "${ZIG1_OBJECT}")
|
target_link_libraries(zig "${ZIG1_OBJECT}" zig_cpp)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_link_libraries(zig ntdll.lib)
|
target_link_libraries(zig ntdll.lib)
|
||||||
elseif(MINGW)
|
elseif(MINGW)
|
||||||
|
|
|
@ -1005,7 +1005,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
|
||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
|
|
||||||
if (!build_options.have_llvm) {
|
if (!build_options.have_llvm) {
|
||||||
return comp.failCObj(c_object, "clang not available: compiler not built with LLVM extensions enabled", .{});
|
return comp.failCObj(c_object, "clang not available: compiler built without LLVM extensions", .{});
|
||||||
}
|
}
|
||||||
const self_exe_path = comp.self_exe_path orelse
|
const self_exe_path = comp.self_exe_path orelse
|
||||||
return comp.failCObj(c_object, "clang compilation disabled", .{});
|
return comp.failCObj(c_object, "clang compilation disabled", .{});
|
||||||
|
@ -1081,10 +1081,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
|
||||||
try argv.appendSlice(c_object.src.extra_flags);
|
try argv.appendSlice(c_object.src.extra_flags);
|
||||||
|
|
||||||
if (comp.verbose_cc) {
|
if (comp.verbose_cc) {
|
||||||
for (argv.items[0 .. argv.items.len - 1]) |arg| {
|
dump_argv(argv.items);
|
||||||
std.debug.print("{} ", .{arg});
|
|
||||||
}
|
|
||||||
std.debug.print("{}\n", .{argv.items[argv.items.len - 1]});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const child = try std.ChildProcess.init(argv.items, arena);
|
const child = try std.ChildProcess.init(argv.items, arena);
|
||||||
|
@ -1190,7 +1187,7 @@ fn tmpFilePath(comp: *Compilation, arena: *Allocator, suffix: []const u8) error{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add common C compiler args between translate-c and C object compilation.
|
/// Add common C compiler args between translate-c and C object compilation.
|
||||||
fn addCCArgs(
|
pub fn addCCArgs(
|
||||||
comp: *Compilation,
|
comp: *Compilation,
|
||||||
arena: *Allocator,
|
arena: *Allocator,
|
||||||
argv: *std.ArrayList([]const u8),
|
argv: *std.ArrayList([]const u8),
|
||||||
|
@ -1671,12 +1668,19 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) !void {
|
fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) !void {
|
||||||
const source = try comp.generateBuiltinZigSource();
|
const source = try comp.generateBuiltinZigSource(comp.gpa);
|
||||||
defer comp.gpa.free(source);
|
defer comp.gpa.free(source);
|
||||||
try mod.zig_cache_artifact_directory.handle.writeFile("builtin.zig", source);
|
try mod.zig_cache_artifact_directory.handle.writeFile("builtin.zig", source);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generateBuiltinZigSource(comp: *Compilation) ![]u8 {
|
pub fn dump_argv(argv: []const []const u8) void {
|
||||||
|
for (argv[0 .. argv.len - 1]) |arg| {
|
||||||
|
std.debug.print("{} ", .{arg});
|
||||||
|
}
|
||||||
|
std.debug.print("{}\n", .{argv[argv.len - 1]});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 {
|
||||||
var buffer = std.ArrayList(u8).init(comp.gpa);
|
var buffer = std.ArrayList(u8).init(comp.gpa);
|
||||||
defer buffer.deinit();
|
defer buffer.deinit();
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ const build_options = @import("build_options");
|
||||||
const warn = std.log.warn;
|
const warn = std.log.warn;
|
||||||
const introspect = @import("introspect.zig");
|
const introspect = @import("introspect.zig");
|
||||||
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
||||||
|
const translate_c = @import("translate_c.zig");
|
||||||
|
|
||||||
pub fn fatal(comptime format: []const u8, args: anytype) noreturn {
|
pub fn fatal(comptime format: []const u8, args: anytype) noreturn {
|
||||||
std.log.emerg(format, args);
|
std.log.emerg(format, args);
|
||||||
|
@ -864,6 +865,10 @@ pub fn buildOutputType(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg_mode == .translate_c and c_source_files.items.len != 1) {
|
||||||
|
fatal("translate-c expects exactly 1 source file (found {})", .{c_source_files.items.len});
|
||||||
|
}
|
||||||
|
|
||||||
const root_name = if (provided_name) |n| n else blk: {
|
const root_name = if (provided_name) |n| n else blk: {
|
||||||
if (root_src_file) |file| {
|
if (root_src_file) |file| {
|
||||||
const basename = fs.path.basename(file);
|
const basename = fs.path.basename(file);
|
||||||
|
@ -1175,10 +1180,10 @@ pub fn buildOutputType(
|
||||||
defer comp.destroy();
|
defer comp.destroy();
|
||||||
|
|
||||||
if (show_builtin) {
|
if (show_builtin) {
|
||||||
const source = try comp.generateBuiltinZigSource();
|
return std.io.getStdOut().writeAll(try comp.generateBuiltinZigSource(arena));
|
||||||
defer comp.gpa.free(source);
|
}
|
||||||
try std.io.getStdOut().writeAll(source);
|
if (arg_mode == .translate_c) {
|
||||||
return;
|
return cmdTranslateC(comp, arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
try updateModule(gpa, comp, zir_out_path);
|
try updateModule(gpa, comp, zir_out_path);
|
||||||
|
@ -1248,6 +1253,63 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, zir_out_path: ?[]const u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cmdTranslateC(comp: *Compilation, arena: *Allocator) !void {
|
||||||
|
if (!build_options.have_llvm)
|
||||||
|
fatal("cannot translate-c: compiler built without LLVM extensions", .{});
|
||||||
|
|
||||||
|
assert(comp.c_source_files.len == 1);
|
||||||
|
|
||||||
|
var argv = std.ArrayList([]const u8).init(arena);
|
||||||
|
|
||||||
|
const c_source_file = comp.c_source_files[0];
|
||||||
|
const file_ext = Compilation.classifyFileExt(c_source_file.src_path);
|
||||||
|
try comp.addCCArgs(arena, &argv, file_ext, true, null);
|
||||||
|
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 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) |arg, i| {
|
||||||
|
new_argv[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);
|
||||||
|
var clang_errors: []translate_c.ClangErrMsg = &[0]translate_c.ClangErrMsg{};
|
||||||
|
const tree = translate_c.translate(
|
||||||
|
comp.gpa,
|
||||||
|
new_argv.ptr,
|
||||||
|
new_argv.ptr + new_argv.len,
|
||||||
|
&clang_errors,
|
||||||
|
c_headers_dir_path_z,
|
||||||
|
) catch |err| switch (err) {
|
||||||
|
error.OutOfMemory => return error.OutOfMemory,
|
||||||
|
error.ASTUnitFailure => fatal("clang API returned errors but due to a clang bug, it is not exposing the errors for zig to see. For more details: https://github.com/ziglang/zig/issues/4455", .{}),
|
||||||
|
error.SemanticAnalyzeFail => {
|
||||||
|
for (clang_errors) |clang_err| {
|
||||||
|
std.debug.print("{}:{}:{}: {}\n", .{
|
||||||
|
if (clang_err.filename_ptr) |p| p[0..clang_err.filename_len] else "(no file)",
|
||||||
|
clang_err.line + 1,
|
||||||
|
clang_err.column + 1,
|
||||||
|
clang_err.msg_ptr[0..clang_err.msg_len],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
process.exit(1);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
defer tree.deinit();
|
||||||
|
|
||||||
|
var bos = io.bufferedOutStream(io.getStdOut().writer());
|
||||||
|
_ = try std.zig.render(comp.gpa, bos.writer(), tree);
|
||||||
|
try bos.flush();
|
||||||
|
}
|
||||||
|
|
||||||
pub const usage_libc =
|
pub const usage_libc =
|
||||||
\\Usage: zig libc
|
\\Usage: zig libc
|
||||||
\\
|
\\
|
||||||
|
@ -1401,8 +1463,9 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
|
||||||
process.exit(code);
|
process.exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
const stdout = io.getStdOut().outStream();
|
var bos = io.bufferedOutStream(io.getStdOut().writer());
|
||||||
_ = try std.zig.render(gpa, stdout, tree);
|
_ = try std.zig.render(gpa, bos.writer(), tree);
|
||||||
|
try bos.flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1644,7 +1707,7 @@ extern "c" fn ZigClang_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
|
||||||
/// TODO https://github.com/ziglang/zig/issues/3257
|
/// TODO https://github.com/ziglang/zig/issues/3257
|
||||||
fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory} {
|
fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory} {
|
||||||
if (!build_options.have_llvm)
|
if (!build_options.have_llvm)
|
||||||
fatal("`zig cc` and `zig c++` unavailable: compiler not built with LLVM extensions enabled", .{});
|
fatal("`zig cc` and `zig c++` unavailable: compiler built without LLVM extensions", .{});
|
||||||
// Convert the args to the format Clang expects.
|
// Convert the args to the format Clang expects.
|
||||||
const argv = try arena.alloc(?[*:0]u8, args.len + 1);
|
const argv = try arena.alloc(?[*:0]u8, args.len + 1);
|
||||||
for (args) |arg, i| {
|
for (args) |arg, i| {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// This is the userland implementation of translate-c which is used by both stage1
|
//! This is the userland implementation of translate-c which is used by both stage1
|
||||||
// and stage2.
|
//! and stage2.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
|
Loading…
Reference in New Issue