| author | |
| committer | |
| log | 6af2990549709ec5e2bc1efeb5090a944f1a8bdf |
| tree | c4dc51ddde68c2842b6450bd6dee6432e2226bde |
| parent | a337046832b936d912b6902e331cb58bdc513a2d |
These CLI options are now forwarded to the stage1 backend.
We're not going to support the -mllvm CLI option any longer. As a
compromise, we unconditionally tell LLVM to output intel x86 syntax when
using -femit-asm.
Simplify stage1 logic; it no longer has the concept of an output
directory. --output-dir is no longer a valid CLI option. cmake uses
the `-femit-bin=[path]` option.
Note the changes to test/cli.zig. This breaks the CLI API that Godbolt
is using so we're going to want to open a PR to help them upgrade to the
new CLI for the upcoming Zig 0.7.0 release.12 files changed, 263 insertions(+), 158 deletions(-)
BRANCH_TODO+4-9| ... | ... | @@ -1,13 +1,7 @@ |
| 1 | * support -fno-emit-bin for godbolt | |
| 1 | 2 | * tests passing with -Dskip-non-native |
| 2 | 3 | * `-ftime-report` |
| 3 | 4 | * -fstack-report print stack size diagnostics\n" |
| 4 | * -fdump-analysis write analysis.json file with type information\n" | |
| 5 | * -femit-docs create a docs/ dir with html documentation\n" | |
| 6 | * -fno-emit-docs do not produce docs/ dir with html documentation\n" | |
| 7 | * -femit-asm output .s (assembly code)\n" | |
| 8 | * -fno-emit-asm (default) do not output .s (assembly code)\n" | |
| 9 | * -femit-llvm-ir produce a .ll file with LLVM IR\n" | |
| 10 | * -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n" | |
| 11 | 5 | * mingw-w64 |
| 12 | 6 | * MachO LLD linking |
| 13 | 7 | * COFF LLD linking |
| ... | ... | @@ -17,8 +11,8 @@ |
| 17 | 11 | * On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process. |
| 18 | 12 | * restore error messages for stage2_add_link_lib |
| 19 | 13 | * windows CUSTOMBUILD : error : unable to build compiler_rt: FileNotFound [D:\a\1\s\build\zig_install_lib_files.vcxproj] |
| 20 | * try building some software with zig cc | |
| 21 | * implement support for -femit-asm | |
| 14 | * try building some software with zig cc to make sure it didn't regress | |
| 15 | * restore the legacy -femit-h feature using the stage1 backend | |
| 22 | 16 | |
| 23 | 17 | * implement proper parsing of clang stderr/stdout and exposing compile errors with the Compilation API |
| 24 | 18 | * implement proper parsing of LLD stderr/stdout and exposing compile errors with the Compilation API |
| ... | ... | @@ -56,3 +50,4 @@ |
| 56 | 50 | * make std.Progress support multithreaded |
| 57 | 51 | * update musl.zig static data to use native path separator in static data rather than replacing '/' at runtime |
| 58 | 52 | * linking hello world with LLD, lld is silently calling exit(1) instead of reporting ok=false. when run standalone the error message is: ld.lld: error: section [index 3] has a sh_offset (0x57000) + sh_size (0x68) that is greater than the file size (0x57060) |
| 53 | * submit PR to godbolt and update the CLI options (see changes to test/cli.zig) |
CMakeLists.txt+3-3| ... | ... | @@ -449,7 +449,7 @@ endif() |
| 449 | 449 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") |
| 450 | 450 | set(ZIG1_RELEASE_ARG "") |
| 451 | 451 | else() |
| 452 | set(ZIG1_RELEASE_ARG --release-fast --strip) | |
| 452 | set(ZIG1_RELEASE_ARG -OReleaseFast --strip) | |
| 453 | 453 | endif() |
| 454 | 454 | |
| 455 | 455 | set(BUILD_ZIG1_ARGS |
| ... | ... | @@ -458,8 +458,8 @@ set(BUILD_ZIG1_ARGS |
| 458 | 458 | "-mcpu=${ZIG_TARGET_MCPU}" |
| 459 | 459 | --name zig1 |
| 460 | 460 | --override-lib-dir "${CMAKE_SOURCE_DIR}/lib" |
| 461 | --output-dir "${CMAKE_BINARY_DIR}" | |
| 462 | ${ZIG1_RELEASE_ARG} | |
| 461 | "-femit-bin=${ZIG1_OBJECT}" | |
| 462 | "${ZIG1_RELEASE_ARG}" | |
| 463 | 463 | -lc |
| 464 | 464 | --pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}" |
| 465 | 465 | --pkg-end |
src/Compilation.zig+54-14| ... | ... | @@ -107,6 +107,12 @@ test_filter: ?[]const u8, |
| 107 | 107 | test_name_prefix: ?[]const u8, |
| 108 | 108 | test_evented_io: bool, |
| 109 | 109 | |
| 110 | emit_h: ?EmitLoc, | |
| 111 | emit_asm: ?EmitLoc, | |
| 112 | emit_llvm_ir: ?EmitLoc, | |
| 113 | emit_analysis: ?EmitLoc, | |
| 114 | emit_docs: ?EmitLoc, | |
| 115 | ||
| 110 | 116 | pub const InnerError = Module.InnerError; |
| 111 | 117 | |
| 112 | 118 | pub const CRTFile = struct { |
| ... | ... | @@ -296,6 +302,12 @@ pub const InitOptions = struct { |
| 296 | 302 | emit_h: ?EmitLoc = null, |
| 297 | 303 | /// `null` means to not emit assembly. |
| 298 | 304 | emit_asm: ?EmitLoc = null, |
| 305 | /// `null` means to not emit LLVM IR. | |
| 306 | emit_llvm_ir: ?EmitLoc = null, | |
| 307 | /// `null` means to not emit semantic analysis JSON. | |
| 308 | emit_analysis: ?EmitLoc = null, | |
| 309 | /// `null` means to not emit docs. | |
| 310 | emit_docs: ?EmitLoc = null, | |
| 299 | 311 | link_mode: ?std.builtin.LinkMode = null, |
| 300 | 312 | dll_export_fns: ?bool = false, |
| 301 | 313 | /// Normally when using LLD to link, Zig uses a file named "lld.id" in the |
| ... | ... | @@ -442,7 +454,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 442 | 454 | break :blk false; |
| 443 | 455 | }; |
| 444 | 456 | |
| 445 | ||
| 446 | 457 | const link_libc = options.link_libc or |
| 447 | 458 | (is_exe_or_dyn_lib and target_util.osRequiresLibC(options.target)); |
| 448 | 459 | |
| ... | ... | @@ -489,9 +500,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 489 | 500 | break :pic explicit; |
| 490 | 501 | } else must_pic; |
| 491 | 502 | |
| 492 | if (options.emit_h != null) fatal("-femit-h not supported yet", .{}); // TODO | |
| 493 | if (options.emit_asm != null) fatal("-femit-asm not supported yet", .{}); // TODO | |
| 494 | ||
| 495 | 503 | const emit_bin = options.emit_bin orelse fatal("-fno-emit-bin not supported yet", .{}); // TODO |
| 496 | 504 | |
| 497 | 505 | // Make a decision on whether to use Clang for translate-c and compiling C files. |
| ... | ... | @@ -579,6 +587,12 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 579 | 587 | cache.hash.add(options.link_libcpp); |
| 580 | 588 | cache.hash.add(options.output_mode); |
| 581 | 589 | cache.hash.add(options.machine_code_model); |
| 590 | cache.hash.add(options.emit_bin != null); | |
| 591 | cache.hash.add(options.emit_h != null); | |
| 592 | cache.hash.add(options.emit_asm != null); | |
| 593 | cache.hash.add(options.emit_llvm_ir != null); | |
| 594 | cache.hash.add(options.emit_analysis != null); | |
| 595 | cache.hash.add(options.emit_docs != null); | |
| 582 | 596 | // TODO audit this and make sure everything is in it |
| 583 | 597 | |
| 584 | 598 | const module: ?*Module = if (options.root_pkg) |root_pkg| blk: { |
| ... | ... | @@ -752,6 +766,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 752 | 766 | .local_cache_directory = options.local_cache_directory, |
| 753 | 767 | .global_cache_directory = options.global_cache_directory, |
| 754 | 768 | .bin_file = bin_file, |
| 769 | .emit_h = options.emit_h, | |
| 770 | .emit_asm = options.emit_asm, | |
| 771 | .emit_llvm_ir = options.emit_llvm_ir, | |
| 772 | .emit_analysis = options.emit_analysis, | |
| 773 | .emit_docs = options.emit_docs, | |
| 755 | 774 | .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa), |
| 756 | 775 | .keep_source_files_loaded = options.keep_source_files_loaded, |
| 757 | 776 | .use_clang = use_clang, |
| ... | ... | @@ -1450,8 +1469,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 1450 | 1469 | |
| 1451 | 1470 | try argv.ensureCapacity(argv.items.len + 3); |
| 1452 | 1471 | switch (comp.clang_preprocessor_mode) { |
| 1453 | .no => argv.appendSliceAssumeCapacity(&[_][]const u8{"-c", "-o", out_obj_path}), | |
| 1454 | .yes => argv.appendSliceAssumeCapacity(&[_][]const u8{"-E", "-o", out_obj_path}), | |
| 1472 | .no => argv.appendSliceAssumeCapacity(&[_][]const u8{ "-c", "-o", out_obj_path }), | |
| 1473 | .yes => argv.appendSliceAssumeCapacity(&[_][]const u8{ "-E", "-o", out_obj_path }), | |
| 1455 | 1474 | .stdout => argv.appendAssumeCapacity("-E"), |
| 1456 | 1475 | } |
| 1457 | 1476 | |
| ... | ... | @@ -2498,15 +2517,35 @@ fn updateStage1Module(comp: *Compilation) !void { |
| 2498 | 2517 | comp.is_test, |
| 2499 | 2518 | ) orelse return error.OutOfMemory; |
| 2500 | 2519 | |
| 2520 | const bin_basename = try std.zig.binNameAlloc(arena, .{ | |
| 2521 | .root_name = comp.bin_file.options.root_name, | |
| 2522 | .target = target, | |
| 2523 | .output_mode = .Obj, | |
| 2524 | }); | |
| 2525 | const emit_bin_path = try directory.join(arena, &[_][]const u8{bin_basename}); | |
| 2526 | const emit_h_path = try stage1LocPath(arena, comp.emit_h, directory); | |
| 2527 | const emit_asm_path = try stage1LocPath(arena, comp.emit_asm, directory); | |
| 2528 | const emit_llvm_ir_path = try stage1LocPath(arena, comp.emit_llvm_ir, directory); | |
| 2529 | const emit_analysis_path = try stage1LocPath(arena, comp.emit_analysis, directory); | |
| 2530 | const emit_docs_path = try stage1LocPath(arena, comp.emit_docs, directory); | |
| 2501 | 2531 | const stage1_pkg = try createStage1Pkg(arena, "root", mod.root_pkg, null); |
| 2502 | const output_dir = directory.path orelse "."; | |
| 2503 | 2532 | const test_filter = comp.test_filter orelse ""[0..0]; |
| 2504 | 2533 | const test_name_prefix = comp.test_name_prefix orelse ""[0..0]; |
| 2505 | 2534 | stage1_module.* = .{ |
| 2506 | 2535 | .root_name_ptr = comp.bin_file.options.root_name.ptr, |
| 2507 | 2536 | .root_name_len = comp.bin_file.options.root_name.len, |
| 2508 | .output_dir_ptr = output_dir.ptr, | |
| 2509 | .output_dir_len = output_dir.len, | |
| 2537 | .emit_o_ptr = emit_bin_path.ptr, | |
| 2538 | .emit_o_len = emit_bin_path.len, | |
| 2539 | .emit_h_ptr = emit_h_path.ptr, | |
| 2540 | .emit_h_len = emit_h_path.len, | |
| 2541 | .emit_asm_ptr = emit_asm_path.ptr, | |
| 2542 | .emit_asm_len = emit_asm_path.len, | |
| 2543 | .emit_llvm_ir_ptr = emit_llvm_ir_path.ptr, | |
| 2544 | .emit_llvm_ir_len = emit_llvm_ir_path.len, | |
| 2545 | .emit_analysis_json_ptr = emit_analysis_path.ptr, | |
| 2546 | .emit_analysis_json_len = emit_analysis_path.len, | |
| 2547 | .emit_docs_ptr = emit_docs_path.ptr, | |
| 2548 | .emit_docs_len = emit_docs_path.len, | |
| 2510 | 2549 | .builtin_zig_path_ptr = builtin_zig_path.ptr, |
| 2511 | 2550 | .builtin_zig_path_len = builtin_zig_path.len, |
| 2512 | 2551 | .test_filter_ptr = test_filter.ptr, |
| ... | ... | @@ -2530,11 +2569,6 @@ fn updateStage1Module(comp: *Compilation) !void { |
| 2530 | 2569 | .enable_stack_probing = comp.bin_file.options.stack_check, |
| 2531 | 2570 | .enable_time_report = comp.time_report, |
| 2532 | 2571 | .enable_stack_report = false, |
| 2533 | .dump_analysis = false, | |
| 2534 | .enable_doc_generation = false, | |
| 2535 | .emit_bin = true, | |
| 2536 | .emit_asm = false, | |
| 2537 | .emit_llvm_ir = false, | |
| 2538 | 2572 | .test_is_evented = comp.test_evented_io, |
| 2539 | 2573 | .verbose_tokenize = comp.verbose_tokenize, |
| 2540 | 2574 | .verbose_ast = comp.verbose_ast, |
| ... | ... | @@ -2565,6 +2599,12 @@ fn updateStage1Module(comp: *Compilation) !void { |
| 2565 | 2599 | comp.stage1_lock = man.toOwnedLock(); |
| 2566 | 2600 | } |
| 2567 | 2601 | |
| 2602 | fn stage1LocPath(arena: *Allocator, opt_loc: ?EmitLoc, cache_directory: Directory) ![]const u8 { | |
| 2603 | const loc = opt_loc orelse return ""; | |
| 2604 | const directory = loc.directory orelse cache_directory; | |
| 2605 | return directory.join(arena, &[_][]const u8{loc.basename}); | |
| 2606 | } | |
| 2607 | ||
| 2568 | 2608 | fn createStage1Pkg( |
| 2569 | 2609 | arena: *Allocator, |
| 2570 | 2610 | name: []const u8, |
src/llvm.zig+3| ... | ... | @@ -72,3 +72,6 @@ pub const OSType = extern enum(c_int) { |
| 72 | 72 | WASI = 34, |
| 73 | 73 | Emscripten = 35, |
| 74 | 74 | }; |
| 75 | ||
| 76 | pub const ParseCommandLineOptions = ZigLLVMParseCommandLineOptions; | |
| 77 | extern fn ZigLLVMParseCommandLineOptions(argc: usize, argv: [*]const [*:0]const u8) void; |
src/main.zig+122-35| ... | ... | @@ -195,8 +195,20 @@ const usage_build_generic = |
| 195 | 195 | \\ -h, --help Print this help and exit |
| 196 | 196 | \\ --watch Enable compiler REPL |
| 197 | 197 | \\ --color [auto|off|on] Enable or disable colored error messages |
| 198 | \\ -femit-bin[=path] (default) output machine code | |
| 198 | \\ -femit-bin[=path] (default) Output machine code | |
| 199 | 199 | \\ -fno-emit-bin Do not output machine code |
| 200 | \\ -femit-asm[=path] Output .s (assembly code) | |
| 201 | \\ -fno-emit-asm (default) Do not output .s (assembly code) | |
| 202 | \\ -femit-zir[=path] Produce a .zir file with Zig IR | |
| 203 | \\ -fno-emit-zir (default) Do not produce a .zir file with Zig IR | |
| 204 | \\ -femit-llvm-ir[=path] Produce a .ll file with LLVM IR (requires LLVM extensions) | |
| 205 | \\ -fno-emit-llvm-ir (default) Do not produce a .ll file with LLVM IR | |
| 206 | \\ -femit-h[=path] Generate a C header file (.h) | |
| 207 | \\ -fno-emit-h (default) Do not generate a C header file (.h) | |
| 208 | \\ -femit-docs[=path] Create a docs/ dir with html documentation | |
| 209 | \\ -fno-emit-docs (default) Do not produce docs/ dir with html documentation | |
| 210 | \\ -femit-analysis[=path] Write analysis JSON file with type information | |
| 211 | \\ -fno-emit-analysis (default) Do not write analysis JSON file with type information | |
| 200 | 212 | \\ --show-builtin Output the source of @import("builtin") then exit |
| 201 | 213 | \\ --cache-dir [path] Override the local cache directory |
| 202 | 214 | \\ --global-cache-dir [path] Override the global cache directory |
| ... | ... | @@ -210,10 +222,11 @@ const usage_build_generic = |
| 210 | 222 | \\ small|kernel| |
| 211 | 223 | \\ medium|large] |
| 212 | 224 | \\ --name [name] Override root name (not a file path) |
| 213 | \\ -ODebug (default) optimizations off, safety on | |
| 214 | \\ -OReleaseFast Optimizations on, safety off | |
| 215 | \\ -OReleaseSafe Optimizations on, safety on | |
| 216 | \\ -OReleaseSmall Optimize for small binary, safety off | |
| 225 | \\ -O [mode] Choose what to optimize for | |
| 226 | \\ Debug (default) Optimizations off, safety on | |
| 227 | \\ ReleaseFast Optimizations on, safety off | |
| 228 | \\ ReleaseSafe Optimizations on, safety on | |
| 229 | \\ ReleaseSmall Optimize for small binary, safety off | |
| 217 | 230 | \\ --pkg-begin [name] [path] Make pkg available to import and push current pkg |
| 218 | 231 | \\ --pkg-end Pop current pkg |
| 219 | 232 | \\ --main-pkg-path Set the directory of the root package |
| ... | ... | @@ -290,9 +303,57 @@ const Emit = union(enum) { |
| 290 | 303 | no, |
| 291 | 304 | yes_default_path, |
| 292 | 305 | yes: []const u8, |
| 306 | ||
| 307 | const Resolved = struct { | |
| 308 | data: ?Compilation.EmitLoc, | |
| 309 | dir: ?fs.Dir, | |
| 310 | ||
| 311 | fn deinit(self: *Resolved) void { | |
| 312 | if (self.dir) |*dir| { | |
| 313 | dir.close(); | |
| 314 | } | |
| 315 | } | |
| 316 | }; | |
| 317 | ||
| 318 | fn resolve(emit: Emit, default_basename: []const u8) !Resolved { | |
| 319 | var resolved: Resolved = .{ .data = null, .dir = null }; | |
| 320 | errdefer resolved.deinit(); | |
| 321 | ||
| 322 | switch (emit) { | |
| 323 | .no => {}, | |
| 324 | .yes_default_path => { | |
| 325 | resolved.data = Compilation.EmitLoc{ | |
| 326 | .directory = .{ .path = null, .handle = fs.cwd() }, | |
| 327 | .basename = default_basename, | |
| 328 | }; | |
| 329 | }, | |
| 330 | .yes => |full_path| { | |
| 331 | const basename = fs.path.basename(full_path); | |
| 332 | if (fs.path.dirname(full_path)) |dirname| { | |
| 333 | const handle = try fs.cwd().openDir(dirname, .{}); | |
| 334 | resolved = .{ | |
| 335 | .dir = handle, | |
| 336 | .data = Compilation.EmitLoc{ | |
| 337 | .basename = basename, | |
| 338 | .directory = .{ | |
| 339 | .path = dirname, | |
| 340 | .handle = handle, | |
| 341 | }, | |
| 342 | }, | |
| 343 | }; | |
| 344 | } else { | |
| 345 | resolved.data = Compilation.EmitLoc{ | |
| 346 | .basename = basename, | |
| 347 | .directory = .{ .path = null, .handle = fs.cwd() }, | |
| 348 | }; | |
| 349 | } | |
| 350 | }, | |
| 351 | } | |
| 352 | return resolved; | |
| 353 | } | |
| 293 | 354 | }; |
| 294 | 355 | |
| 295 | pub fn buildOutputType( | |
| 356 | fn buildOutputType( | |
| 296 | 357 | gpa: *Allocator, |
| 297 | 358 | arena: *Allocator, |
| 298 | 359 | all_args: []const []const u8, |
| ... | ... | @@ -328,7 +389,10 @@ pub fn buildOutputType( |
| 328 | 389 | var show_builtin = false; |
| 329 | 390 | var emit_bin: Emit = .yes_default_path; |
| 330 | 391 | var emit_asm: Emit = .no; |
| 392 | var emit_llvm_ir: Emit = .no; | |
| 331 | 393 | var emit_zir: Emit = .no; |
| 394 | var emit_docs: Emit = .no; | |
| 395 | var emit_analysis: Emit = .no; | |
| 332 | 396 | var target_arch_os_abi: []const u8 = "native"; |
| 333 | 397 | var target_mcpu: ?[]const u8 = null; |
| 334 | 398 | var target_dynamic_linker: ?[]const u8 = null; |
| ... | ... | @@ -667,6 +731,30 @@ pub fn buildOutputType( |
| 667 | 731 | emit_h = .{ .yes = arg["-femit-h=".len..] }; |
| 668 | 732 | } else if (mem.eql(u8, arg, "-fno-emit-h")) { |
| 669 | 733 | emit_h = .no; |
| 734 | } else if (mem.eql(u8, arg, "-femit-asm")) { | |
| 735 | emit_asm = .yes_default_path; | |
| 736 | } else if (mem.startsWith(u8, arg, "-femit-asm=")) { | |
| 737 | emit_asm = .{ .yes = arg["-femit-asm=".len..] }; | |
| 738 | } else if (mem.eql(u8, arg, "-fno-emit-asm")) { | |
| 739 | emit_asm = .no; | |
| 740 | } else if (mem.eql(u8, arg, "-femit-llvm-ir")) { | |
| 741 | emit_llvm_ir = .yes_default_path; | |
| 742 | } else if (mem.startsWith(u8, arg, "-femit-llvm-ir=")) { | |
| 743 | emit_llvm_ir = .{ .yes = arg["-femit-llvm-ir=".len..] }; | |
| 744 | } else if (mem.eql(u8, arg, "-fno-emit-llvm-ir")) { | |
| 745 | emit_llvm_ir = .no; | |
| 746 | } else if (mem.eql(u8, arg, "-femit-docs")) { | |
| 747 | emit_docs = .yes_default_path; | |
| 748 | } else if (mem.startsWith(u8, arg, "-femit-docs=")) { | |
| 749 | emit_docs = .{ .yes = arg["-femit-docs=".len..] }; | |
| 750 | } else if (mem.eql(u8, arg, "-fno-emit-docs")) { | |
| 751 | emit_docs = .no; | |
| 752 | } else if (mem.eql(u8, arg, "-femit-analysis")) { | |
| 753 | emit_analysis = .yes_default_path; | |
| 754 | } else if (mem.startsWith(u8, arg, "-femit-analysis=")) { | |
| 755 | emit_analysis = .{ .yes = arg["-femit-analysis=".len..] }; | |
| 756 | } else if (mem.eql(u8, arg, "-fno-emit-analysis")) { | |
| 757 | emit_analysis = .no; | |
| 670 | 758 | } else if (mem.eql(u8, arg, "-dynamic")) { |
| 671 | 759 | link_mode = .Dynamic; |
| 672 | 760 | } else if (mem.eql(u8, arg, "-static")) { |
| ... | ... | @@ -1237,35 +1325,24 @@ pub fn buildOutputType( |
| 1237 | 1325 | }, |
| 1238 | 1326 | }; |
| 1239 | 1327 | |
| 1240 | var cleanup_emit_h_dir: ?fs.Dir = null; | |
| 1241 | defer if (cleanup_emit_h_dir) |*dir| dir.close(); | |
| 1328 | const default_h_basename = try std.fmt.allocPrint(arena, "{}.h", .{root_name}); | |
| 1329 | var emit_h_resolved = try emit_h.resolve(default_h_basename); | |
| 1330 | defer emit_h_resolved.deinit(); | |
| 1242 | 1331 | |
| 1243 | const emit_h_loc: ?Compilation.EmitLoc = switch (emit_h) { | |
| 1244 | .no => null, | |
| 1245 | .yes_default_path => Compilation.EmitLoc{ | |
| 1246 | .directory = .{ .path = null, .handle = fs.cwd() }, | |
| 1247 | .basename = try std.fmt.allocPrint(arena, "{}.h", .{root_name}), | |
| 1248 | }, | |
| 1249 | .yes => |full_path| b: { | |
| 1250 | const basename = fs.path.basename(full_path); | |
| 1251 | if (fs.path.dirname(full_path)) |dirname| { | |
| 1252 | const handle = try fs.cwd().openDir(dirname, .{}); | |
| 1253 | cleanup_emit_h_dir = handle; | |
| 1254 | break :b Compilation.EmitLoc{ | |
| 1255 | .basename = basename, | |
| 1256 | .directory = .{ | |
| 1257 | .path = dirname, | |
| 1258 | .handle = handle, | |
| 1259 | }, | |
| 1260 | }; | |
| 1261 | } else { | |
| 1262 | break :b Compilation.EmitLoc{ | |
| 1263 | .basename = basename, | |
| 1264 | .directory = .{ .path = null, .handle = fs.cwd() }, | |
| 1265 | }; | |
| 1266 | } | |
| 1267 | }, | |
| 1268 | }; | |
| 1332 | const default_asm_basename = try std.fmt.allocPrint(arena, "{}.s", .{root_name}); | |
| 1333 | var emit_asm_resolved = try emit_asm.resolve(default_asm_basename); | |
| 1334 | defer emit_asm_resolved.deinit(); | |
| 1335 | ||
| 1336 | const default_llvm_ir_basename = try std.fmt.allocPrint(arena, "{}.ll", .{root_name}); | |
| 1337 | var emit_llvm_ir_resolved = try emit_llvm_ir.resolve(default_llvm_ir_basename); | |
| 1338 | defer emit_llvm_ir_resolved.deinit(); | |
| 1339 | ||
| 1340 | const default_analysis_basename = try std.fmt.allocPrint(arena, "{}-analysis.json", .{root_name}); | |
| 1341 | var emit_analysis_resolved = try emit_analysis.resolve(default_analysis_basename); | |
| 1342 | defer emit_analysis_resolved.deinit(); | |
| 1343 | ||
| 1344 | var emit_docs_resolved = try emit_docs.resolve("docs"); | |
| 1345 | defer emit_docs_resolved.deinit(); | |
| 1269 | 1346 | |
| 1270 | 1347 | const zir_out_path: ?[]const u8 = switch (emit_zir) { |
| 1271 | 1348 | .no => null, |
| ... | ... | @@ -1365,6 +1442,12 @@ pub fn buildOutputType( |
| 1365 | 1442 | }; |
| 1366 | 1443 | }; |
| 1367 | 1444 | |
| 1445 | if (build_options.have_llvm and emit_asm != .no) { | |
| 1446 | // LLVM has no way to set this non-globally. | |
| 1447 | const argv = [_][*:0]const u8{ "zig (LLVM option parsing)", "--x86-asm-syntax=intel" }; | |
| 1448 | @import("llvm.zig").ParseCommandLineOptions(argv.len, &argv); | |
| 1449 | } | |
| 1450 | ||
| 1368 | 1451 | gimmeMoreOfThoseSweetSweetFileDescriptors(); |
| 1369 | 1452 | |
| 1370 | 1453 | const comp = Compilation.create(gpa, .{ |
| ... | ... | @@ -1378,7 +1461,11 @@ pub fn buildOutputType( |
| 1378 | 1461 | .output_mode = output_mode, |
| 1379 | 1462 | .root_pkg = root_pkg, |
| 1380 | 1463 | .emit_bin = emit_bin_loc, |
| 1381 | .emit_h = emit_h_loc, | |
| 1464 | .emit_h = emit_h_resolved.data, | |
| 1465 | .emit_asm = emit_asm_resolved.data, | |
| 1466 | .emit_llvm_ir = emit_llvm_ir_resolved.data, | |
| 1467 | .emit_docs = emit_docs_resolved.data, | |
| 1468 | .emit_analysis = emit_analysis_resolved.data, | |
| 1382 | 1469 | .link_mode = link_mode, |
| 1383 | 1470 | .dll_export_fns = dll_export_fns, |
| 1384 | 1471 | .object_format = object_format, |
src/stage1.zig+12-7| ... | ... | @@ -75,8 +75,18 @@ pub const Pkg = extern struct { |
| 75 | 75 | pub const Module = extern struct { |
| 76 | 76 | root_name_ptr: [*]const u8, |
| 77 | 77 | root_name_len: usize, |
| 78 | output_dir_ptr: [*]const u8, | |
| 79 | output_dir_len: usize, | |
| 78 | emit_o_ptr: [*]const u8, | |
| 79 | emit_o_len: usize, | |
| 80 | emit_h_ptr: [*]const u8, | |
| 81 | emit_h_len: usize, | |
| 82 | emit_asm_ptr: [*]const u8, | |
| 83 | emit_asm_len: usize, | |
| 84 | emit_llvm_ir_ptr: [*]const u8, | |
| 85 | emit_llvm_ir_len: usize, | |
| 86 | emit_analysis_json_ptr: [*]const u8, | |
| 87 | emit_analysis_json_len: usize, | |
| 88 | emit_docs_ptr: [*]const u8, | |
| 89 | emit_docs_len: usize, | |
| 80 | 90 | builtin_zig_path_ptr: [*]const u8, |
| 81 | 91 | builtin_zig_path_len: usize, |
| 82 | 92 | test_filter_ptr: [*]const u8, |
| ... | ... | @@ -101,11 +111,6 @@ pub const Module = extern struct { |
| 101 | 111 | enable_stack_probing: bool, |
| 102 | 112 | enable_time_report: bool, |
| 103 | 113 | enable_stack_report: bool, |
| 104 | dump_analysis: bool, | |
| 105 | enable_doc_generation: bool, | |
| 106 | emit_bin: bool, | |
| 107 | emit_asm: bool, | |
| 108 | emit_llvm_ir: bool, | |
| 109 | 114 | test_is_evented: bool, |
| 110 | 115 | verbose_tokenize: bool, |
| 111 | 116 | verbose_ast: bool, |
src/stage1/all_types.hpp+3-8| ... | ... | @@ -2116,12 +2116,12 @@ struct CodeGen { |
| 2116 | 2116 | Buf llvm_triple_str; |
| 2117 | 2117 | Buf global_asm; |
| 2118 | 2118 | Buf o_file_output_path; |
| 2119 | Buf h_file_output_path; | |
| 2119 | 2120 | Buf asm_file_output_path; |
| 2120 | 2121 | Buf llvm_ir_file_output_path; |
| 2122 | Buf analysis_json_output_path; | |
| 2123 | Buf docs_output_path; | |
| 2121 | 2124 | Buf *cache_dir; |
| 2122 | // As an input parameter, mutually exclusive with enable_cache. But it gets | |
| 2123 | // populated in codegen_build_and_link. | |
| 2124 | Buf *output_dir; | |
| 2125 | 2125 | Buf *c_artifact_dir; |
| 2126 | 2126 | const char **libc_include_dir_list; |
| 2127 | 2127 | size_t libc_include_dir_len; |
| ... | ... | @@ -2186,11 +2186,6 @@ struct CodeGen { |
| 2186 | 2186 | bool dll_export_fns; |
| 2187 | 2187 | bool have_stack_probing; |
| 2188 | 2188 | bool function_sections; |
| 2189 | bool enable_dump_analysis; | |
| 2190 | bool enable_doc_generation; | |
| 2191 | bool emit_bin; | |
| 2192 | bool emit_asm; | |
| 2193 | bool emit_llvm_ir; | |
| 2194 | 2189 | bool test_is_evented; |
| 2195 | 2190 | bool valgrind_enabled; |
| 2196 | 2191 |
src/stage1/codegen.cpp+21-54| ... | ... | @@ -8243,9 +8243,9 @@ static void zig_llvm_emit_output(CodeGen *g) { |
| 8243 | 8243 | const char *bin_filename = nullptr; |
| 8244 | 8244 | const char *llvm_ir_filename = nullptr; |
| 8245 | 8245 | |
| 8246 | if (g->emit_bin) bin_filename = buf_ptr(&g->o_file_output_path); | |
| 8247 | if (g->emit_asm) asm_filename = buf_ptr(&g->asm_file_output_path); | |
| 8248 | if (g->emit_llvm_ir) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path); | |
| 8246 | if (buf_len(&g->o_file_output_path) != 0) bin_filename = buf_ptr(&g->o_file_output_path); | |
| 8247 | if (buf_len(&g->asm_file_output_path) != 0) asm_filename = buf_ptr(&g->asm_file_output_path); | |
| 8248 | if (buf_len(&g->llvm_ir_file_output_path) != 0) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path); | |
| 8249 | 8249 | |
| 8250 | 8250 | // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire |
| 8251 | 8251 | // pipeline multiple times if this is requested. |
| ... | ... | @@ -8858,8 +8858,10 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 8858 | 8858 | Buf *contents; |
| 8859 | 8859 | if (g->builtin_zig_path == nullptr) { |
| 8860 | 8860 | // Then this is zig0 building stage2. We can make many assumptions about the compilation. |
| 8861 | Buf *out_dir = buf_alloc(); | |
| 8862 | os_path_split(&g->o_file_output_path, out_dir, nullptr); | |
| 8861 | 8863 | g->builtin_zig_path = buf_alloc(); |
| 8862 | os_path_join(g->output_dir, buf_create_from_str(builtin_zig_basename), g->builtin_zig_path); | |
| 8864 | os_path_join(out_dir, buf_create_from_str(builtin_zig_basename), g->builtin_zig_path); | |
| 8863 | 8865 | |
| 8864 | 8866 | Buf *resolve_paths[] = { g->builtin_zig_path, }; |
| 8865 | 8867 | *g->builtin_zig_path = os_path_resolve(resolve_paths, 1); |
| ... | ... | @@ -8870,7 +8872,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 8870 | 8872 | exit(1); |
| 8871 | 8873 | } |
| 8872 | 8874 | |
| 8873 | g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin"); | |
| 8875 | g->compile_var_package = new_package(buf_ptr(out_dir), builtin_zig_basename, "builtin"); | |
| 8874 | 8876 | } else { |
| 8875 | 8877 | Buf *resolve_paths[] = { g->builtin_zig_path, }; |
| 8876 | 8878 | *g->builtin_zig_path = os_path_resolve(resolve_paths, 1); |
| ... | ... | @@ -9232,33 +9234,20 @@ void codegen_add_time_event(CodeGen *g, const char *name) { |
| 9232 | 9234 | g->timing_events.append({seconds, name}); |
| 9233 | 9235 | } |
| 9234 | 9236 | |
| 9235 | static void resolve_out_paths(CodeGen *g) { | |
| 9236 | assert(g->output_dir != nullptr); | |
| 9237 | assert(g->root_out_name != nullptr); | |
| 9237 | void codegen_build_object(CodeGen *g) { | |
| 9238 | g->have_err_ret_tracing = detect_err_ret_tracing(g); | |
| 9238 | 9239 | |
| 9239 | if (g->emit_bin) { | |
| 9240 | Buf *o_basename = buf_create_from_buf(g->root_out_name); | |
| 9241 | buf_append_str(o_basename, target_o_file_ext(g->zig_target)); | |
| 9242 | os_path_join(g->output_dir, o_basename, &g->o_file_output_path); | |
| 9243 | } | |
| 9244 | if (g->emit_asm) { | |
| 9245 | Buf *asm_basename = buf_create_from_buf(g->root_out_name); | |
| 9246 | const char *asm_ext = target_asm_file_ext(g->zig_target); | |
| 9247 | buf_append_str(asm_basename, asm_ext); | |
| 9248 | os_path_join(g->output_dir, asm_basename, &g->asm_file_output_path); | |
| 9249 | } | |
| 9250 | if (g->emit_llvm_ir) { | |
| 9251 | Buf *llvm_ir_basename = buf_create_from_buf(g->root_out_name); | |
| 9252 | const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target); | |
| 9253 | buf_append_str(llvm_ir_basename, llvm_ir_ext); | |
| 9254 | os_path_join(g->output_dir, llvm_ir_basename, &g->llvm_ir_file_output_path); | |
| 9255 | } | |
| 9256 | } | |
| 9240 | init(g); | |
| 9241 | ||
| 9242 | codegen_add_time_event(g, "Semantic Analysis"); | |
| 9243 | const char *progress_name = "Semantic Analysis"; | |
| 9244 | codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, | |
| 9245 | progress_name, strlen(progress_name), 0)); | |
| 9257 | 9246 | |
| 9258 | static void output_type_information(CodeGen *g) { | |
| 9259 | if (g->enable_dump_analysis) { | |
| 9260 | const char *analysis_json_filename = buf_ptr(buf_sprintf("%s" OS_SEP "%s-analysis.json", | |
| 9261 | buf_ptr(g->output_dir), buf_ptr(g->root_out_name))); | |
| 9247 | gen_root_source(g); | |
| 9248 | ||
| 9249 | if (buf_len(&g->analysis_json_output_path) != 0) { | |
| 9250 | const char *analysis_json_filename = buf_ptr(&g->analysis_json_output_path); | |
| 9262 | 9251 | FILE *f = fopen(analysis_json_filename, "wb"); |
| 9263 | 9252 | if (f == nullptr) { |
| 9264 | 9253 | fprintf(stderr, "Unable to open '%s': %s\n", analysis_json_filename, strerror(errno)); |
| ... | ... | @@ -9270,9 +9259,9 @@ static void output_type_information(CodeGen *g) { |
| 9270 | 9259 | exit(1); |
| 9271 | 9260 | } |
| 9272 | 9261 | } |
| 9273 | if (g->enable_doc_generation) { | |
| 9262 | if (buf_len(&g->docs_output_path) != 0) { | |
| 9274 | 9263 | Error err; |
| 9275 | Buf *doc_dir_path = buf_sprintf("%s" OS_SEP "docs", buf_ptr(g->output_dir)); | |
| 9264 | Buf *doc_dir_path = &g->docs_output_path; | |
| 9276 | 9265 | if ((err = os_make_path(doc_dir_path))) { |
| 9277 | 9266 | fprintf(stderr, "Unable to create directory %s: %s\n", buf_ptr(doc_dir_path), err_str(err)); |
| 9278 | 9267 | exit(1); |
| ... | ... | @@ -9308,27 +9297,6 @@ static void output_type_information(CodeGen *g) { |
| 9308 | 9297 | exit(1); |
| 9309 | 9298 | } |
| 9310 | 9299 | } |
| 9311 | } | |
| 9312 | ||
| 9313 | void codegen_build_object(CodeGen *g) { | |
| 9314 | assert(g->output_dir != nullptr); | |
| 9315 | ||
| 9316 | g->have_err_ret_tracing = detect_err_ret_tracing(g); | |
| 9317 | ||
| 9318 | init(g); | |
| 9319 | ||
| 9320 | codegen_add_time_event(g, "Semantic Analysis"); | |
| 9321 | const char *progress_name = "Semantic Analysis"; | |
| 9322 | codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, | |
| 9323 | progress_name, strlen(progress_name), 0)); | |
| 9324 | ||
| 9325 | gen_root_source(g); | |
| 9326 | ||
| 9327 | resolve_out_paths(g); | |
| 9328 | ||
| 9329 | if (g->enable_dump_analysis || g->enable_doc_generation) { | |
| 9330 | output_type_information(g); | |
| 9331 | } | |
| 9332 | 9300 | |
| 9333 | 9301 | codegen_add_time_event(g, "Code Generation"); |
| 9334 | 9302 | { |
| ... | ... | @@ -9379,7 +9347,6 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget |
| 9379 | 9347 | bool is_test_build) |
| 9380 | 9348 | { |
| 9381 | 9349 | CodeGen *g = heap::c_allocator.create<CodeGen>(); |
| 9382 | g->emit_bin = true; | |
| 9383 | 9350 | g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1"); |
| 9384 | 9351 | |
| 9385 | 9352 | g->subsystem = TargetSubsystemAuto; |
src/stage1/stage1.cpp+7-6| ... | ... | @@ -69,7 +69,13 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { |
| 69 | 69 | CodeGen *g = reinterpret_cast<CodeGen *>(stage1); |
| 70 | 70 | |
| 71 | 71 | g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len); |
| 72 | g->output_dir = buf_create_from_mem(stage1->output_dir_ptr, stage1->output_dir_len); | |
| 72 | buf_init_from_mem(&g->o_file_output_path, stage1->emit_o_ptr, stage1->emit_o_len); | |
| 73 | buf_init_from_mem(&g->h_file_output_path, stage1->emit_h_ptr, stage1->emit_h_len); | |
| 74 | buf_init_from_mem(&g->asm_file_output_path, stage1->emit_asm_ptr, stage1->emit_asm_len); | |
| 75 | buf_init_from_mem(&g->llvm_ir_file_output_path, stage1->emit_llvm_ir_ptr, stage1->emit_llvm_ir_len); | |
| 76 | buf_init_from_mem(&g->analysis_json_output_path, stage1->emit_analysis_json_ptr, stage1->emit_analysis_json_len); | |
| 77 | buf_init_from_mem(&g->docs_output_path, stage1->emit_docs_ptr, stage1->emit_docs_len); | |
| 78 | ||
| 73 | 79 | if (stage1->builtin_zig_path_len != 0) { |
| 74 | 80 | g->builtin_zig_path = buf_create_from_mem(stage1->builtin_zig_path_ptr, stage1->builtin_zig_path_len); |
| 75 | 81 | } |
| ... | ... | @@ -94,11 +100,6 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { |
| 94 | 100 | |
| 95 | 101 | g->enable_time_report = stage1->enable_time_report; |
| 96 | 102 | g->enable_stack_report = stage1->enable_stack_report; |
| 97 | g->enable_dump_analysis = stage1->dump_analysis; | |
| 98 | g->enable_doc_generation = stage1->enable_doc_generation; | |
| 99 | g->emit_bin = stage1->emit_bin; | |
| 100 | g->emit_asm = stage1->emit_asm; | |
| 101 | g->emit_llvm_ir = stage1->emit_llvm_ir; | |
| 102 | 103 | g->test_is_evented = stage1->test_is_evented; |
| 103 | 104 | |
| 104 | 105 | g->verbose_tokenize = stage1->verbose_tokenize; |
src/stage1/stage1.h+17-7| ... | ... | @@ -141,8 +141,23 @@ struct ZigStage1 { |
| 141 | 141 | const char *root_name_ptr; |
| 142 | 142 | size_t root_name_len; |
| 143 | 143 | |
| 144 | const char *output_dir_ptr; | |
| 145 | size_t output_dir_len; | |
| 144 | const char *emit_o_ptr; | |
| 145 | size_t emit_o_len; | |
| 146 | ||
| 147 | const char *emit_h_ptr; | |
| 148 | size_t emit_h_len; | |
| 149 | ||
| 150 | const char *emit_asm_ptr; | |
| 151 | size_t emit_asm_len; | |
| 152 | ||
| 153 | const char *emit_llvm_ir_ptr; | |
| 154 | size_t emit_llvm_ir_len; | |
| 155 | ||
| 156 | const char *emit_analysis_json_ptr; | |
| 157 | size_t emit_analysis_json_len; | |
| 158 | ||
| 159 | const char *emit_docs_ptr; | |
| 160 | size_t emit_docs_len; | |
| 146 | 161 | |
| 147 | 162 | const char *builtin_zig_path_ptr; |
| 148 | 163 | size_t builtin_zig_path_len; |
| ... | ... | @@ -173,11 +188,6 @@ struct ZigStage1 { |
| 173 | 188 | bool enable_stack_probing; |
| 174 | 189 | bool enable_time_report; |
| 175 | 190 | bool enable_stack_report; |
| 176 | bool dump_analysis; | |
| 177 | bool enable_doc_generation; | |
| 178 | bool emit_bin; | |
| 179 | bool emit_asm; | |
| 180 | bool emit_llvm_ir; | |
| 181 | 191 | bool test_is_evented; |
| 182 | 192 | bool verbose_tokenize; |
| 183 | 193 | bool verbose_ast; |
src/stage1/zig0.cpp+6-7| ... | ... | @@ -241,7 +241,7 @@ int main(int argc, char **argv) { |
| 241 | 241 | Error err; |
| 242 | 242 | |
| 243 | 243 | const char *in_file = nullptr; |
| 244 | const char *output_dir = nullptr; | |
| 244 | const char *emit_bin_path = nullptr; | |
| 245 | 245 | bool strip = false; |
| 246 | 246 | const char *out_name = nullptr; |
| 247 | 247 | bool verbose_tokenize = false; |
| ... | ... | @@ -324,14 +324,14 @@ int main(int argc, char **argv) { |
| 324 | 324 | cur_pkg = cur_pkg->parent; |
| 325 | 325 | } else if (str_starts_with(arg, "-mcpu=")) { |
| 326 | 326 | mcpu = arg + strlen("-mcpu="); |
| 327 | } else if (str_starts_with(arg, "-femit-bin=")) { | |
| 328 | emit_bin_path = arg + strlen("-femit-bin="); | |
| 327 | 329 | } else if (i + 1 >= argc) { |
| 328 | 330 | fprintf(stderr, "Expected another argument after %s\n", arg); |
| 329 | 331 | return print_error_usage(arg0); |
| 330 | 332 | } else { |
| 331 | 333 | i += 1; |
| 332 | if (strcmp(arg, "--output-dir") == 0) { | |
| 333 | output_dir = argv[i]; | |
| 334 | } else if (strcmp(arg, "--color") == 0) { | |
| 334 | if (strcmp(arg, "--color") == 0) { | |
| 335 | 335 | if (strcmp(argv[i], "auto") == 0) { |
| 336 | 336 | color = ErrColorAuto; |
| 337 | 337 | } else if (strcmp(argv[i], "on") == 0) { |
| ... | ... | @@ -443,15 +443,14 @@ int main(int argc, char **argv) { |
| 443 | 443 | stage1->verbose_llvm_ir = verbose_llvm_ir; |
| 444 | 444 | stage1->verbose_cimport = verbose_cimport; |
| 445 | 445 | stage1->verbose_llvm_cpu_features = verbose_llvm_cpu_features; |
| 446 | stage1->output_dir_ptr = output_dir; | |
| 447 | stage1->output_dir_len = strlen(output_dir); | |
| 446 | stage1->emit_o_ptr = emit_bin_path; | |
| 447 | stage1->emit_o_len = strlen(emit_bin_path); | |
| 448 | 448 | stage1->root_pkg = cur_pkg; |
| 449 | 449 | stage1->err_color = color; |
| 450 | 450 | stage1->link_libc = link_libc; |
| 451 | 451 | stage1->link_libcpp = link_libcpp; |
| 452 | 452 | stage1->subsystem = subsystem; |
| 453 | 453 | stage1->pic = true; |
| 454 | stage1->emit_bin = true; | |
| 455 | 454 | |
| 456 | 455 | zig_stage1_build_object(stage1); |
| 457 | 456 |
test/cli.zig+11-8| ... | ... | @@ -118,17 +118,20 @@ fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void { |
| 118 | 118 | \\} |
| 119 | 119 | ); |
| 120 | 120 | |
| 121 | const args = [_][]const u8{ | |
| 121 | var args = std.ArrayList([]const u8).init(a); | |
| 122 | try args.appendSlice(&[_][]const u8{ | |
| 122 | 123 | zig_exe, "build-obj", |
| 123 | 124 | "--cache-dir", dir_path, |
| 124 | 125 | "--name", "example", |
| 125 | "--output-dir", dir_path, | |
| 126 | "--emit", "asm", | |
| 127 | "-mllvm", "--x86-asm-syntax=intel", | |
| 128 | "--strip", "--release-fast", | |
| 129 | example_zig_path, "--disable-gen-h", | |
| 130 | }; | |
| 131 | _ = try exec(dir_path, &args); | |
| 126 | "-fno-emit-bin", "-fno-emit-h", | |
| 127 | "--strip", "-OReleaseFast", | |
| 128 | example_zig_path, | |
| 129 | }); | |
| 130 | ||
| 131 | const emit_asm_arg = try std.fmt.allocPrint(a, "-femit-asm={s}", .{example_s_path}); | |
| 132 | try args.append(emit_asm_arg); | |
| 133 | ||
| 134 | _ = try exec(dir_path, args.items); | |
| 132 | 135 | |
| 133 | 136 | const out_asm = try std.fs.cwd().readFileAlloc(a, example_s_path, std.math.maxInt(usize)); |
| 134 | 137 | testing.expect(std.mem.indexOf(u8, out_asm, "square:") != null); |