libc.zig (4869B) - Raw
1 const std = @import("std"); 2 const mem = std.mem; 3 const io = std.io; 4 const LibCInstallation = std.zig.LibCInstallation; 5 6 const usage_libc = 7 \\Usage: zig libc 8 \\ 9 \\ Detect the native libc installation and print the resulting 10 \\ paths to stdout. You can save this into a file and then edit 11 \\ the paths to create a cross compilation libc kit. Then you 12 \\ can pass `--libc [file]` for Zig to use it. 13 \\ 14 \\Usage: zig libc [paths_file] 15 \\ 16 \\ Parse a libc installation text file and validate it. 17 \\ 18 \\Options: 19 \\ -h, --help Print this help and exit 20 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command 21 \\ -includes Print the libc include directories for the target 22 \\ 23 ; 24 25 var stdout_buffer: [4096]u8 = undefined; 26 27 pub fn main() !void { 28 var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); 29 defer arena_instance.deinit(); 30 const arena = arena_instance.allocator(); 31 const gpa = arena; 32 33 const args = try std.process.argsAlloc(arena); 34 const zig_lib_directory = args[1]; 35 36 var input_file: ?[]const u8 = null; 37 var target_arch_os_abi: []const u8 = "native"; 38 var print_includes: bool = false; 39 var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); 40 const stdout = &stdout_writer.interface; 41 { 42 var i: usize = 2; 43 while (i < args.len) : (i += 1) { 44 const arg = args[i]; 45 if (mem.startsWith(u8, arg, "-")) { 46 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { 47 try stdout.writeAll(usage_libc); 48 try stdout.flush(); 49 return std.process.cleanExit(); 50 } else if (mem.eql(u8, arg, "-target")) { 51 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg}); 52 i += 1; 53 target_arch_os_abi = args[i]; 54 } else if (mem.eql(u8, arg, "-includes")) { 55 print_includes = true; 56 } else { 57 fatal("unrecognized parameter: '{s}'", .{arg}); 58 } 59 } else if (input_file != null) { 60 fatal("unexpected extra parameter: '{s}'", .{arg}); 61 } else { 62 input_file = arg; 63 } 64 } 65 } 66 67 const target_query = std.zig.parseTargetQueryOrReportFatalError(gpa, .{ 68 .arch_os_abi = target_arch_os_abi, 69 }); 70 const target = std.zig.resolveTargetQueryOrFatal(target_query); 71 72 if (print_includes) { 73 const libc_installation: ?*LibCInstallation = libc: { 74 if (input_file) |libc_file| { 75 const libc = try arena.create(LibCInstallation); 76 libc.* = LibCInstallation.parse(arena, libc_file, &target) catch |err| { 77 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); 78 }; 79 break :libc libc; 80 } else { 81 break :libc null; 82 } 83 }; 84 85 const is_native_abi = target_query.isNativeAbi(); 86 87 const libc_dirs = std.zig.LibCDirs.detect( 88 arena, 89 zig_lib_directory, 90 &target, 91 is_native_abi, 92 true, 93 libc_installation, 94 ) catch |err| { 95 const zig_target = try target.zigTriple(arena); 96 fatal("unable to detect libc for target {s}: {s}", .{ zig_target, @errorName(err) }); 97 }; 98 99 if (libc_dirs.libc_include_dir_list.len == 0) { 100 const zig_target = try target.zigTriple(arena); 101 fatal("no include dirs detected for target {s}", .{zig_target}); 102 } 103 104 for (libc_dirs.libc_include_dir_list) |include_dir| { 105 try stdout.writeAll(include_dir); 106 try stdout.writeByte('\n'); 107 } 108 try stdout.flush(); 109 return std.process.cleanExit(); 110 } 111 112 if (input_file) |libc_file| { 113 var libc = LibCInstallation.parse(gpa, libc_file, &target) catch |err| { 114 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); 115 }; 116 defer libc.deinit(gpa); 117 } else { 118 if (!target_query.canDetectLibC()) { 119 fatal("unable to detect libc for non-native target", .{}); 120 } 121 var libc = LibCInstallation.findNative(.{ 122 .allocator = gpa, 123 .verbose = true, 124 .target = &target, 125 }) catch |err| { 126 fatal("unable to detect native libc: {s}", .{@errorName(err)}); 127 }; 128 defer libc.deinit(gpa); 129 130 try libc.render(stdout); 131 try stdout.flush(); 132 } 133 } 134 135 fn fatal(comptime format: []const u8, args: anytype) noreturn { 136 std.log.err(format, args); 137 std.process.exit(1); 138 }