authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-06 14:35:52-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-06 14:35:52-05:00
log9154a8606996ce34e5f1d805672c83e2b733f5a7
tree3ba5b928b4d7476540d408f150a69b40eaa29c63
parente535521619d474fb5d819d0e5cafa3e197bba7af
parentc3a2b51a2cdd5a64401df2ad326c20f151455f00
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11065 from hexops/sg/responsefiles-2

Do not fail to build if 'zig build-lib' etc. arguments exceed OS limits (take 2)

2 files changed, 204 insertions(+), 146 deletions(-)

lib/std/build.zig+36
...@@ -17,6 +17,7 @@ const fmt_lib = std.fmt;...@@ -17,6 +17,7 @@ const fmt_lib = std.fmt;
17const File = std.fs.File;17const File = std.fs.File;
18const CrossTarget = std.zig.CrossTarget;18const CrossTarget = std.zig.CrossTarget;
19const NativeTargetInfo = std.zig.system.NativeTargetInfo;19const NativeTargetInfo = std.zig.system.NativeTargetInfo;
20const Sha256 = std.crypto.hash.sha2.Sha256;
2021
21pub const FmtStep = @import("build/FmtStep.zig");22pub const FmtStep = @import("build/FmtStep.zig");
22pub const TranslateCStep = @import("build/TranslateCStep.zig");23pub const TranslateCStep = @import("build/TranslateCStep.zig");
...@@ -2892,6 +2893,41 @@ pub const LibExeObjStep = struct {...@@ -2892,6 +2893,41 @@ pub const LibExeObjStep = struct {
28922893
2893 try zig_args.append("--enable-cache");2894 try zig_args.append("--enable-cache");
28942895
2896 // Windows has an argument length limit of 32,766 characters, macOS 262,144 and Linux
2897 // 2,097,152. If our args exceed 30 KiB, we instead write them to a "response file" and
2898 // pass that to zig, e.g. via 'zig build-lib @args.rsp'
2899 var args_length: usize = 0;
2900 for (zig_args.items) |arg| {
2901 args_length += arg.len + 1; // +1 to account for null terminator
2902 }
2903 if (args_length >= 30 * 1024) {
2904 const args_dir = try fs.path.join(
2905 builder.allocator,
2906 &[_][]const u8{ builder.pathFromRoot("zig-cache"), "args" },
2907 );
2908 try std.fs.cwd().makePath(args_dir);
2909
2910 // Write the args to zig-cache/args/<SHA256 hash of args> to avoid conflicts with
2911 // other zig build commands running in parallel.
2912 const partially_quoted = try std.mem.join(builder.allocator, "\" \"", zig_args.items[2..]);
2913 const args = try std.mem.concat(builder.allocator, u8, &[_][]const u8{ "\"", partially_quoted, "\"" });
2914
2915 var args_hash: [Sha256.digest_length]u8 = undefined;
2916 Sha256.hash(args, &args_hash, .{});
2917 var args_hex_hash: [Sha256.digest_length * 2]u8 = undefined;
2918 _ = try std.fmt.bufPrint(
2919 &args_hex_hash,
2920 "{s}",
2921 .{std.fmt.fmtSliceHexLower(&args_hash)},
2922 );
2923
2924 const args_file = try fs.path.join(builder.allocator, &[_][]const u8{ args_dir, args_hex_hash[0..] });
2925 try std.fs.cwd().writeFile(args_file, args);
2926
2927 zig_args.shrinkRetainingCapacity(2);
2928 try zig_args.append(try std.mem.concat(builder.allocator, u8, &[_][]const u8{ "@", args_file }));
2929 }
2930
2895 const output_dir_nl = try builder.execFromStep(zig_args.items, &self.step);2931 const output_dir_nl = try builder.execFromStep(zig_args.items, &self.step);
2896 const build_output_dir = mem.trimRight(u8, output_dir_nl, "\r\n");2932 const build_output_dir = mem.trimRight(u8, output_dir_nl, "\r\n");
28972933
src/main.zig+168-146
...@@ -767,85 +767,105 @@ fn buildOutputType(...@@ -767,85 +767,105 @@ fn buildOutputType(
767 }767 }
768768
769 soname = .yes_default_value;769 soname = .yes_default_value;
770 const args = all_args[2..];770
771 var i: usize = 0;771 const Iterator = struct {
772 args_loop: while (i < args.len) : (i += 1) {772 resp_file: ?ArgIteratorResponseFile = null,
773 const arg = args[i];773 args: []const []const u8,
774 if (mem.startsWith(u8, arg, "-")) {774 i: usize = 0,
775 fn next(it: *@This()) ?[]const u8 {
776 if (it.i >= it.args.len) {
777 if (it.resp_file) |*resp| return if (resp.next()) |sentinel| std.mem.span(sentinel) else null;
778 return null;
779 }
780 defer it.i += 1;
781 return it.args[it.i];
782 }
783 };
784 var args_iter = Iterator{
785 .args = all_args[2..],
786 };
787
788 args_loop: while (args_iter.next()) |arg| {
789 if (mem.startsWith(u8, arg, "@")) {
790 // This is a "compiler response file". We must parse the file and treat its
791 // contents as command line parameters.
792 const resp_file_path = arg[1..];
793 args_iter.resp_file = initArgIteratorResponseFile(arena, resp_file_path) catch |err| {
794 fatal("unable to read response file '{s}': {s}", .{ resp_file_path, @errorName(err) });
795 };
796 } else if (mem.startsWith(u8, arg, "-")) {
775 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {797 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
776 try io.getStdOut().writeAll(usage_build_generic);798 try io.getStdOut().writeAll(usage_build_generic);
777 return cleanExit();799 return cleanExit();
778 } else if (mem.eql(u8, arg, "--")) {800 } else if (mem.eql(u8, arg, "--")) {
779 if (arg_mode == .run) {801 if (arg_mode == .run) {
780 // The index refers to all_args so skip `zig` `run`802 // args_iter.i is 1, referring the next arg after "--" in ["--", ...]
781 // and `--`803 // Add +2 to the index so it is relative to all_args
782 runtime_args_start = i + 3;804 runtime_args_start = args_iter.i + 2;
783 break :args_loop;805 break :args_loop;
784 } else {806 } else {
785 fatal("unexpected end-of-parameter mark: --", .{});807 fatal("unexpected end-of-parameter mark: --", .{});
786 }808 }
787 } else if (mem.eql(u8, arg, "--pkg-begin")) {809 } else if (mem.eql(u8, arg, "--pkg-begin")) {
788 if (i + 2 >= args.len) fatal("Expected 2 arguments after {s}", .{arg});810 const pkg_name = args_iter.next();
789 i += 1;811 const pkg_path = args_iter.next();
790 const pkg_name = args[i];812 if (pkg_name == null or pkg_path == null) fatal("Expected 2 arguments after {s}", .{arg});
791 i += 1;
792 const pkg_path = args[i];
793813
794 const new_cur_pkg = Package.create(814 const new_cur_pkg = Package.create(
795 gpa,815 gpa,
796 fs.path.dirname(pkg_path),816 fs.path.dirname(pkg_path.?),
797 fs.path.basename(pkg_path),817 fs.path.basename(pkg_path.?),
798 ) catch |err| {818 ) catch |err| {
799 fatal("Failed to add package at path {s}: {s}", .{ pkg_path, @errorName(err) });819 fatal("Failed to add package at path {s}: {s}", .{ pkg_path.?, @errorName(err) });
800 };820 };
801 try cur_pkg.addAndAdopt(gpa, pkg_name, new_cur_pkg);821 try cur_pkg.addAndAdopt(gpa, pkg_name.?, new_cur_pkg);
802 cur_pkg = new_cur_pkg;822 cur_pkg = new_cur_pkg;
803 } else if (mem.eql(u8, arg, "--pkg-end")) {823 } else if (mem.eql(u8, arg, "--pkg-end")) {
804 cur_pkg = cur_pkg.parent orelse824 cur_pkg = cur_pkg.parent orelse
805 fatal("encountered --pkg-end with no matching --pkg-begin", .{});825 fatal("encountered --pkg-end with no matching --pkg-begin", .{});
806 } else if (mem.eql(u8, arg, "--main-pkg-path")) {826 } else if (mem.eql(u8, arg, "--main-pkg-path")) {
807 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});827 main_pkg_path = args_iter.next() orelse {
808 i += 1;828 fatal("expected parameter after {s}", .{arg});
809 main_pkg_path = args[i];829 };
810 } else if (mem.eql(u8, arg, "-cflags")) {830 } else if (mem.eql(u8, arg, "-cflags")) {
811 extra_cflags.shrinkRetainingCapacity(0);831 extra_cflags.shrinkRetainingCapacity(0);
812 while (true) {832 while (true) {
813 i += 1;833 const next_arg = args_iter.next() orelse {
814 if (i >= args.len) fatal("expected -- after -cflags", .{});834 fatal("expected -- after -cflags", .{});
815 if (mem.eql(u8, args[i], "--")) break;835 };
816 try extra_cflags.append(args[i]);836 if (mem.eql(u8, next_arg, "--")) break;
837 try extra_cflags.append(next_arg);
817 }838 }
818 } else if (mem.eql(u8, arg, "--color")) {839 } else if (mem.eql(u8, arg, "--color")) {
819 if (i + 1 >= args.len) {840 const next_arg = args_iter.next() orelse {
820 fatal("expected [auto|on|off] after --color", .{});841 fatal("expected [auto|on|off] after --color", .{});
821 }842 };
822 i += 1;
823 const next_arg = args[i];
824 color = std.meta.stringToEnum(Color, next_arg) orelse {843 color = std.meta.stringToEnum(Color, next_arg) orelse {
825 fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg});844 fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg});
826 };845 };
827 } else if (mem.eql(u8, arg, "--subsystem")) {846 } else if (mem.eql(u8, arg, "--subsystem")) {
828 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});847 const next_arg = args_iter.next() orelse {
829 i += 1;848 fatal("expected parameter after {s}", .{arg});
830 if (mem.eql(u8, args[i], "console")) {849 };
850 if (mem.eql(u8, next_arg, "console")) {
831 subsystem = .Console;851 subsystem = .Console;
832 } else if (mem.eql(u8, args[i], "windows")) {852 } else if (mem.eql(u8, next_arg, "windows")) {
833 subsystem = .Windows;853 subsystem = .Windows;
834 } else if (mem.eql(u8, args[i], "posix")) {854 } else if (mem.eql(u8, next_arg, "posix")) {
835 subsystem = .Posix;855 subsystem = .Posix;
836 } else if (mem.eql(u8, args[i], "native")) {856 } else if (mem.eql(u8, next_arg, "native")) {
837 subsystem = .Native;857 subsystem = .Native;
838 } else if (mem.eql(u8, args[i], "efi_application")) {858 } else if (mem.eql(u8, next_arg, "efi_application")) {
839 subsystem = .EfiApplication;859 subsystem = .EfiApplication;
840 } else if (mem.eql(u8, args[i], "efi_boot_service_driver")) {860 } else if (mem.eql(u8, next_arg, "efi_boot_service_driver")) {
841 subsystem = .EfiBootServiceDriver;861 subsystem = .EfiBootServiceDriver;
842 } else if (mem.eql(u8, args[i], "efi_rom")) {862 } else if (mem.eql(u8, next_arg, "efi_rom")) {
843 subsystem = .EfiRom;863 subsystem = .EfiRom;
844 } else if (mem.eql(u8, args[i], "efi_runtime_driver")) {864 } else if (mem.eql(u8, next_arg, "efi_runtime_driver")) {
845 subsystem = .EfiRuntimeDriver;865 subsystem = .EfiRuntimeDriver;
846 } else {866 } else {
847 fatal("invalid: --subsystem: '{s}'. Options are:\n{s}", .{867 fatal("invalid: --subsystem: '{s}'. Options are:\n{s}", .{
848 args[i],868 next_arg,
849 \\ console869 \\ console
850 \\ windows870 \\ windows
851 \\ posix871 \\ posix
...@@ -858,67 +878,71 @@ fn buildOutputType(...@@ -858,67 +878,71 @@ fn buildOutputType(
858 });878 });
859 }879 }
860 } else if (mem.eql(u8, arg, "-O")) {880 } else if (mem.eql(u8, arg, "-O")) {
861 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});881 optimize_mode_string = args_iter.next() orelse {
862 i += 1;882 fatal("expected parameter after {s}", .{arg});
863 optimize_mode_string = args[i];883 };
864 } else if (mem.eql(u8, arg, "--entry")) {884 } else if (mem.eql(u8, arg, "--entry")) {
865 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});885 entry = args_iter.next() orelse {
866 i += 1;886 fatal("expected parameter after {s}", .{arg});
867 entry = args[i];887 };
868 } else if (mem.eql(u8, arg, "--stack")) {888 } else if (mem.eql(u8, arg, "--stack")) {
869 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});889 const next_arg = args_iter.next() orelse {
870 i += 1;890 fatal("expected parameter after {s}", .{arg});
871 stack_size_override = std.fmt.parseUnsigned(u64, args[i], 0) catch |err| {891 };
892 stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {
872 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });893 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
873 };894 };
874 } else if (mem.eql(u8, arg, "--image-base")) {895 } else if (mem.eql(u8, arg, "--image-base")) {
875 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});896 const next_arg = args_iter.next() orelse {
876 i += 1;897 fatal("expected parameter after {s}", .{arg});
877 image_base_override = std.fmt.parseUnsigned(u64, args[i], 0) catch |err| {898 };
899 image_base_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {
878 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });900 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
879 };901 };
880 } else if (mem.eql(u8, arg, "--name")) {902 } else if (mem.eql(u8, arg, "--name")) {
881 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});903 provided_name = args_iter.next() orelse {
882 i += 1;904 fatal("expected parameter after {s}", .{arg});
883 provided_name = args[i];905 };
884 } else if (mem.eql(u8, arg, "-rpath")) {906 } else if (mem.eql(u8, arg, "-rpath")) {
885 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});907 try rpath_list.append(args_iter.next() orelse {
886 i += 1;908 fatal("expected parameter after {s}", .{arg});
887 try rpath_list.append(args[i]);909 });
888 } else if (mem.eql(u8, arg, "--library-directory") or mem.eql(u8, arg, "-L")) {910 } else if (mem.eql(u8, arg, "--library-directory") or mem.eql(u8, arg, "-L")) {
889 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});911 try lib_dirs.append(args_iter.next() orelse {
890 i += 1;912 fatal("expected parameter after {s}", .{arg});
891 try lib_dirs.append(args[i]);913 });
892 } else if (mem.eql(u8, arg, "-F")) {914 } else if (mem.eql(u8, arg, "-F")) {
893 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});915 try framework_dirs.append(args_iter.next() orelse {
894 i += 1;916 fatal("expected parameter after {s}", .{arg});
895 try framework_dirs.append(args[i]);917 });
896 } else if (mem.eql(u8, arg, "-framework")) {918 } else if (mem.eql(u8, arg, "-framework")) {
897 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});919 try frameworks.append(args_iter.next() orelse {
898 i += 1;920 fatal("expected parameter after {s}", .{arg});
899 try frameworks.append(args[i]);921 });
900 } else if (mem.eql(u8, arg, "-install_name")) {922 } else if (mem.eql(u8, arg, "-install_name")) {
901 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});923 install_name = args_iter.next() orelse {
902 i += 1;924 fatal("expected parameter after {s}", .{arg});
903 install_name = args[i];925 };
904 } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) {926 } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) {
905 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});927 linker_script = args_iter.next() orelse {
906 i += 1;928 fatal("expected parameter after {s}", .{arg});
907 linker_script = args[i];929 };
908 } else if (mem.eql(u8, arg, "--version-script")) {930 } else if (mem.eql(u8, arg, "--version-script")) {
909 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});931 version_script = args_iter.next() orelse {
910 i += 1;932 fatal("expected parameter after {s}", .{arg});
911 version_script = args[i];933 };
912 } else if (mem.eql(u8, arg, "--library") or mem.eql(u8, arg, "-l")) {934 } else if (mem.eql(u8, arg, "--library") or mem.eql(u8, arg, "-l")) {
913 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});935 const next_arg = args_iter.next() orelse {
936 fatal("expected parameter after {s}", .{arg});
937 };
914 // We don't know whether this library is part of libc or libc++ until938 // We don't know whether this library is part of libc or libc++ until
915 // we resolve the target, so we simply append to the list for now.939 // we resolve the target, so we simply append to the list for now.
916 i += 1;940 try system_libs.put(next_arg, .{ .needed = false });
917 try system_libs.put(args[i], .{ .needed = false });
918 } else if (mem.eql(u8, arg, "--needed-library") or mem.eql(u8, arg, "-needed-l")) {941 } else if (mem.eql(u8, arg, "--needed-library") or mem.eql(u8, arg, "-needed-l")) {
919 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});942 const next_arg = args_iter.next() orelse {
920 i += 1;943 fatal("expected parameter after {s}", .{arg});
921 try system_libs.put(args[i], .{ .needed = true });944 };
945 try system_libs.put(next_arg, .{ .needed = true });
922 } else if (mem.eql(u8, arg, "-D") or946 } else if (mem.eql(u8, arg, "-D") or
923 mem.eql(u8, arg, "-isystem") or947 mem.eql(u8, arg, "-isystem") or
924 mem.eql(u8, arg, "-I") or948 mem.eql(u8, arg, "-I") or
...@@ -927,31 +951,30 @@ fn buildOutputType(...@@ -927,31 +951,30 @@ fn buildOutputType(
927 mem.eql(u8, arg, "-iframework") or951 mem.eql(u8, arg, "-iframework") or
928 mem.eql(u8, arg, "-iframeworkwithsysroot"))952 mem.eql(u8, arg, "-iframeworkwithsysroot"))
929 {953 {
930 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});
931 i += 1;
932 try clang_argv.append(arg);954 try clang_argv.append(arg);
933 try clang_argv.append(args[i]);955 try clang_argv.append(args_iter.next() orelse {
956 fatal("expected parameter after {s}", .{arg});
957 });
934 } else if (mem.eql(u8, arg, "--version")) {958 } else if (mem.eql(u8, arg, "--version")) {
935 if (i + 1 >= args.len) {959 const next_arg = args_iter.next() orelse {
936 fatal("expected parameter after --version", .{});960 fatal("expected parameter after {s}", .{arg});
937 }961 };
938 i += 1;962 version = std.builtin.Version.parse(next_arg) catch |err| {
939 version = std.builtin.Version.parse(args[i]) catch |err| {963 fatal("unable to parse --version '{s}': {s}", .{ next_arg, @errorName(err) });
940 fatal("unable to parse --version '{s}': {s}", .{ args[i], @errorName(err) });
941 };964 };
942 have_version = true;965 have_version = true;
943 } else if (mem.eql(u8, arg, "-target")) {966 } else if (mem.eql(u8, arg, "-target")) {
944 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});967 target_arch_os_abi = args_iter.next() orelse {
945 i += 1;968 fatal("expected parameter after {s}", .{arg});
946 target_arch_os_abi = args[i];969 };
947 } else if (mem.eql(u8, arg, "-mcpu")) {970 } else if (mem.eql(u8, arg, "-mcpu")) {
948 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});971 target_mcpu = args_iter.next() orelse {
949 i += 1;972 fatal("expected parameter after {s}", .{arg});
950 target_mcpu = args[i];973 };
951 } else if (mem.eql(u8, arg, "-mcmodel")) {974 } else if (mem.eql(u8, arg, "-mcmodel")) {
952 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});975 machine_code_model = parseCodeModel(args_iter.next() orelse {
953 i += 1;976 fatal("expected parameter after {s}", .{arg});
954 machine_code_model = parseCodeModel(args[i]);977 });
955 } else if (mem.startsWith(u8, arg, "-ofmt=")) {978 } else if (mem.startsWith(u8, arg, "-ofmt=")) {
956 target_ofmt = arg["-ofmt=".len..];979 target_ofmt = arg["-ofmt=".len..];
957 } else if (mem.startsWith(u8, arg, "-mcpu=")) {980 } else if (mem.startsWith(u8, arg, "-mcpu=")) {
...@@ -961,50 +984,51 @@ fn buildOutputType(...@@ -961,50 +984,51 @@ fn buildOutputType(
961 } else if (mem.startsWith(u8, arg, "-O")) {984 } else if (mem.startsWith(u8, arg, "-O")) {
962 optimize_mode_string = arg["-O".len..];985 optimize_mode_string = arg["-O".len..];
963 } else if (mem.eql(u8, arg, "--dynamic-linker")) {986 } else if (mem.eql(u8, arg, "--dynamic-linker")) {
964 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});987 target_dynamic_linker = args_iter.next() orelse {
965 i += 1;988 fatal("expected parameter after {s}", .{arg});
966 target_dynamic_linker = args[i];989 };
967 } else if (mem.eql(u8, arg, "--sysroot")) {990 } else if (mem.eql(u8, arg, "--sysroot")) {
968 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});991 sysroot = args_iter.next() orelse {
969 i += 1;992 fatal("expected parameter after {s}", .{arg});
970 sysroot = args[i];993 };
971 try clang_argv.append("-isysroot");994 try clang_argv.append("-isysroot");
972 try clang_argv.append(args[i]);995 try clang_argv.append(sysroot.?);
973 } else if (mem.eql(u8, arg, "--libc")) {996 } else if (mem.eql(u8, arg, "--libc")) {
974 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});997 libc_paths_file = args_iter.next() orelse {
975 i += 1;998 fatal("expected parameter after {s}", .{arg});
976 libc_paths_file = args[i];999 };
977 } else if (mem.eql(u8, arg, "--test-filter")) {1000 } else if (mem.eql(u8, arg, "--test-filter")) {
978 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});1001 test_filter = args_iter.next() orelse {
979 i += 1;1002 fatal("expected parameter after {s}", .{arg});
980 test_filter = args[i];1003 };
981 } else if (mem.eql(u8, arg, "--test-name-prefix")) {1004 } else if (mem.eql(u8, arg, "--test-name-prefix")) {
982 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});1005 test_name_prefix = args_iter.next() orelse {
983 i += 1;1006 fatal("expected parameter after {s}", .{arg});
984 test_name_prefix = args[i];1007 };
985 } else if (mem.eql(u8, arg, "--test-cmd")) {1008 } else if (mem.eql(u8, arg, "--test-cmd")) {
986 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});1009 try test_exec_args.append(args_iter.next() orelse {
987 i += 1;1010 fatal("expected parameter after {s}", .{arg});
988 try test_exec_args.append(args[i]);1011 });
989 } else if (mem.eql(u8, arg, "--cache-dir")) {1012 } else if (mem.eql(u8, arg, "--cache-dir")) {
990 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});1013 override_local_cache_dir = args_iter.next() orelse {
991 i += 1;1014 fatal("expected parameter after {s}", .{arg});
992 override_local_cache_dir = args[i];1015 };
993 } else if (mem.eql(u8, arg, "--global-cache-dir")) {1016 } else if (mem.eql(u8, arg, "--global-cache-dir")) {
994 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});1017 override_global_cache_dir = args_iter.next() orelse {
995 i += 1;1018 fatal("expected parameter after {s}", .{arg});
996 override_global_cache_dir = args[i];1019 };
997 } else if (mem.eql(u8, arg, "--zig-lib-dir")) {1020 } else if (mem.eql(u8, arg, "--zig-lib-dir")) {
998 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});1021 override_lib_dir = args_iter.next() orelse {
999 i += 1;1022 fatal("expected parameter after {s}", .{arg});
1000 override_lib_dir = args[i];1023 };
1001 } else if (mem.eql(u8, arg, "--debug-log")) {1024 } else if (mem.eql(u8, arg, "--debug-log")) {
1002 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});1025 const next_arg = args_iter.next() orelse {
1003 i += 1;1026 fatal("expected parameter after {s}", .{arg});
1027 };
1004 if (!build_options.enable_logging) {1028 if (!build_options.enable_logging) {
1005 std.log.warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{});1029 std.log.warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{});
1006 } else {1030 } else {
1007 try log_scopes.append(gpa, args[i]);1031 try log_scopes.append(gpa, next_arg);
1008 }1032 }
1009 } else if (mem.eql(u8, arg, "--debug-link-snapshot")) {1033 } else if (mem.eql(u8, arg, "--debug-link-snapshot")) {
1010 if (!build_options.enable_link_snapshots) {1034 if (!build_options.enable_link_snapshots) {
...@@ -1177,11 +1201,9 @@ fn buildOutputType(...@@ -1177,11 +1201,9 @@ fn buildOutputType(
1177 } else if (mem.eql(u8, arg, "-fno-allow-shlib-undefined")) {1201 } else if (mem.eql(u8, arg, "-fno-allow-shlib-undefined")) {
1178 linker_allow_shlib_undefined = false;1202 linker_allow_shlib_undefined = false;
1179 } else if (mem.eql(u8, arg, "-z")) {1203 } else if (mem.eql(u8, arg, "-z")) {
1180 i += 1;1204 const z_arg = args_iter.next() orelse {
1181 if (i >= args.len) {1205 fatal("expected parameter after {s}", .{arg});
1182 fatal("expected linker extension flag after '{s}'", .{arg});1206 };
1183 }
1184 const z_arg = args[i];
1185 if (mem.eql(u8, z_arg, "nodelete")) {1207 if (mem.eql(u8, z_arg, "nodelete")) {
1186 linker_z_nodelete = true;1208 linker_z_nodelete = true;
1187 } else if (mem.eql(u8, z_arg, "notext")) {1209 } else if (mem.eql(u8, z_arg, "notext")) {
...@@ -4300,6 +4322,17 @@ pub fn lldMain(...@@ -4300,6 +4322,17 @@ pub fn lldMain(
4300 return @bitCast(u8, @truncate(i8, exit_code));4322 return @bitCast(u8, @truncate(i8, exit_code));
4301}4323}
43024324
4325const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true, .single_quotes = true });
4326
4327/// Initialize the arguments from a Response File. "*.rsp"
4328fn initArgIteratorResponseFile(allocator: Allocator, resp_file_path: []const u8) !ArgIteratorResponseFile {
4329 const max_bytes = 10 * 1024 * 1024; // 10 MiB of command line arguments is a reasonable limit
4330 var cmd_line = try fs.cwd().readFileAlloc(allocator, resp_file_path, max_bytes);
4331 errdefer allocator.free(cmd_line);
4332
4333 return ArgIteratorResponseFile.initTakeOwnership(allocator, cmd_line);
4334}
4335
4303const clang_args = @import("clang_options.zig").list;4336const clang_args = @import("clang_options.zig").list;
43044337
4305pub const ClangArgIterator = struct {4338pub const ClangArgIterator = struct {
...@@ -4391,17 +4424,6 @@ pub const ClangArgIterator = struct {...@@ -4391,17 +4424,6 @@ pub const ClangArgIterator = struct {
4391 };4424 };
4392 }4425 }
43934426
4394 const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true, .single_quotes = true });
4395
4396 /// Initialize the arguments from a Response File. "*.rsp"
4397 fn initArgIteratorResponseFile(allocator: Allocator, resp_file_path: []const u8) !ArgIteratorResponseFile {
4398 const max_bytes = 10 * 1024 * 1024; // 10 MiB of command line arguments is a reasonable limit
4399 var cmd_line = try fs.cwd().readFileAlloc(allocator, resp_file_path, max_bytes);
4400 errdefer allocator.free(cmd_line);
4401
4402 return ArgIteratorResponseFile.initTakeOwnership(allocator, cmd_line);
4403 }
4404
4405 fn next(self: *ClangArgIterator) !void {4427 fn next(self: *ClangArgIterator) !void {
4406 assert(self.has_next);4428 assert(self.has_next);
4407 assert(self.next_index < self.argv.len);4429 assert(self.next_index < self.argv.len);