| ... | @@ -288,10 +288,6 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -288,10 +288,6 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 288 | else => |e| return e, | 288 | else => |e| return e, |
| 289 | }; | 289 | }; |
| 290 | | 290 | |
| 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 | | | |
| 295 | const target = comp.getTarget(); | 291 | const target = comp.getTarget(); |
| 296 | | 292 | |
| 297 | var cache: Cache = .{ | 293 | var cache: Cache = .{ |
| ... | @@ -305,6 +301,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -305,6 +301,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 305 | cache.hash.addBytes(build_options.version); | 301 | cache.hash.addBytes(build_options.version); |
| 306 | cache.hash.addOptionalBytes(comp.zig_lib_directory.path); | 302 | cache.hash.addOptionalBytes(comp.zig_lib_directory.path); |
| 307 | cache.hash.add(target.cpu.arch); | 303 | cache.hash.add(target.cpu.arch); |
| | 304 | cache.hash.addBytes("aro"); |
| 308 | | 305 | |
| 309 | var man = cache.obtain(); | 306 | var man = cache.obtain(); |
| 310 | defer man.deinit(); | 307 | defer man.deinit(); |
| ... | @@ -337,67 +334,58 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -337,67 +334,58 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 337 | "o", &digest, final_def_basename, | 334 | "o", &digest, final_def_basename, |
| 338 | }); | 335 | }); |
| 339 | | 336 | |
| 340 | const target_def_arg = switch (target.cpu.arch) { | 337 | const target_defines = switch (target.cpu.arch) { |
| 341 | .x86 => "-DDEF_I386", | 338 | .x86 => "#define DEF_I386\n", |
| 342 | .x86_64 => "-DDEF_X64", | 339 | .x86_64 => "#define DEF_X64\n", |
| 343 | .arm, .armeb, .thumb, .thumbeb, .aarch64_32 => "-DDEF_ARM32", | 340 | .arm, .armeb, .thumb, .thumbeb, .aarch64_32 => "#define DEF_ARM32\n", |
| 344 | .aarch64, .aarch64_be => "-DDEF_ARM64", | 341 | .aarch64, .aarch64_be => "#define DEF_ARM64\n", |
| 345 | else => unreachable, | 342 | else => unreachable, |
| 346 | }; | 343 | }; |
| 347 | | 344 | |
| 348 | const args = [_][]const u8{ | 345 | if (builtin.zig_backend == .stage2_c) @panic("the CBE cannot compile Aro yet!"); |
| 349 | self_exe_path, | 346 | const aro = @import("aro"); |
| 350 | "clang", | 347 | var aro_comp = aro.Compilation.init(comp.gpa); |
| 351 | "-x", | 348 | defer aro_comp.deinit(); |
| 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 | }; | | |
| 364 | | 349 | |
| 365 | if (comp.verbose_cc) { | 350 | const include_dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "def-include" }); |
| 366 | Compilation.dump_argv(&args); | 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; |
| 367 | } | 359 | } |
| 368 | | 360 | |
| 369 | if (std.process.can_spawn) { | 361 | try aro_comp.include_dirs.append(include_dir); |
| 370 | var child = std.ChildProcess.init(&args, arena); | 362 | |
| 371 | child.stdin_behavior = .Ignore; | 363 | const builtin_macros = try aro_comp.generateBuiltinMacros(); |
| 372 | child.stdout_behavior = .Pipe; | 364 | const user_macros = try aro_comp.addSourceFromBuffer("<command line>", target_defines); |
| 373 | child.stderr_behavior = .Pipe; | 365 | const def_file_source = try aro_comp.addSourceFromPath(def_file_path); |
| 374 | | 366 | |
| 375 | try child.spawn(); | 367 | var pp = aro.Preprocessor.init(&aro_comp); |
| 376 | | 368 | defer pp.deinit(); |
| 377 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, std.math.maxInt(usize)); | 369 | pp.linemarkers = .none; |
| 378 | | 370 | pp.preserve_whitespace = true; |
| 379 | const term = child.wait() catch |err| { | 371 | |
| 380 | // TODO surface a proper error here | 372 | _ = try pp.preprocess(builtin_macros); |
| 381 | log.err("unable to spawn {s}: {s}", .{ args[0], @errorName(err) }); | 373 | _ = try pp.preprocess(user_macros); |
| 382 | return error.ClangPreprocessorFailed; | 374 | const eof = try pp.preprocess(def_file_source); |
| 383 | }; | 375 | try pp.tokens.append(pp.comp.gpa, eof); |
| 384 | switch (term) { | 376 | |
| 385 | .Exited => |code| { | 377 | for (aro_comp.diag.list.items) |diagnostic| { |
| 386 | if (code != 0) { | 378 | if (diagnostic.kind == .@"fatal error" or diagnostic.kind == .@"error") { |
| 387 | // TODO surface a proper error here | 379 | aro_comp.renderErrors(); |
| 388 | log.err("clang exited with code {d} and stderr: {s}", .{ code, stderr }); | 380 | return error.AroPreprocessorFailed; |
| 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 | }, | | |
| 397 | } | 381 | } |
| 398 | } else { | 382 | } |
| 399 | log.err("unable to spawn {s}: spawning child process not supported on {s}", .{ args[0], @tagName(builtin.os.tag) }); | 383 | |
| 400 | return error.ClangPreprocessorFailed; | 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()); |
| 401 | } | 389 | } |
| 402 | | 390 | |
| 403 | const lib_final_path = try comp.global_cache_directory.join(comp.gpa, &[_][]const u8{ | 391 | const lib_final_path = try comp.global_cache_directory.join(comp.gpa, &[_][]const u8{ |
| ... | @@ -405,6 +393,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -405,6 +393,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 405 | }); | 393 | }); |
| 406 | errdefer comp.gpa.free(lib_final_path); | 394 | errdefer comp.gpa.free(lib_final_path); |
| 407 | | 395 | |
| | 396 | if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions; |
| 408 | const llvm_bindings = @import("codegen/llvm/bindings.zig"); | 397 | const llvm_bindings = @import("codegen/llvm/bindings.zig"); |
| 409 | const llvm = @import("codegen/llvm.zig"); | 398 | const llvm = @import("codegen/llvm.zig"); |
| 410 | const arch_tag = llvm.targetArch(target.cpu.arch); | 399 | const arch_tag = llvm.targetArch(target.cpu.arch); |