diff --git a/src/Compilation.zig b/src/Compilation.zig index ae1e1072f397..0150d615e37f 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -4887,7 +4887,7 @@ fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8, }; } -fn detectLibCIncludeDirs( +pub fn detectLibCIncludeDirs( arena: Allocator, zig_lib_dir: []const u8, target: Target, diff --git a/src/main.zig b/src/main.zig index 5848961052f5..6e7b330c407b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4260,12 +4260,14 @@ pub const usage_libc = \\Options: \\ -h, --help Print this help and exit \\ -target [name] <arch><sub>-<os>-<abi> see the targets command + \\ -includes Print the libc include directories for the target \\ ; pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { var input_file: ?[]const u8 = null; var target_arch_os_abi: []const u8 = "native"; + var print_includes: bool = false; { var i: usize = 0; while (i < args.len) : (i += 1) { @@ -4279,6 +4281,8 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg}); i += 1; target_arch_os_abi = args[i]; + } else if (mem.eql(u8, arg, "-includes")) { + print_includes = true; } else { fatal("unrecognized parameter: '{s}'", .{arg}); } @@ -4294,6 +4298,59 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { .arch_os_abi = target_arch_os_abi, }); + if (print_includes) { + var arena_state = std.heap.ArenaAllocator.init(gpa); + defer arena_state.deinit(); + const arena = arena_state.allocator(); + + const libc_installation: ?*LibCInstallation = libc: { + if (input_file) |libc_file| { + var libc = try arena.create(LibCInstallation); + libc.* = LibCInstallation.parse(arena, libc_file, cross_target) catch |err| { + fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); + }; + break :libc libc; + } else { + break :libc null; + } + }; + + const self_exe_path = try introspect.findZigExePath(arena); + var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { + fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); + }; + defer zig_lib_directory.handle.close(); + + const target = cross_target.toTarget(); + const is_native_abi = cross_target.isNativeAbi(); + + var libc_dirs = Compilation.detectLibCIncludeDirs( + arena, + zig_lib_directory.path.?, + target, + is_native_abi, + true, + libc_installation, + ) catch |err| { + const zig_target = try target.zigTriple(arena); + fatal("unable to detect libc for target {s}: {s}", .{ zig_target, @errorName(err) }); + }; + + if (libc_dirs.libc_include_dir_list.len == 0) { + const zig_target = try target.zigTriple(arena); + fatal("no include dirs detected for target {s}", .{zig_target}); + } + + var bw = io.bufferedWriter(io.getStdOut().writer()); + var writer = bw.writer(); + for (libc_dirs.libc_include_dir_list) |include_dir| { + try writer.writeAll(include_dir); + try writer.writeByte('\n'); + } + try bw.flush(); + return cleanExit(); + } + if (input_file) |libc_file| { var libc = LibCInstallation.parse(gpa, libc_file, cross_target) catch |err| { fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });