Skip to content

Commit

Permalink
mingw: Use aro instead of clang for preprocessing import libs
Browse files Browse the repository at this point in the history
  • Loading branch information
ehaas committed Nov 3, 2023
1 parent 94cee4f commit 9f2cb92
Showing 1 changed file with 47 additions and 58 deletions.
105 changes: 47 additions & 58 deletions src/mingw.zig
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,6 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
else => |e| return e,
};

// We need to invoke `zig clang` to use the preprocessor.
if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;
const self_exe_path = comp.self_exe_path orelse return error.PreprocessorDisabled;

const target = comp.getTarget();

var cache: Cache = .{
Expand All @@ -305,6 +301,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
cache.hash.addBytes(build_options.version);
cache.hash.addOptionalBytes(comp.zig_lib_directory.path);
cache.hash.add(target.cpu.arch);
cache.hash.addBytes("aro");

var man = cache.obtain();
defer man.deinit();
Expand Down Expand Up @@ -337,74 +334,66 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
"o", &digest, final_def_basename,
});

const target_def_arg = switch (target.cpu.arch) {
.x86 => "-DDEF_I386",
.x86_64 => "-DDEF_X64",
.arm, .armeb, .thumb, .thumbeb, .aarch64_32 => "-DDEF_ARM32",
.aarch64, .aarch64_be => "-DDEF_ARM64",
const target_defines = switch (target.cpu.arch) {
.x86 => "#define DEF_I386\n",
.x86_64 => "#define DEF_X64\n",
.arm, .armeb, .thumb, .thumbeb, .aarch64_32 => "#define DEF_ARM32\n",
.aarch64, .aarch64_be => "#define DEF_ARM64\n",
else => unreachable,
};

const args = [_][]const u8{
self_exe_path,
"clang",
"-x",
"c",
def_file_path,
"-Wp,-w",
"-undef",
"-P",
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "def-include" }),
target_def_arg,
"-E",
"-o",
def_final_path,
};
if (builtin.zig_backend == .stage2_c) @panic("the CBE cannot compile Aro yet!");
const aro = @import("aro");
var aro_comp = aro.Compilation.init(comp.gpa);
defer aro_comp.deinit();

if (comp.verbose_cc) {
Compilation.dump_argv(&args);
const include_dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "def-include" });

if (comp.verbose_cc) print: {
std.debug.getStderrMutex().lock();
defer std.debug.getStderrMutex().unlock();
const stderr = std.io.getStdErr().writer();
nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print;
nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print;
nosuspend stderr.print("output path: {s}\n", .{def_final_path}) catch break :print;
}

if (std.process.can_spawn) {
var child = std.ChildProcess.init(&args, arena);
child.stdin_behavior = .Ignore;
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Pipe;

try child.spawn();

const stderr = try child.stderr.?.reader().readAllAlloc(arena, std.math.maxInt(usize));

const term = child.wait() catch |err| {
// TODO surface a proper error here
log.err("unable to spawn {s}: {s}", .{ args[0], @errorName(err) });
return error.ClangPreprocessorFailed;
};
switch (term) {
.Exited => |code| {
if (code != 0) {
// TODO surface a proper error here
log.err("clang exited with code {d} and stderr: {s}", .{ code, stderr });
return error.ClangPreprocessorFailed;
}
},
else => {
// TODO surface a proper error here
log.err("clang terminated unexpectedly with stderr: {s}", .{stderr});
return error.ClangPreprocessorFailed;
},
try aro_comp.include_dirs.append(include_dir);

const builtin_macros = try aro_comp.generateBuiltinMacros();
const user_macros = try aro_comp.addSourceFromBuffer("<command line>", target_defines);
const def_file_source = try aro_comp.addSourceFromPath(def_file_path);

var pp = aro.Preprocessor.init(&aro_comp);
defer pp.deinit();
pp.linemarkers = .none;
pp.preserve_whitespace = true;

_ = try pp.preprocess(builtin_macros);
_ = try pp.preprocess(user_macros);
const eof = try pp.preprocess(def_file_source);
try pp.tokens.append(pp.comp.gpa, eof);

for (aro_comp.diag.list.items) |diagnostic| {
if (diagnostic.kind == .@"fatal error" or diagnostic.kind == .@"error") {
aro_comp.renderErrors();
return error.AroPreprocessorFailed;
}
} else {
log.err("unable to spawn {s}: spawning child process not supported on {s}", .{ args[0], @tagName(builtin.os.tag) });
return error.ClangPreprocessorFailed;
}

{
// new scope to ensure definition file is written before passing the path to WriteImportLibrary
const def_final_file = try comp.global_cache_directory.handle.createFile(def_final_path, .{ .truncate = true });
defer def_final_file.close();
try pp.prettyPrintTokens(def_final_file.writer());
}

const lib_final_path = try comp.global_cache_directory.join(comp.gpa, &[_][]const u8{
"o", &digest, final_lib_basename,
});
errdefer comp.gpa.free(lib_final_path);

if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;
const llvm_bindings = @import("codegen/llvm/bindings.zig");
const llvm = @import("codegen/llvm.zig");
const arch_tag = llvm.targetArch(target.cpu.arch);
Expand Down

0 comments on commit 9f2cb92

Please sign in to comment.