authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-28 17:20:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 19:49:08-07:00
log8fa44969095caa293cb76b9a0b5fc0c0c270dc3b
tree7634043f2f9efee481d2b28a80464131b4b40420
parentb8674910d45f0b87f82376abbd7a705ad77fe79a

std.Build.Step.Compile: fix search prefix lowering

Instead of adding -I and -L flags at the end of the CLI, they need to be added for every module, after the module-specific flags.

1 files changed, 59 insertions(+), 51 deletions(-)

lib/std/Build/Step/Compile.zig+59-51
...@@ -894,9 +894,48 @@ fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_st...@@ -894,9 +894,48 @@ fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_st
894894
895fn make(step: *Step, prog_node: *std.Progress.Node) !void {895fn make(step: *Step, prog_node: *std.Progress.Node) !void {
896 const b = step.owner;896 const b = step.owner;
897 const arena = b.allocator;
897 const self = @fieldParentPtr(Compile, "step", step);898 const self = @fieldParentPtr(Compile, "step", step);
898899
899 var zig_args = ArrayList([]const u8).init(b.allocator);900 // Convert search prefixes to -I and -L arguments to be added at the end of
901 // each module's configuration.
902 var search_prefix_args: std.ArrayListUnmanaged([]const u8) = .{};
903 for (b.search_prefixes.items) |search_prefix| {
904 var prefix_dir = fs.cwd().openDir(search_prefix, .{}) catch |err| {
905 return step.fail("unable to open prefix directory '{s}': {s}", .{
906 search_prefix, @errorName(err),
907 });
908 };
909 defer prefix_dir.close();
910
911 // Avoid passing -L and -I flags for nonexistent directories.
912 // This prevents a warning, that should probably be upgraded to an error in Zig's
913 // CLI parsing code, when the linker sees an -L directory that does not exist.
914
915 if (prefix_dir.accessZ("lib", .{})) |_| {
916 try search_prefix_args.appendSlice(arena, &.{
917 "-L", try fs.path.join(arena, &.{ search_prefix, "lib" }),
918 });
919 } else |err| switch (err) {
920 error.FileNotFound => {},
921 else => |e| return step.fail("unable to access '{s}/lib' directory: {s}", .{
922 search_prefix, @errorName(e),
923 }),
924 }
925
926 if (prefix_dir.accessZ("include", .{})) |_| {
927 try search_prefix_args.appendSlice(arena, &.{
928 "-I", try fs.path.join(arena, &.{ search_prefix, "include" }),
929 });
930 } else |err| switch (err) {
931 error.FileNotFound => {},
932 else => |e| return step.fail("unable to access '{s}/include' directory: {s}", .{
933 search_prefix, @errorName(e),
934 }),
935 }
936 }
937
938 var zig_args = ArrayList([]const u8).init(arena);
900 defer zig_args.deinit();939 defer zig_args.deinit();
901940
902 try zig_args.append(b.zig_exe);941 try zig_args.append(b.zig_exe);
...@@ -910,14 +949,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -910,14 +949,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
910 try zig_args.append(cmd);949 try zig_args.append(cmd);
911950
912 if (b.reference_trace) |some| {951 if (b.reference_trace) |some| {
913 try zig_args.append(try std.fmt.allocPrint(b.allocator, "-freference-trace={d}", .{some}));952 try zig_args.append(try std.fmt.allocPrint(arena, "-freference-trace={d}", .{some}));
914 }953 }
915954
916 try addFlag(&zig_args, "llvm", self.use_llvm);955 try addFlag(&zig_args, "llvm", self.use_llvm);
917 try addFlag(&zig_args, "lld", self.use_lld);956 try addFlag(&zig_args, "lld", self.use_lld);
918957
919 if (self.root_module.resolved_target.?.query.ofmt) |ofmt| {958 if (self.root_module.resolved_target.?.query.ofmt) |ofmt| {
920 try zig_args.append(try std.fmt.allocPrint(b.allocator, "-ofmt={s}", .{@tagName(ofmt)}));959 try zig_args.append(try std.fmt.allocPrint(arena, "-ofmt={s}", .{@tagName(ofmt)}));
921 }960 }
922961
923 switch (self.entry) {962 switch (self.entry) {
...@@ -925,7 +964,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -925,7 +964,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
925 .disabled => try zig_args.append("-fno-entry"),964 .disabled => try zig_args.append("-fno-entry"),
926 .enabled => try zig_args.append("-fentry"),965 .enabled => try zig_args.append("-fentry"),
927 .symbol_name => |entry_name| {966 .symbol_name => |entry_name| {
928 try zig_args.append(try std.fmt.allocPrint(b.allocator, "-fentry={s}", .{entry_name}));967 try zig_args.append(try std.fmt.allocPrint(arena, "-fentry={s}", .{entry_name}));
929 },968 },
930 }969 }
931970
...@@ -939,7 +978,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -939,7 +978,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
939978
940 if (self.stack_size) |stack_size| {979 if (self.stack_size) |stack_size| {
941 try zig_args.append("--stack");980 try zig_args.append("--stack");
942 try zig_args.append(try std.fmt.allocPrint(b.allocator, "{}", .{stack_size}));981 try zig_args.append(try std.fmt.allocPrint(arena, "{}", .{stack_size}));
943 }982 }
944983
945 {984 {
...@@ -964,7 +1003,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -964,7 +1003,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
964 }1003 }
965 }1004 }
9661005
967 var cli_named_modules = try CliNamedModules.init(b.allocator, &self.root_module);1006 var cli_named_modules = try CliNamedModules.init(arena, &self.root_module);
9681007
969 // For this loop, don't chase dynamic libraries because their link1008 // For this loop, don't chase dynamic libraries because their link
970 // objects are already linked.1009 // objects are already linked.
...@@ -983,7 +1022,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -983,7 +1022,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
983 // Inherit dependencies on darwin frameworks.1022 // Inherit dependencies on darwin frameworks.
984 if (!already_linked) {1023 if (!already_linked) {
985 for (module.frameworks.keys(), module.frameworks.values()) |name, info| {1024 for (module.frameworks.keys(), module.frameworks.values()) |name, info| {
986 try frameworks.put(b.allocator, name, info);1025 try frameworks.put(arena, name, info);
987 }1026 }
988 }1027 }
9891028
...@@ -997,7 +1036,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -997,7 +1036,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
997 }1036 }
998 },1037 },
999 .system_lib => |system_lib| {1038 .system_lib => |system_lib| {
1000 if ((try seen_system_libs.fetchPut(b.allocator, system_lib.name, {})) != null)1039 if ((try seen_system_libs.fetchPut(arena, system_lib.name, {})) != null)
1001 continue;1040 continue;
10021041
1003 if (already_linked)1042 if (already_linked)
...@@ -1196,6 +1235,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1196,6 +1235,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1196 if (cli_named_modules.modules.getIndex(module)) |module_cli_index| {1235 if (cli_named_modules.modules.getIndex(module)) |module_cli_index| {
1197 const module_cli_name = cli_named_modules.names.keys()[module_cli_index];1236 const module_cli_name = cli_named_modules.names.keys()[module_cli_index];
1198 try module.appendZigProcessFlags(&zig_args, step);1237 try module.appendZigProcessFlags(&zig_args, step);
1238 // These go after `appendZigProcessFlags` so that
1239 // --search-prefix directories are prioritized lower than
1240 // per-module settings.
1241 try zig_args.appendSlice(search_prefix_args.items);
11991242
1200 // --dep arguments1243 // --dep arguments
1201 try zig_args.ensureUnusedCapacity(module.import_table.count() * 2);1244 try zig_args.ensureUnusedCapacity(module.import_table.count() * 2);
...@@ -1385,11 +1428,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1385,11 +1428,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1385 try zig_args.appendSlice(&[_][]const u8{ "--entitlements", entitlements });1428 try zig_args.appendSlice(&[_][]const u8{ "--entitlements", entitlements });
1386 }1429 }
1387 if (self.pagezero_size) |pagezero_size| {1430 if (self.pagezero_size) |pagezero_size| {
1388 const size = try std.fmt.allocPrint(b.allocator, "{x}", .{pagezero_size});1431 const size = try std.fmt.allocPrint(arena, "{x}", .{pagezero_size});
1389 try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size });1432 try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size });
1390 }1433 }
1391 if (self.headerpad_size) |headerpad_size| {1434 if (self.headerpad_size) |headerpad_size| {
1392 const size = try std.fmt.allocPrint(b.allocator, "{x}", .{headerpad_size});1435 const size = try std.fmt.allocPrint(arena, "{x}", .{headerpad_size});
1393 try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size });1436 try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size });
1394 }1437 }
1395 if (self.headerpad_max_install_names) {1438 if (self.headerpad_max_install_names) {
...@@ -1462,41 +1505,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1462,41 +1505,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1462 try zig_args.appendSlice(&[_][]const u8{ "--sysroot", sysroot });1505 try zig_args.appendSlice(&[_][]const u8{ "--sysroot", sysroot });
1463 }1506 }
14641507
1465 for (b.search_prefixes.items) |search_prefix| {
1466 var prefix_dir = fs.cwd().openDir(search_prefix, .{}) catch |err| {
1467 return step.fail("unable to open prefix directory '{s}': {s}", .{
1468 search_prefix, @errorName(err),
1469 });
1470 };
1471 defer prefix_dir.close();
1472
1473 // Avoid passing -L and -I flags for nonexistent directories.
1474 // This prevents a warning, that should probably be upgraded to an error in Zig's
1475 // CLI parsing code, when the linker sees an -L directory that does not exist.
1476
1477 if (prefix_dir.accessZ("lib", .{})) |_| {
1478 try zig_args.appendSlice(&.{
1479 "-L", try fs.path.join(b.allocator, &.{ search_prefix, "lib" }),
1480 });
1481 } else |err| switch (err) {
1482 error.FileNotFound => {},
1483 else => |e| return step.fail("unable to access '{s}/lib' directory: {s}", .{
1484 search_prefix, @errorName(e),
1485 }),
1486 }
1487
1488 if (prefix_dir.accessZ("include", .{})) |_| {
1489 try zig_args.appendSlice(&.{
1490 "-I", try fs.path.join(b.allocator, &.{ search_prefix, "include" }),
1491 });
1492 } else |err| switch (err) {
1493 error.FileNotFound => {},
1494 else => |e| return step.fail("unable to access '{s}/include' directory: {s}", .{
1495 search_prefix, @errorName(e),
1496 }),
1497 }
1498 }
1499
1500 if (self.rc_includes != .any) {1508 if (self.rc_includes != .any) {
1501 try zig_args.append("-rcincludes");1509 try zig_args.append("-rcincludes");
1502 try zig_args.append(@tagName(self.rc_includes));1510 try zig_args.append(@tagName(self.rc_includes));
...@@ -1554,12 +1562,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1554,12 +1562,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1554 try b.cache_root.handle.makePath("args");1562 try b.cache_root.handle.makePath("args");
15551563
1556 const args_to_escape = zig_args.items[2..];1564 const args_to_escape = zig_args.items[2..];
1557 var escaped_args = try ArrayList([]const u8).initCapacity(b.allocator, args_to_escape.len);1565 var escaped_args = try ArrayList([]const u8).initCapacity(arena, args_to_escape.len);
1558 arg_blk: for (args_to_escape) |arg| {1566 arg_blk: for (args_to_escape) |arg| {
1559 for (arg, 0..) |c, arg_idx| {1567 for (arg, 0..) |c, arg_idx| {
1560 if (c == '\\' or c == '"') {1568 if (c == '\\' or c == '"') {
1561 // Slow path for arguments that need to be escaped. We'll need to allocate and copy1569 // Slow path for arguments that need to be escaped. We'll need to allocate and copy
1562 var escaped = try ArrayList(u8).initCapacity(b.allocator, arg.len + 1);1570 var escaped = try ArrayList(u8).initCapacity(arena, arg.len + 1);
1563 const writer = escaped.writer();1571 const writer = escaped.writer();
1564 try writer.writeAll(arg[0..arg_idx]);1572 try writer.writeAll(arg[0..arg_idx]);
1565 for (arg[arg_idx..]) |to_escape| {1573 for (arg[arg_idx..]) |to_escape| {
...@@ -1575,8 +1583,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1575,8 +1583,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
15751583
1576 // Write the args to zig-cache/args/<SHA256 hash of args> to avoid conflicts with1584 // Write the args to zig-cache/args/<SHA256 hash of args> to avoid conflicts with
1577 // other zig build commands running in parallel.1585 // other zig build commands running in parallel.
1578 const partially_quoted = try std.mem.join(b.allocator, "\" \"", escaped_args.items);1586 const partially_quoted = try std.mem.join(arena, "\" \"", escaped_args.items);
1579 const args = try std.mem.concat(b.allocator, u8, &[_][]const u8{ "\"", partially_quoted, "\"" });1587 const args = try std.mem.concat(arena, u8, &[_][]const u8{ "\"", partially_quoted, "\"" });
15801588
1581 var args_hash: [Sha256.digest_length]u8 = undefined;1589 var args_hash: [Sha256.digest_length]u8 = undefined;
1582 Sha256.hash(args, &args_hash, .{});1590 Sha256.hash(args, &args_hash, .{});
...@@ -1590,9 +1598,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1590,9 +1598,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1590 const args_file = "args" ++ fs.path.sep_str ++ args_hex_hash;1598 const args_file = "args" ++ fs.path.sep_str ++ args_hex_hash;
1591 try b.cache_root.handle.writeFile(args_file, args);1599 try b.cache_root.handle.writeFile(args_file, args);
15921600
1593 const resolved_args_file = try mem.concat(b.allocator, u8, &.{1601 const resolved_args_file = try mem.concat(arena, u8, &.{
1594 "@",1602 "@",
1595 try b.cache_root.join(b.allocator, &.{args_file}),1603 try b.cache_root.join(arena, &.{args_file}),
1596 });1604 });
15971605
1598 zig_args.shrinkRetainingCapacity(2);1606 zig_args.shrinkRetainingCapacity(2);