authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-19 22:19:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-19 22:26:13-07:00
log29cce62a259384e7daffe8fa68a0edf34377c6b3
treed0e7439e7669b54e8588e204cbb0f98dce136cd8
parent41eff5723dd61b19be88830f16d76514583e3339

CLI: introduce -M; deprecate --mod

I changed my mind on how the CLI for Zig modules should work. I don't like that `--mod` takes 2 parameters. Instead let's swing all the way in the other direction: `-M[name][=src]` This is shorter (Zig CLI invocations are long enough already), avoids the double parameter edge case, and supports the concept of omitting the source file part of the argument, which was already wanted for `-Mstd`. The legacy way to encode that was `--mod std ''` - awkward! Undocumented support for `--mod` remains so that this branch does not need a zig1.wasm update. The next time that file is updated, support for `--mod` can be dropped. Importantly, this commit also adds support for modules that do not have a root zig source file. In such case, it sets root to cwd and root_src_path to empty string, and only sets have_zcu to true if a module is provided with a root zig source file.

1 files changed, 107 insertions(+), 53 deletions(-)

src/main.zig+107-53
...@@ -409,10 +409,10 @@ const usage_build_generic =...@@ -409,10 +409,10 @@ const usage_build_generic =
409 \\ --libc [file] Provide a file which specifies libc paths409 \\ --libc [file] Provide a file which specifies libc paths
410 \\ -x language Treat subsequent input files as having type <language>410 \\ -x language Treat subsequent input files as having type <language>
411 \\ --dep [[import=]name] Add an entry to the next module's import table411 \\ --dep [[import=]name] Add an entry to the next module's import table
412 \\ --mod [name] [src] Create a module based on the current per-module settings.412 \\ -M[name][=src] Create a module based on the current per-module settings.
413 \\ The first module is the main module.413 \\ The first module is the main module.
414 \\ "std" can be configured by leaving src blank.414 \\ "std" can be configured by omitting src
415 \\ After a --mod argument, per-module settings are reset.415 \\ After a -M argument, per-module settings are reset.
416 \\ --error-limit [num] Set the maximum amount of distinct error values416 \\ --error-limit [num] Set the maximum amount of distinct error values
417 \\ -fllvm Force using LLVM as the codegen backend417 \\ -fllvm Force using LLVM as the codegen backend
418 \\ -fno-llvm Prevent using LLVM as the codegen backend418 \\ -fno-llvm Prevent using LLVM as the codegen backend
...@@ -1040,56 +1040,39 @@ fn buildOutputType(...@@ -1040,56 +1040,39 @@ fn buildOutputType(
1040 .value = value,1040 .value = value,
1041 });1041 });
1042 } else if (mem.eql(u8, arg, "--mod")) {1042 } else if (mem.eql(u8, arg, "--mod")) {
1043 const mod_name = args_iter.nextOrFatal();1043 // deprecated, kept around until the next zig1.wasm update
1044 const root_src_orig = args_iter.nextOrFatal();1044 try handleModArg(
10451045 arena,
1046 const gop = try create_module.modules.getOrPut(arena, mod_name);1046 args_iter.nextOrFatal(),
10471047 args_iter.nextOrFatal(),
1048 if (gop.found_existing) {1048 &create_module,
1049 fatal("unable to add module '{s}': already exists as '{s}'", .{1049 &mod_opts,
1050 mod_name, gop.value_ptr.paths.root_src_path,1050 &cc_argv,
1051 });1051 &target_arch_os_abi,
1052 }1052 &target_mcpu,
10531053 &deps,
1054 // See duplicate logic: ModCreationGlobalFlags1054 &c_source_files_owner_index,
1055 create_module.opts.have_zcu = true;1055 &rc_source_files_owner_index,
1056 if (mod_opts.single_threaded == false)1056 &cssan,
1057 create_module.opts.any_non_single_threaded = true;1057 );
1058 if (mod_opts.sanitize_thread == true)1058 } else if (mem.startsWith(u8, arg, "-M")) {
1059 create_module.opts.any_sanitize_thread = true;1059 var it = mem.splitScalar(u8, arg["-M".len..], '=');
1060 if (mod_opts.unwind_tables == true)1060 const mod_name = it.next().?;
1061 create_module.opts.any_unwind_tables = true;1061 const root_src_orig = it.next();
1062 if (mod_opts.strip == false)1062 try handleModArg(
1063 create_module.opts.any_non_stripped = true;1063 arena,
1064 if (mod_opts.error_tracing == true)1064 mod_name,
1065 create_module.opts.any_error_tracing = true;1065 root_src_orig,
10661066 &create_module,
1067 const root_src = try introspect.resolvePath(arena, root_src_orig);1067 &mod_opts,
1068 gop.value_ptr.* = .{1068 &cc_argv,
1069 .paths = .{1069 &target_arch_os_abi,
1070 .root = .{1070 &target_mcpu,
1071 .root_dir = Cache.Directory.cwd(),1071 &deps,
1072 .sub_path = fs.path.dirname(root_src) orelse "",1072 &c_source_files_owner_index,
1073 },1073 &rc_source_files_owner_index,
1074 .root_src_path = fs.path.basename(root_src),1074 &cssan,
1075 },1075 );
1076 .cc_argv = try cc_argv.toOwnedSlice(arena),
1077 .inherited = mod_opts,
1078 .target_arch_os_abi = target_arch_os_abi,
1079 .target_mcpu = target_mcpu,
1080 .deps = try deps.toOwnedSlice(arena),
1081 .resolved = null,
1082 .c_source_files_start = c_source_files_owner_index,
1083 .c_source_files_end = create_module.c_source_files.items.len,
1084 .rc_source_files_start = rc_source_files_owner_index,
1085 .rc_source_files_end = create_module.rc_source_files.items.len,
1086 };
1087 cssan.reset();
1088 mod_opts = .{};
1089 target_arch_os_abi = null;
1090 target_mcpu = null;
1091 c_source_files_owner_index = create_module.c_source_files.items.len;
1092 rc_source_files_owner_index = create_module.rc_source_files.items.len;
1093 } else if (mem.eql(u8, arg, "--error-limit")) {1076 } else if (mem.eql(u8, arg, "--error-limit")) {
1094 const next_arg = args_iter.nextOrFatal();1077 const next_arg = args_iter.nextOrFatal();
1095 error_limit = std.fmt.parseUnsigned(Module.ErrorInt, next_arg, 0) catch |err| {1078 error_limit = std.fmt.parseUnsigned(Module.ErrorInt, next_arg, 0) catch |err| {
...@@ -7797,3 +7780,74 @@ fn parseImageBase(s: []const u8) u64 {...@@ -7797,3 +7780,74 @@ fn parseImageBase(s: []const u8) u64 {
7797 return std.fmt.parseUnsigned(u64, s, 0) catch |err|7780 return std.fmt.parseUnsigned(u64, s, 0) catch |err|
7798 fatal("unable to parse image base '{s}': {s}", .{ s, @errorName(err) });7781 fatal("unable to parse image base '{s}': {s}", .{ s, @errorName(err) });
7799}7782}
7783
7784fn handleModArg(
7785 arena: Allocator,
7786 mod_name: []const u8,
7787 opt_root_src_orig: ?[]const u8,
7788 create_module: *CreateModule,
7789 mod_opts: *Package.Module.CreateOptions.Inherited,
7790 cc_argv: *std.ArrayListUnmanaged([]const u8),
7791 target_arch_os_abi: *?[]const u8,
7792 target_mcpu: *?[]const u8,
7793 deps: *std.ArrayListUnmanaged(CliModule.Dep),
7794 c_source_files_owner_index: *usize,
7795 rc_source_files_owner_index: *usize,
7796 cssan: *ClangSearchSanitizer,
7797) !void {
7798 const gop = try create_module.modules.getOrPut(arena, mod_name);
7799
7800 if (gop.found_existing) {
7801 fatal("unable to add module '{s}': already exists as '{s}'", .{
7802 mod_name, gop.value_ptr.paths.root_src_path,
7803 });
7804 }
7805
7806 // See duplicate logic: ModCreationGlobalFlags
7807 if (mod_opts.single_threaded == false)
7808 create_module.opts.any_non_single_threaded = true;
7809 if (mod_opts.sanitize_thread == true)
7810 create_module.opts.any_sanitize_thread = true;
7811 if (mod_opts.unwind_tables == true)
7812 create_module.opts.any_unwind_tables = true;
7813 if (mod_opts.strip == false)
7814 create_module.opts.any_non_stripped = true;
7815 if (mod_opts.error_tracing == true)
7816 create_module.opts.any_error_tracing = true;
7817
7818 gop.value_ptr.* = .{
7819 .paths = p: {
7820 if (opt_root_src_orig) |root_src_orig| {
7821 create_module.opts.have_zcu = true;
7822 const root_src = try introspect.resolvePath(arena, root_src_orig);
7823 break :p .{
7824 .root = .{
7825 .root_dir = Cache.Directory.cwd(),
7826 .sub_path = fs.path.dirname(root_src) orelse "",
7827 },
7828 .root_src_path = fs.path.basename(root_src),
7829 };
7830 }
7831 break :p .{
7832 .root = .{ .root_dir = Cache.Directory.cwd() },
7833 .root_src_path = "",
7834 };
7835 },
7836 .cc_argv = try cc_argv.toOwnedSlice(arena),
7837 .inherited = mod_opts.*,
7838 .target_arch_os_abi = target_arch_os_abi.*,
7839 .target_mcpu = target_mcpu.*,
7840 .deps = try deps.toOwnedSlice(arena),
7841 .resolved = null,
7842 .c_source_files_start = c_source_files_owner_index.*,
7843 .c_source_files_end = create_module.c_source_files.items.len,
7844 .rc_source_files_start = rc_source_files_owner_index.*,
7845 .rc_source_files_end = create_module.rc_source_files.items.len,
7846 };
7847 cssan.reset();
7848 mod_opts.* = .{};
7849 target_arch_os_abi.* = null;
7850 target_mcpu.* = null;
7851 c_source_files_owner_index.* = create_module.c_source_files.items.len;
7852 rc_source_files_owner_index.* = create_module.rc_source_files.items.len;
7853}