| ... | @@ -4260,12 +4260,14 @@ pub const usage_libc = | ... | @@ -4260,12 +4260,14 @@ pub const usage_libc = |
| 4260 | \\Options: | 4260 | \\Options: |
| 4261 | \\ -h, --help Print this help and exit | 4261 | \\ -h, --help Print this help and exit |
| 4262 | \\ -target [name] <arch><sub>-<os>-<abi> see the targets command | 4262 | \\ -target [name] <arch><sub>-<os>-<abi> see the targets command |
| | 4263 | \\ -includes Print the libc include directories for the target |
| 4263 | \\ | 4264 | \\ |
| 4264 | ; | 4265 | ; |
| 4265 | | 4266 | |
| 4266 | pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { | 4267 | pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4267 | var input_file: ?[]const u8 = null; | 4268 | var input_file: ?[]const u8 = null; |
| 4268 | var target_arch_os_abi: []const u8 = "native"; | 4269 | var target_arch_os_abi: []const u8 = "native"; |
| | 4270 | var print_includes: bool = false; |
| 4269 | { | 4271 | { |
| 4270 | var i: usize = 0; | 4272 | var i: usize = 0; |
| 4271 | while (i < args.len) : (i += 1) { | 4273 | while (i < args.len) : (i += 1) { |
| ... | @@ -4279,6 +4281,8 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { | ... | @@ -4279,6 +4281,8 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4279 | if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg}); | 4281 | if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg}); |
| 4280 | i += 1; | 4282 | i += 1; |
| 4281 | target_arch_os_abi = args[i]; | 4283 | target_arch_os_abi = args[i]; |
| | 4284 | } else if (mem.eql(u8, arg, "-includes")) { |
| | 4285 | print_includes = true; |
| 4282 | } else { | 4286 | } else { |
| 4283 | fatal("unrecognized parameter: '{s}'", .{arg}); | 4287 | fatal("unrecognized parameter: '{s}'", .{arg}); |
| 4284 | } | 4288 | } |
| ... | @@ -4294,6 +4298,59 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { | ... | @@ -4294,6 +4298,59 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4294 | .arch_os_abi = target_arch_os_abi, | 4298 | .arch_os_abi = target_arch_os_abi, |
| 4295 | }); | 4299 | }); |
| 4296 | | 4300 | |
| | 4301 | if (print_includes) { |
| | 4302 | var arena_state = std.heap.ArenaAllocator.init(gpa); |
| | 4303 | defer arena_state.deinit(); |
| | 4304 | const arena = arena_state.allocator(); |
| | 4305 | |
| | 4306 | const libc_installation: ?*LibCInstallation = libc: { |
| | 4307 | if (input_file) |libc_file| { |
| | 4308 | var libc = try arena.create(LibCInstallation); |
| | 4309 | libc.* = LibCInstallation.parse(arena, libc_file, cross_target) catch |err| { |
| | 4310 | fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); |
| | 4311 | }; |
| | 4312 | break :libc libc; |
| | 4313 | } else { |
| | 4314 | break :libc null; |
| | 4315 | } |
| | 4316 | }; |
| | 4317 | |
| | 4318 | const self_exe_path = try introspect.findZigExePath(arena); |
| | 4319 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { |
| | 4320 | fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); |
| | 4321 | }; |
| | 4322 | defer zig_lib_directory.handle.close(); |
| | 4323 | |
| | 4324 | const target = cross_target.toTarget(); |
| | 4325 | const is_native_abi = cross_target.isNativeAbi(); |
| | 4326 | |
| | 4327 | var libc_dirs = Compilation.detectLibCIncludeDirs( |
| | 4328 | arena, |
| | 4329 | zig_lib_directory.path.?, |
| | 4330 | target, |
| | 4331 | is_native_abi, |
| | 4332 | true, |
| | 4333 | libc_installation, |
| | 4334 | ) catch |err| { |
| | 4335 | const zig_target = try target.zigTriple(arena); |
| | 4336 | fatal("unable to detect libc for target {s}: {s}", .{ zig_target, @errorName(err) }); |
| | 4337 | }; |
| | 4338 | |
| | 4339 | if (libc_dirs.libc_include_dir_list.len == 0) { |
| | 4340 | const zig_target = try target.zigTriple(arena); |
| | 4341 | fatal("no include dirs detected for target {s}", .{zig_target}); |
| | 4342 | } |
| | 4343 | |
| | 4344 | var bw = io.bufferedWriter(io.getStdOut().writer()); |
| | 4345 | var writer = bw.writer(); |
| | 4346 | for (libc_dirs.libc_include_dir_list) |include_dir| { |
| | 4347 | try writer.writeAll(include_dir); |
| | 4348 | try writer.writeByte('\n'); |
| | 4349 | } |
| | 4350 | try bw.flush(); |
| | 4351 | return cleanExit(); |
| | 4352 | } |
| | 4353 | |
| 4297 | if (input_file) |libc_file| { | 4354 | if (input_file) |libc_file| { |
| 4298 | var libc = LibCInstallation.parse(gpa, libc_file, cross_target) catch |err| { | 4355 | var libc = LibCInstallation.parse(gpa, libc_file, cross_target) catch |err| { |
| 4299 | fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); | 4356 | fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); |