Skip to content

Commit 68f16db

Browse files
committed
mingw: Use aro instead of clang for preprocessing import libs
Closes #17753
1 parent 9ff9ea3 commit 68f16db

File tree

1 file changed

+47
-58
lines changed

1 file changed

+47
-58
lines changed

src/mingw.zig

Lines changed: 47 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,6 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
288288
else => |e| return e,
289289
};
290290

291-
// We need to invoke `zig clang` to use the preprocessor.
292-
if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;
293-
const self_exe_path = comp.self_exe_path orelse return error.PreprocessorDisabled;
294-
295291
const target = comp.getTarget();
296292

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

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

340-
const target_def_arg = switch (target.cpu.arch) {
341-
.x86 => "-DDEF_I386",
342-
.x86_64 => "-DDEF_X64",
343-
.arm, .armeb, .thumb, .thumbeb, .aarch64_32 => "-DDEF_ARM32",
344-
.aarch64, .aarch64_be => "-DDEF_ARM64",
337+
const target_defines = switch (target.cpu.arch) {
338+
.x86 => "#define DEF_I386\n",
339+
.x86_64 => "#define DEF_X64\n",
340+
.arm, .armeb, .thumb, .thumbeb, .aarch64_32 => "#define DEF_ARM32\n",
341+
.aarch64, .aarch64_be => "#define DEF_ARM64\n",
345342
else => unreachable,
346343
};
347344

348-
const args = [_][]const u8{
349-
self_exe_path,
350-
"clang",
351-
"-x",
352-
"c",
353-
def_file_path,
354-
"-Wp,-w",
355-
"-undef",
356-
"-P",
357-
"-I",
358-
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "def-include" }),
359-
target_def_arg,
360-
"-E",
361-
"-o",
362-
def_final_path,
363-
};
345+
if (builtin.zig_backend == .stage2_c) @panic("the CBE cannot compile Aro yet!");
346+
const aro = @import("aro");
347+
var aro_comp = aro.Compilation.init(comp.gpa);
348+
defer aro_comp.deinit();
364349

365-
if (comp.verbose_cc) {
366-
Compilation.dump_argv(&args);
350+
const include_dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "def-include" });
351+
352+
if (comp.verbose_cc) print: {
353+
std.debug.getStderrMutex().lock();
354+
defer std.debug.getStderrMutex().unlock();
355+
const stderr = std.io.getStdErr().writer();
356+
nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print;
357+
nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print;
358+
nosuspend stderr.print("output path: {s}\n", .{def_final_path}) catch break :print;
367359
}
368360

369-
if (std.process.can_spawn) {
370-
var child = std.ChildProcess.init(&args, arena);
371-
child.stdin_behavior = .Ignore;
372-
child.stdout_behavior = .Pipe;
373-
child.stderr_behavior = .Pipe;
374-
375-
try child.spawn();
376-
377-
const stderr = try child.stderr.?.reader().readAllAlloc(arena, std.math.maxInt(usize));
378-
379-
const term = child.wait() catch |err| {
380-
// TODO surface a proper error here
381-
log.err("unable to spawn {s}: {s}", .{ args[0], @errorName(err) });
382-
return error.ClangPreprocessorFailed;
383-
};
384-
switch (term) {
385-
.Exited => |code| {
386-
if (code != 0) {
387-
// TODO surface a proper error here
388-
log.err("clang exited with code {d} and stderr: {s}", .{ code, stderr });
389-
return error.ClangPreprocessorFailed;
390-
}
391-
},
392-
else => {
393-
// TODO surface a proper error here
394-
log.err("clang terminated unexpectedly with stderr: {s}", .{stderr});
395-
return error.ClangPreprocessorFailed;
396-
},
361+
try aro_comp.include_dirs.append(include_dir);
362+
363+
const builtin_macros = try aro_comp.generateBuiltinMacros();
364+
const user_macros = try aro_comp.addSourceFromBuffer("<command line>", target_defines);
365+
const def_file_source = try aro_comp.addSourceFromPath(def_file_path);
366+
367+
var pp = aro.Preprocessor.init(&aro_comp);
368+
defer pp.deinit();
369+
pp.linemarkers = .none;
370+
pp.preserve_whitespace = true;
371+
372+
_ = try pp.preprocess(builtin_macros);
373+
_ = try pp.preprocess(user_macros);
374+
const eof = try pp.preprocess(def_file_source);
375+
try pp.tokens.append(pp.comp.gpa, eof);
376+
377+
for (aro_comp.diag.list.items) |diagnostic| {
378+
if (diagnostic.kind == .@"fatal error" or diagnostic.kind == .@"error") {
379+
aro_comp.renderErrors();
380+
return error.AroPreprocessorFailed;
397381
}
398-
} else {
399-
log.err("unable to spawn {s}: spawning child process not supported on {s}", .{ args[0], @tagName(builtin.os.tag) });
400-
return error.ClangPreprocessorFailed;
382+
}
383+
384+
{
385+
// new scope to ensure definition file is written before passing the path to WriteImportLibrary
386+
const def_final_file = try comp.global_cache_directory.handle.createFile(def_final_path, .{ .truncate = true });
387+
defer def_final_file.close();
388+
try pp.prettyPrintTokens(def_final_file.writer());
401389
}
402390

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

396+
if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;
408397
const llvm_bindings = @import("codegen/llvm/bindings.zig");
409398
const llvm = @import("codegen/llvm.zig");
410399
const arch_tag = llvm.targetArch(target.cpu.arch);

0 commit comments

Comments
 (0)