authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 18:47:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 19:49:08-07:00
logeae6d45cded76dd027569c86a7cdd5bc9039664b
treec08ca87ed0d8b59154d2ce321ab8cfcf8be72a0d
parent7cec11a66bfd9d38bd355ba55aca4fa0e61ba4b5

CLI: introduce global -I args for C include paths

This isn't technically needed since per-module -I args can suffice, but this can produce very long CLI invocations when several --mod args are combined with --search-prefix args since the -I args have to be repeated for each module. This is a partial revert of ecbe8bbf2df2ed4d473efbc32e0b6d7091fba76f.

3 files changed, 50 insertions(+), 45 deletions(-)

lib/std/Build/Step/Compile.zig+36-42
......@@ -897,44 +897,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
897897 const arena = b.allocator;
898898 const self = @fieldParentPtr(Compile, "step", step);
899899
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
938900 var zig_args = ArrayList([]const u8).init(arena);
939901 defer zig_args.deinit();
940902
......@@ -1235,10 +1197,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
12351197 if (cli_named_modules.modules.getIndex(module)) |module_cli_index| {
12361198 const module_cli_name = cli_named_modules.names.keys()[module_cli_index];
12371199 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);
12421200
12431201 // --dep arguments
12441202 try zig_args.ensureUnusedCapacity(module.import_table.count() * 2);
......@@ -1505,6 +1463,42 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
15051463 try zig_args.appendSlice(&[_][]const u8{ "--sysroot", sysroot });
15061464 }
15071465
1466 // -I and -L arguments that appear after the last --mod argument apply to all modules.
1467 for (b.search_prefixes.items) |search_prefix| {
1468 var prefix_dir = fs.cwd().openDir(search_prefix, .{}) catch |err| {
1469 return step.fail("unable to open prefix directory '{s}': {s}", .{
1470 search_prefix, @errorName(err),
1471 });
1472 };
1473 defer prefix_dir.close();
1474
1475 // Avoid passing -L and -I flags for nonexistent directories.
1476 // This prevents a warning, that should probably be upgraded to an error in Zig's
1477 // CLI parsing code, when the linker sees an -L directory that does not exist.
1478
1479 if (prefix_dir.accessZ("lib", .{})) |_| {
1480 try zig_args.appendSlice(&.{
1481 "-L", try fs.path.join(arena, &.{ search_prefix, "lib" }),
1482 });
1483 } else |err| switch (err) {
1484 error.FileNotFound => {},
1485 else => |e| return step.fail("unable to access '{s}/lib' directory: {s}", .{
1486 search_prefix, @errorName(e),
1487 }),
1488 }
1489
1490 if (prefix_dir.accessZ("include", .{})) |_| {
1491 try zig_args.appendSlice(&.{
1492 "-I", try fs.path.join(arena, &.{ search_prefix, "include" }),
1493 });
1494 } else |err| switch (err) {
1495 error.FileNotFound => {},
1496 else => |e| return step.fail("unable to access '{s}/include' directory: {s}", .{
1497 search_prefix, @errorName(e),
1498 }),
1499 }
1500 }
1501
15081502 if (self.rc_includes != .any) {
15091503 try zig_args.append("-rcincludes");
15101504 try zig_args.append(@tagName(self.rc_includes));
src/Compilation.zig+7
......@@ -165,6 +165,7 @@ last_update_was_cache_hit: bool = false,
165165
166166c_source_files: []const CSourceFile,
167167rc_source_files: []const RcSourceFile,
168global_cc_argv: []const []const u8,
168169cache_parent: *Cache,
169170/// Path to own executable for invoking `zig clang`.
170171self_exe_path: ?[]const u8,
......@@ -1120,6 +1121,7 @@ pub const CreateOptions = struct {
11201121 /// (Windows) PDB output path
11211122 pdb_out_path: ?[]const u8 = null,
11221123 error_limit: ?Compilation.Module.ErrorInt = null,
1124 global_cc_argv: []const []const u8 = &.{},
11231125
11241126 pub const Entry = link.File.OpenOptions.Entry;
11251127};
......@@ -1515,6 +1517,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
15151517 .wasi_emulated_libs = options.wasi_emulated_libs,
15161518 .force_undefined_symbols = options.force_undefined_symbols,
15171519 .link_eh_frame_hdr = link_eh_frame_hdr,
1520 .global_cc_argv = options.global_cc_argv,
15181521 };
15191522
15201523 // Prevent some footguns by making the "any" fields of config reflect
......@@ -2527,6 +2530,8 @@ fn addNonIncrementalStuffToCacheManifest(
25272530 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_ir);
25282531 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);
25292532
2533 man.hash.addListOfBytes(comp.global_cc_argv);
2534
25302535 const opts = comp.cache_use.whole.lf_open_opts;
25312536
25322537 try man.addOptionalFile(opts.linker_script);
......@@ -3941,6 +3946,7 @@ pub fn obtainCObjectCacheManifest(
39413946 // that apply both to @cImport and compiling C objects. No linking stuff here!
39423947 // Also nothing that applies only to compiling .zig code.
39433948 cache_helpers.addModule(&man.hash, owner_mod);
3949 man.hash.addListOfBytes(comp.global_cc_argv);
39443950 man.hash.add(comp.config.link_libcpp);
39453951
39463952 // When libc_installation is null it means that Zig generated this dir list
......@@ -5411,6 +5417,7 @@ pub fn addCCArgs(
54115417 }
54125418 }
54135419
5420 try argv.appendSlice(comp.global_cc_argv);
54145421 try argv.appendSlice(mod.cc_argv);
54155422}
54165423
src/main.zig+7-3
......@@ -3244,6 +3244,10 @@ fn buildOutputType(
32443244 .pdb_out_path = pdb_out_path,
32453245 .error_limit = error_limit,
32463246 .native_system_include_paths = create_module.native_system_include_paths,
3247 // Any leftover C compilation args (such as -I) apply globally rather
3248 // than to any particular module. This feature can greatly reduce CLI
3249 // noise when --search-prefix and --mod are combined.
3250 .global_cc_argv = try cc_argv.toOwnedSlice(arena),
32473251 }) catch |err| switch (err) {
32483252 error.LibCUnavailable => {
32493253 const triple_name = try target.zigTriple(arena);
......@@ -3421,9 +3425,9 @@ const CreateModule = struct {
34213425 c_source_files: std.ArrayListUnmanaged(Compilation.CSourceFile),
34223426 rc_source_files: std.ArrayListUnmanaged(Compilation.RcSourceFile),
34233427
3424 // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.
3425 // This array is populated by zig cc frontend and then has to be converted to zig-style
3426 // CPU features.
3428 /// e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.
3429 /// This array is populated by zig cc frontend and then has to be converted to zig-style
3430 /// CPU features.
34273431 llvm_m_args: std.ArrayListUnmanaged([]const u8),
34283432 sysroot: ?[]const u8,
34293433 lib_dirs: std.ArrayListUnmanaged([]const u8),