authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-20 03:22:02-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-20 03:22:02-08:00
log5c4cb60f4fab0f3c0fde43e04bbc4a03c92bef8e
tree642441862f41281202980b4c34ec32afbc9bd80d
parentb729a3f008304d464b431f8ac34ad16cde08ba7b
parent2dea37545046e1a7e472e52c8c110ee6f32842d7
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #18622 from ziglang/zig-mod-edge-case

build system: better handle modules that do not have a zig root source file

3 files changed, 125 insertions(+), 63 deletions(-)

lib/std/Build/Step/Compile.zig+17-7
......@@ -1220,15 +1220,18 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
12201220 }
12211221 }
12221222
1223 // The CLI assumes if it sees a --mod argument that it is a zig
1224 // compilation unit. If there is no root source file, then this
1225 // is not a zig compilation unit - it is perhaps a set of
1226 // linker objects, or C source files instead.
1227 // In such case, there will be only one module, so we can leave
1228 // off the naming here.
1223 // When the CLI sees a -M argument, it determines whether it
1224 // implies the existence of a Zig compilation unit based on
1225 // whether there is a root source file. If there is no root
1226 // source file, then this is not a zig compilation unit - it is
1227 // perhaps a set of linker objects, or C source files instead.
1228 // Linker objects are added to the CLI globally, while C source
1229 // files must have a module parent.
12291230 if (module.root_source_file) |lp| {
12301231 const src = lp.getPath2(module.owner, step);
1231 try zig_args.appendSlice(&.{ "--mod", module_cli_name, src });
1232 try zig_args.append(b.fmt("-M{s}={s}", .{ module_cli_name, src }));
1233 } else if (moduleNeedsCliArg(module)) {
1234 try zig_args.append(b.fmt("-M{s}", .{module_cli_name}));
12321235 }
12331236 }
12341237 }
......@@ -1850,3 +1853,10 @@ pub fn rootModuleTarget(c: *Compile) std.Target {
18501853 // The root module is always given a target, so we know this to be non-null.
18511854 return c.root_module.resolved_target.?.result;
18521855}
1856
1857fn moduleNeedsCliArg(mod: *const Module) bool {
1858 return for (mod.link_objects.items) |o| switch (o) {
1859 .c_source_file, .c_source_files, .assembly_file, .win32_resource_file => break true,
1860 else => continue,
1861 } else false;
1862}
src/Compilation.zig+1-3
......@@ -1172,7 +1172,7 @@ fn addModuleTableToCacheHash(
11721172 hash.addOptionalBytes(mod.root.root_dir.path);
11731173 hash.addBytes(mod.root.sub_path);
11741174 },
1175 .files => |man| {
1175 .files => |man| if (mod.root_src_path.len != 0) {
11761176 const pkg_zig_file = try mod.root.joinString(arena, mod.root_src_path);
11771177 _ = try man.addFile(pkg_zig_file, null);
11781178 },
......@@ -2469,8 +2469,6 @@ fn addNonIncrementalStuffToCacheManifest(
24692469 comptime assert(link_hash_implementation_version == 11);
24702470
24712471 if (comp.module) |mod| {
2472 const main_zig_file = try mod.main_mod.root.joinString(arena, mod.main_mod.root_src_path);
2473 _ = try man.addFile(main_zig_file, null);
24742472 try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man });
24752473
24762474 // Synchronize with other matching comments: ZigOnlyHashStuff
src/main.zig+107-53
......@@ -409,10 +409,10 @@ const usage_build_generic =
409409 \\ --libc [file] Provide a file which specifies libc paths
410410 \\ -x language Treat subsequent input files as having type <language>
411411 \\ --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.
413413 \\ The first module is the main module.
414 \\ "std" can be configured by leaving src blank.
415 \\ After a --mod argument, per-module settings are reset.
414 \\ "std" can be configured by omitting src
415 \\ After a -M argument, per-module settings are reset.
416416 \\ --error-limit [num] Set the maximum amount of distinct error values
417417 \\ -fllvm Force using LLVM as the codegen backend
418418 \\ -fno-llvm Prevent using LLVM as the codegen backend
......@@ -1040,56 +1040,39 @@ fn buildOutputType(
10401040 .value = value,
10411041 });
10421042 } else if (mem.eql(u8, arg, "--mod")) {
1043 const mod_name = args_iter.nextOrFatal();
1044 const root_src_orig = args_iter.nextOrFatal();
1045
1046 const gop = try create_module.modules.getOrPut(arena, mod_name);
1047
1048 if (gop.found_existing) {
1049 fatal("unable to add module '{s}': already exists as '{s}'", .{
1050 mod_name, gop.value_ptr.paths.root_src_path,
1051 });
1052 }
1053
1054 // See duplicate logic: ModCreationGlobalFlags
1055 create_module.opts.have_zcu = true;
1056 if (mod_opts.single_threaded == false)
1057 create_module.opts.any_non_single_threaded = true;
1058 if (mod_opts.sanitize_thread == true)
1059 create_module.opts.any_sanitize_thread = true;
1060 if (mod_opts.unwind_tables == true)
1061 create_module.opts.any_unwind_tables = true;
1062 if (mod_opts.strip == false)
1063 create_module.opts.any_non_stripped = true;
1064 if (mod_opts.error_tracing == true)
1065 create_module.opts.any_error_tracing = true;
1066
1067 const root_src = try introspect.resolvePath(arena, root_src_orig);
1068 gop.value_ptr.* = .{
1069 .paths = .{
1070 .root = .{
1071 .root_dir = Cache.Directory.cwd(),
1072 .sub_path = fs.path.dirname(root_src) orelse "",
1073 },
1074 .root_src_path = fs.path.basename(root_src),
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;
1043 // deprecated, kept around until the next zig1.wasm update
1044 try handleModArg(
1045 arena,
1046 args_iter.nextOrFatal(),
1047 args_iter.nextOrFatal(),
1048 &create_module,
1049 &mod_opts,
1050 &cc_argv,
1051 &target_arch_os_abi,
1052 &target_mcpu,
1053 &deps,
1054 &c_source_files_owner_index,
1055 &rc_source_files_owner_index,
1056 &cssan,
1057 );
1058 } else if (mem.startsWith(u8, arg, "-M")) {
1059 var it = mem.splitScalar(u8, arg["-M".len..], '=');
1060 const mod_name = it.next().?;
1061 const root_src_orig = it.next();
1062 try handleModArg(
1063 arena,
1064 mod_name,
1065 root_src_orig,
1066 &create_module,
1067 &mod_opts,
1068 &cc_argv,
1069 &target_arch_os_abi,
1070 &target_mcpu,
1071 &deps,
1072 &c_source_files_owner_index,
1073 &rc_source_files_owner_index,
1074 &cssan,
1075 );
10931076 } else if (mem.eql(u8, arg, "--error-limit")) {
10941077 const next_arg = args_iter.nextOrFatal();
10951078 error_limit = std.fmt.parseUnsigned(Module.ErrorInt, next_arg, 0) catch |err| {
......@@ -7810,3 +7793,74 @@ fn parseImageBase(s: []const u8) u64 {
78107793 return std.fmt.parseUnsigned(u64, s, 0) catch |err|
78117794 fatal("unable to parse image base '{s}': {s}", .{ s, @errorName(err) });
78127795}
7796
7797fn handleModArg(
7798 arena: Allocator,
7799 mod_name: []const u8,
7800 opt_root_src_orig: ?[]const u8,
7801 create_module: *CreateModule,
7802 mod_opts: *Package.Module.CreateOptions.Inherited,
7803 cc_argv: *std.ArrayListUnmanaged([]const u8),
7804 target_arch_os_abi: *?[]const u8,
7805 target_mcpu: *?[]const u8,
7806 deps: *std.ArrayListUnmanaged(CliModule.Dep),
7807 c_source_files_owner_index: *usize,
7808 rc_source_files_owner_index: *usize,
7809 cssan: *ClangSearchSanitizer,
7810) !void {
7811 const gop = try create_module.modules.getOrPut(arena, mod_name);
7812
7813 if (gop.found_existing) {
7814 fatal("unable to add module '{s}': already exists as '{s}'", .{
7815 mod_name, gop.value_ptr.paths.root_src_path,
7816 });
7817 }
7818
7819 // See duplicate logic: ModCreationGlobalFlags
7820 if (mod_opts.single_threaded == false)
7821 create_module.opts.any_non_single_threaded = true;
7822 if (mod_opts.sanitize_thread == true)
7823 create_module.opts.any_sanitize_thread = true;
7824 if (mod_opts.unwind_tables == true)
7825 create_module.opts.any_unwind_tables = true;
7826 if (mod_opts.strip == false)
7827 create_module.opts.any_non_stripped = true;
7828 if (mod_opts.error_tracing == true)
7829 create_module.opts.any_error_tracing = true;
7830
7831 gop.value_ptr.* = .{
7832 .paths = p: {
7833 if (opt_root_src_orig) |root_src_orig| {
7834 create_module.opts.have_zcu = true;
7835 const root_src = try introspect.resolvePath(arena, root_src_orig);
7836 break :p .{
7837 .root = .{
7838 .root_dir = Cache.Directory.cwd(),
7839 .sub_path = fs.path.dirname(root_src) orelse "",
7840 },
7841 .root_src_path = fs.path.basename(root_src),
7842 };
7843 }
7844 break :p .{
7845 .root = .{ .root_dir = Cache.Directory.cwd() },
7846 .root_src_path = "",
7847 };
7848 },
7849 .cc_argv = try cc_argv.toOwnedSlice(arena),
7850 .inherited = mod_opts.*,
7851 .target_arch_os_abi = target_arch_os_abi.*,
7852 .target_mcpu = target_mcpu.*,
7853 .deps = try deps.toOwnedSlice(arena),
7854 .resolved = null,
7855 .c_source_files_start = c_source_files_owner_index.*,
7856 .c_source_files_end = create_module.c_source_files.items.len,
7857 .rc_source_files_start = rc_source_files_owner_index.*,
7858 .rc_source_files_end = create_module.rc_source_files.items.len,
7859 };
7860 cssan.reset();
7861 mod_opts.* = .{};
7862 target_arch_os_abi.* = null;
7863 target_mcpu.* = null;
7864 c_source_files_owner_index.* = create_module.c_source_files.items.len;
7865 rc_source_files_owner_index.* = create_module.rc_source_files.items.len;
7866}