| ... | ... | @@ -41,6 +41,10 @@ pub fn main() !void { |
| 41 | 41 | const args = try os.argsAlloc(allocator); |
| 42 | 42 | defer os.argsFree(allocator, args); |
| 43 | 43 | |
| 44 | if (args.len >= 2 and mem.eql(u8, args[1], "build")) { |
| 45 | return buildMain(allocator, args[2..]); |
| 46 | } |
| 47 | |
| 44 | 48 | if (args.len >= 2 and mem.eql(u8, args[1], "fmt")) { |
| 45 | 49 | return fmtMain(allocator, args[2..]); |
| 46 | 50 | } |
| ... | ... | @@ -560,6 +564,161 @@ fn printZen() !void { |
| 560 | 564 | ); |
| 561 | 565 | } |
| 562 | 566 | |
| 567 | fn buildMain(allocator: &mem.Allocator, argv: []const []const u8) !void { |
| 568 | var build_file: [] const u8 = "build.zig"; |
| 569 | var cache_dir: ?[] const u8 = null; |
| 570 | var zig_install_prefix: ?[] const u8 = null; |
| 571 | var asked_for_help = false; |
| 572 | var asked_for_init = false; |
| 573 | |
| 574 | var args = ArrayList([] const u8).init(allocator); |
| 575 | defer args.deinit(); |
| 576 | |
| 577 | var zig_exe_path = try os.selfExePath(allocator); |
| 578 | defer allocator.free(zig_exe_path); |
| 579 | |
| 580 | try args.append(""); // Placeholder for zig-cache/build |
| 581 | try args.append(""); // Placeholder for zig_exe_path |
| 582 | try args.append(""); // Placeholder for build_file_dirname |
| 583 | try args.append(""); // Placeholder for full_cache_dir |
| 584 | |
| 585 | var i: usize = 0; |
| 586 | while (i < argv.len) : (i += 1) { |
| 587 | var arg = argv[i]; |
| 588 | if (mem.eql(u8, arg, "--help")) { |
| 589 | asked_for_help = true; |
| 590 | try args.append(argv[i]); |
| 591 | } else if (mem.eql(u8, arg, "--init")) { |
| 592 | asked_for_init = true; |
| 593 | try args.append(argv[i]); |
| 594 | } else if (i + 1 < argv.len and mem.eql(u8, arg, "--build-file")) { |
| 595 | build_file = argv[i + 1]; |
| 596 | i += 1; |
| 597 | } else if (i + 1 < argv.len and mem.eql(u8, arg, "--cache-dir")) { |
| 598 | cache_dir = argv[i + 1]; |
| 599 | i += 1; |
| 600 | } else if (i + 1 < argv.len and mem.eql(u8, arg, "--zig-install-prefix")) { |
| 601 | try args.append(arg); |
| 602 | i += 1; |
| 603 | zig_install_prefix = argv[i]; |
| 604 | try args.append(argv[i]); |
| 605 | } else { |
| 606 | try args.append(arg); |
| 607 | } |
| 608 | } |
| 609 | |
| 610 | const zig_lib_dir = try resolveZigLibDir(allocator, zig_install_prefix); |
| 611 | defer allocator.free(zig_lib_dir); |
| 612 | |
| 613 | const zig_std_dir = try os.path.join(allocator, zig_lib_dir, "std"); |
| 614 | defer allocator.free(zig_std_dir); |
| 615 | |
| 616 | const special_dir = try os.path.join(allocator, zig_std_dir, "special"); |
| 617 | defer allocator.free(special_dir); |
| 618 | |
| 619 | const build_runner_path = try os.path.join(allocator, special_dir, "build_runner.zig"); |
| 620 | defer allocator.free(build_runner_path); |
| 621 | |
| 622 | // g = codegen_create(build_runner_path, ...) |
| 623 | // codegen_set_out_name(g, "build") |
| 624 | |
| 625 | const build_file_abs = try os.path.resolve(allocator, ".", build_file); |
| 626 | defer allocator.free(build_file_abs); |
| 627 | |
| 628 | const build_file_basename = os.path.basename(build_file_abs); |
| 629 | const build_file_dirname = os.path.dirname(build_file_abs); |
| 630 | |
| 631 | var full_cache_dir: []u8 = undefined; |
| 632 | if (cache_dir == null) { |
| 633 | full_cache_dir = try os.path.join(allocator, build_file_dirname, "zig-cache"); |
| 634 | } else { |
| 635 | full_cache_dir = try os.path.resolve(allocator, ".", ??cache_dir, full_cache_dir); |
| 636 | } |
| 637 | defer allocator.free(full_cache_dir); |
| 638 | |
| 639 | const path_to_build_exe = try os.path.join(allocator, full_cache_dir, "build"); |
| 640 | defer allocator.free(path_to_build_exe); |
| 641 | // codegen_set_cache_dir(g, full_cache_dir) |
| 642 | |
| 643 | args.items[0] = path_to_build_exe; |
| 644 | args.items[1] = zig_exe_path; |
| 645 | args.items[2] = build_file_dirname; |
| 646 | args.items[3] = full_cache_dir; |
| 647 | |
| 648 | var build_file_exists: bool = undefined; |
| 649 | if (os.File.openRead(allocator, build_file_abs)) |*file| { |
| 650 | file.close(); |
| 651 | build_file_exists = true; |
| 652 | } else |_| { |
| 653 | build_file_exists = false; |
| 654 | } |
| 655 | |
| 656 | if (!build_file_exists and asked_for_help) { |
| 657 | // TODO(bnoordhuis) Print help message from std/special/build_runner.zig |
| 658 | return; |
| 659 | } |
| 660 | |
| 661 | if (!build_file_exists and asked_for_init) { |
| 662 | const build_template_path = try os.path.join(allocator, special_dir, "build_file_template.zig"); |
| 663 | defer allocator.free(build_template_path); |
| 664 | |
| 665 | var srcfile = try os.File.openRead(allocator, build_template_path); |
| 666 | defer srcfile.close(); |
| 667 | |
| 668 | var dstfile = try os.File.openWrite(allocator, build_file_abs); |
| 669 | defer dstfile.close(); |
| 670 | |
| 671 | while (true) { |
| 672 | var buffer: [4096]u8 = undefined; |
| 673 | const n = try srcfile.read(buffer[0..]); |
| 674 | if (n == 0) break; |
| 675 | try dstfile.write(buffer[0..n]); |
| 676 | } |
| 677 | |
| 678 | return; |
| 679 | } |
| 680 | |
| 681 | if (!build_file_exists) { |
| 682 | warn( |
| 683 | \\No 'build.zig' file found. |
| 684 | \\Initialize a 'build.zig' template file with `zig build --init`, |
| 685 | \\or build an executable directly with `zig build-exe $FILENAME.zig`. |
| 686 | \\See: `zig build --help` or `zig help` for more options. |
| 687 | \\ |
| 688 | ); |
| 689 | os.exit(1); |
| 690 | } |
| 691 | |
| 692 | // codegen_build(g) |
| 693 | // codegen_link(g, path_to_build_exe) |
| 694 | // codegen_destroy(g) |
| 695 | |
| 696 | var proc = try os.ChildProcess.init(args.toSliceConst(), allocator); |
| 697 | defer proc.deinit(); |
| 698 | |
| 699 | var term = try proc.spawnAndWait(); |
| 700 | switch (term) { |
| 701 | os.ChildProcess.Term.Exited => |status| { |
| 702 | if (status != 0) { |
| 703 | warn("{} exited with status {}\n", args.at(0), status); |
| 704 | os.exit(1); |
| 705 | } |
| 706 | }, |
| 707 | os.ChildProcess.Term.Signal => |signal| { |
| 708 | warn("{} killed by signal {}\n", args.at(0), signal); |
| 709 | os.exit(1); |
| 710 | }, |
| 711 | os.ChildProcess.Term.Stopped => |signal| { |
| 712 | warn("{} stopped by signal {}\n", args.at(0), signal); |
| 713 | os.exit(1); |
| 714 | }, |
| 715 | os.ChildProcess.Term.Unknown => |status| { |
| 716 | warn("{} encountered unknown failure {}\n", args.at(0), status); |
| 717 | os.exit(1); |
| 718 | }, |
| 719 | } |
| 720 | } |
| 721 | |
| 563 | 722 | fn fmtMain(allocator: &mem.Allocator, file_paths: []const []const u8) !void { |
| 564 | 723 | for (file_paths) |file_path| { |
| 565 | 724 | var file = try os.File.openRead(allocator, file_path); |