| ... | @@ -41,6 +41,10 @@ pub fn main() !void { | ... | @@ -41,6 +41,10 @@ pub fn main() !void { |
| 41 | const args = try os.argsAlloc(allocator); | 41 | const args = try os.argsAlloc(allocator); |
| 42 | defer os.argsFree(allocator, args); | 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 | if (args.len >= 2 and mem.eql(u8, args[1], "fmt")) { | 48 | if (args.len >= 2 and mem.eql(u8, args[1], "fmt")) { |
| 45 | return fmtMain(allocator, args[2..]); | 49 | return fmtMain(allocator, args[2..]); |
| 46 | } | 50 | } |
| ... | @@ -560,6 +564,161 @@ fn printZen() !void { | ... | @@ -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 | fn fmtMain(allocator: &mem.Allocator, file_paths: []const []const u8) !void { | 722 | fn fmtMain(allocator: &mem.Allocator, file_paths: []const []const u8) !void { |
| 564 | for (file_paths) |file_path| { | 723 | for (file_paths) |file_path| { |
| 565 | var file = try os.File.openRead(allocator, file_path); | 724 | var file = try os.File.openRead(allocator, file_path); |