diff --git a/lib/compiler/Maker.zig b/lib/compiler/Maker.zig index cb252f1509713ecf1ae6fc88f8f7783cf3bd4d24..8e5bcf2474983422f72b753a866d638439503979 100644 --- a/lib/compiler/Maker.zig +++ b/lib/compiler/Maker.zig @@ -187,9 +187,10 @@ pub fn main(init: process.Init.Minimal) !void { .random_seed = parseRandomSeed(seed_arg), }; - const cmd = stringToEnum(enum { init, fetch, build }, cmd_name) orelse + const cmd = stringToEnum(enum { libc, init, fetch, build }, cmd_name) orelse fatal("bad command name: {q}", .{cmd_name}); switch (cmd) { + .libc => return cmdLibC(gpa, &graph, args[arg_i..]), .init => return cmdInit(gpa, &graph, args[arg_i..]), .fetch => return cmdFetch(gpa, &graph, args[arg_i..]), .build => {}, @@ -1746,6 +1747,25 @@ const usage_init = \\ ; +const usage_libc = + \\Usage: zig libc + \\ + \\ Detect the native libc installation and print the resulting + \\ paths to stdout. You can save this into a file and then edit + \\ the paths to create a cross compilation libc kit. Then you + \\ can pass `--libc [file]` for Zig to use it. + \\ + \\Usage: zig libc [paths_file] + \\ + \\ Parse a libc installation text file and validate it. + \\ + \\Options: + \\ -h, --help Print this help and exit + \\ -target [name] -- see the targets command + \\ -includes Print the libc include directories for the target + \\ +; + fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void { const arena = graph.arena; const io = graph.io; @@ -1851,6 +1871,112 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void { } } +fn cmdLibC(gpa: Allocator, graph: *Graph, args: []const []const u8) !void { + const environ_map = &graph.environ_map; + const io = graph.io; + const arena = graph.arena; + const LibCInstallation = std.zig.LibCInstallation; + + var input_file: ?[]const u8 = null; + var target_arch_os_abi: []const u8 = "native"; + var print_includes: bool = false; + const stdout = initStdoutWriter(io); + { + var i: usize = 0; + while (i < args.len) : (i += 1) { + const arg = args[i]; + if (mem.startsWith(u8, arg, "-")) { + if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { + try stdout.writeAll(usage_libc); + try stdout.flush(); + return std.process.cleanExit(io); + } else if (mem.eql(u8, arg, "-target")) { + 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}); + } + } else if (input_file != null) { + fatal("unexpected extra parameter: '{s}'", .{arg}); + } else { + input_file = arg; + } + } + } + + const target_query = std.zig.parseTargetQueryOrReportFatalError(gpa, .{ + .arch_os_abi = target_arch_os_abi, + }); + const target = std.zig.resolveTargetQueryOrFatal(io, target_query); + + if (print_includes) { + const libc_installation: ?*LibCInstallation = libc: { + if (input_file) |libc_file| { + const libc = try arena.create(LibCInstallation); + libc.* = LibCInstallation.parse(arena, io, libc_file, &target) catch |err| { + fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err }); + }; + break :libc libc; + } else { + break :libc null; + } + }; + + const is_native_abi = target_query.isNativeAbi(); + + const libc_dirs = std.zig.LibCDirs.detect( + arena, + io, + .{ .root_dir = graph.zig_lib_directory }, + &target, + is_native_abi, + true, + libc_installation, + environ_map, + ) catch |err| { + const zig_target = try target.zigTriple(arena); + fatal("unable to detect libc for target {s}: {t}", .{ zig_target, 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}); + } + + for (libc_dirs.libc_include_dir_list) |include_dir| { + try stdout.writeAll(include_dir); + try stdout.writeByte('\n'); + } + try stdout.flush(); + return std.process.cleanExit(io); + } + + if (input_file) |libc_file| { + var libc = LibCInstallation.parse(gpa, io, libc_file, &target) catch |err| { + fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err }); + }; + defer libc.deinit(gpa); + } else { + if (!target_query.canDetectLibC()) { + fatal("unable to detect libc for non-native target", .{}); + } + var libc = LibCInstallation.findNative(gpa, io, .{ + .verbose = true, + .target = &target, + .environ_map = environ_map, + }) catch |err| { + fatal("unable to detect native libc: {t}", .{err}); + }; + defer libc.deinit(gpa); + + try libc.render(stdout); + try stdout.flush(); + } +} + fn markFailedStepsDirty(maker: *Maker) void { const all_steps = maker.step_stack.keys(); diff --git a/lib/compiler/libc.zig b/lib/compiler/libc.zig deleted file mode 100644 index 8ca53fefc905c01527c7157bee4c0d10575e582e..0000000000000000000000000000000000000000 --- a/lib/compiler/libc.zig +++ /dev/null @@ -1,140 +0,0 @@ -const std = @import("std"); -const Io = std.Io; -const mem = std.mem; -const LibCInstallation = std.zig.LibCInstallation; - -const usage_libc = - \\Usage: zig libc - \\ - \\ Detect the native libc installation and print the resulting - \\ paths to stdout. You can save this into a file and then edit - \\ the paths to create a cross compilation libc kit. Then you - \\ can pass `--libc [file]` for Zig to use it. - \\ - \\Usage: zig libc [paths_file] - \\ - \\ Parse a libc installation text file and validate it. - \\ - \\Options: - \\ -h, --help Print this help and exit - \\ -target [name] -- see the targets command - \\ -includes Print the libc include directories for the target - \\ -; - -var stdout_buffer: [4096]u8 = undefined; - -pub fn main(init: std.process.Init) !void { - const arena = init.arena.allocator(); - const gpa = init.gpa; - const io = init.io; - const args = try init.minimal.args.toSlice(arena); - const environ_map = init.environ_map; - - const zig_lib_directory = args[1]; - - var input_file: ?[]const u8 = null; - var target_arch_os_abi: []const u8 = "native"; - var print_includes: bool = false; - var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); - const stdout = &stdout_writer.interface; - { - var i: usize = 2; - while (i < args.len) : (i += 1) { - const arg = args[i]; - if (mem.startsWith(u8, arg, "-")) { - if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - try stdout.writeAll(usage_libc); - try stdout.flush(); - return std.process.cleanExit(io); - } else if (mem.eql(u8, arg, "-target")) { - 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}); - } - } else if (input_file != null) { - fatal("unexpected extra parameter: '{s}'", .{arg}); - } else { - input_file = arg; - } - } - } - - const target_query = std.zig.parseTargetQueryOrReportFatalError(gpa, .{ - .arch_os_abi = target_arch_os_abi, - }); - const target = std.zig.resolveTargetQueryOrFatal(io, target_query); - - if (print_includes) { - const libc_installation: ?*LibCInstallation = libc: { - if (input_file) |libc_file| { - const libc = try arena.create(LibCInstallation); - libc.* = LibCInstallation.parse(arena, io, libc_file, &target) catch |err| { - fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err }); - }; - break :libc libc; - } else { - break :libc null; - } - }; - - const is_native_abi = target_query.isNativeAbi(); - - const libc_dirs = std.zig.LibCDirs.detect( - arena, - io, - zig_lib_directory, - &target, - is_native_abi, - true, - libc_installation, - environ_map, - ) catch |err| { - const zig_target = try target.zigTriple(arena); - fatal("unable to detect libc for target {s}: {t}", .{ zig_target, 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}); - } - - for (libc_dirs.libc_include_dir_list) |include_dir| { - try stdout.writeAll(include_dir); - try stdout.writeByte('\n'); - } - try stdout.flush(); - return std.process.cleanExit(io); - } - - if (input_file) |libc_file| { - var libc = LibCInstallation.parse(gpa, io, libc_file, &target) catch |err| { - fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err }); - }; - defer libc.deinit(gpa); - } else { - if (!target_query.canDetectLibC()) { - fatal("unable to detect libc for non-native target", .{}); - } - var libc = LibCInstallation.findNative(gpa, io, .{ - .verbose = true, - .target = &target, - .environ_map = environ_map, - }) catch |err| { - fatal("unable to detect native libc: {t}", .{err}); - }; - defer libc.deinit(gpa); - - try libc.render(stdout); - try stdout.flush(); - } -} - -fn fatal(comptime format: []const u8, args: anytype) noreturn { - std.log.err(format, args); - std.process.exit(1); -} diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index e962177015641502fdce3bcd6d9b6adf1195d0e3..170a6c02d3606a93c43c85901157da4c967bb0d3 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -639,7 +639,7 @@ fn getIncludePaths( }; const target = std.zig.resolveTargetQueryOrFatal(io, target_query); const is_native_abi = target_query.isNativeAbi(); - const detected_libc = std.zig.LibCDirs.detect(arena, io, zig_lib_dir, &target, is_native_abi, true, null, environ_map) catch { + const detected_libc = std.zig.LibCDirs.detect(arena, io, .{ .root_dir = .cwd, .sub_path = zig_lib_dir }, &target, is_native_abi, true, null, environ_map) catch { if (includes == .any) { // fall back to mingw includes = .gnu; @@ -668,7 +668,7 @@ fn getIncludePaths( const detected_libc = std.zig.LibCDirs.detect( arena, io, - zig_lib_dir, + .{ .root_dir = .cwd, .sub_path = zig_lib_dir }, &target, is_native_abi, true, diff --git a/lib/std/zig/LibCDirs.zig b/lib/std/zig/LibCDirs.zig index 04c61af0bedab6728309db7c00c975ef4229a57d..84002241bf9ea4fb1dbf5f8702a4723c05a01694 100644 --- a/lib/std/zig/LibCDirs.zig +++ b/lib/std/zig/LibCDirs.zig @@ -5,6 +5,7 @@ const std = @import("../std.zig"); const Io = std.Io; const LibCInstallation = std.zig.LibCInstallation; const Allocator = std.mem.Allocator; +const Path = std.Build.Cache.Path; libc_include_dir_list: []const []const u8, libc_installation: ?*const LibCInstallation, @@ -23,7 +24,7 @@ pub const DarwinSdkLayout = enum { pub fn detect( arena: Allocator, io: Io, - zig_lib_dir: []const u8, + zig_lib_dir: Path, target: *const std.Target, is_native_abi: bool, link_libc: bool, @@ -166,20 +167,12 @@ fn detectFromInstallation(arena: Allocator, target: *const std.Target, lci: *con }; } -pub fn detectFromBuilding( - arena: Allocator, - zig_lib_dir: []const u8, - target: *const std.Target, -) !LibCDirs { +pub fn detectFromBuilding(arena: Allocator, zig_lib_dir: Path, target: *const std.Target) !LibCDirs { const s = std.fs.path.sep_str; if (target.os.tag.isDarwin()) { const list = try arena.alloc([]const u8, 1); - list[0] = try std.fmt.allocPrint( - arena, - "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-darwin-any", - .{zig_lib_dir}, - ); + list[0] = try arena.print("{f}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-darwin-any", .{zig_lib_dir}); return .{ .libc_include_dir_list = list, .libc_installation = null, @@ -212,27 +205,19 @@ pub fn detectFromBuilding( std.zig.target.netbsdAbiNameHeaders(target.abi) else @tagName(target.abi); - const arch_include_dir = try std.fmt.allocPrint( - arena, - "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}", - .{ zig_lib_dir, arch_name, os_name, abi_name }, - ); - const generic_include_dir = try std.fmt.allocPrint( - arena, - "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "generic-{s}", - .{ zig_lib_dir, generic_name }, - ); + const arch_include_dir = try arena.print("{f}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}", .{ + zig_lib_dir, arch_name, os_name, abi_name, + }); + const generic_include_dir = try arena.print("{f}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "generic-{s}", .{ + zig_lib_dir, generic_name, + }); const generic_arch_name = std.zig.target.osArchName(target); - const arch_os_include_dir = try std.fmt.allocPrint( - arena, - "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-any", - .{ zig_lib_dir, generic_arch_name, os_name }, - ); - const generic_os_include_dir = try std.fmt.allocPrint( - arena, - "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any", - .{ zig_lib_dir, os_name }, - ); + const arch_os_include_dir = try arena.print("{f}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-any", .{ + zig_lib_dir, generic_arch_name, os_name, + }); + const generic_os_include_dir = try arena.print("{f}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any", .{ + zig_lib_dir, os_name, + }); const list = try arena.alloc([]const u8, 4); list[0] = arch_include_dir; diff --git a/src/Compilation.zig b/src/Compilation.zig index 3bdc049c3e3ba307a1430027567d50e39b346e1f..1e9b81d493d62ceea21fb74b3786677b119eb9b4 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1729,7 +1729,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, const libc_dirs = std.zig.LibCDirs.detect( arena, io, - options.dirs.zig_lib.path.?, + .{ .root_dir = options.dirs.zig_lib }, target, options.root_mod.resolved_target.is_native_abi, link_libc, diff --git a/src/main.zig b/src/main.zig index 2213920e32ac4402c401f9b1cdf7b8abe9c75c8b..47bf6d2f49517e235cb86ded97a665d8c5c5192e 100644 --- a/src/main.zig +++ b/src/main.zig @@ -352,7 +352,7 @@ fn mainArgs( dev.check(.ar_command); return process.exit(try llvmArMain(arena, args)); }, - .build, .fetch, .init => { + .build, .fetch, .init, .libc => { return jitCmd(gpa, arena, io, cmd_args, environ_map, .{ .cmd_name = "maker", .root_src_path = "Maker.zig", @@ -409,13 +409,6 @@ fn mainArgs( .root_src_path = "objdump.zig", }); }, - .libc => { - return jitCmd(gpa, arena, io, cmd_args, environ_map, .{ - .cmd_name = "libc", - .root_src_path = "libc.zig", - .prepend_zig_lib_dir_path = true, - }); - }, .std => { return jitCmd(gpa, arena, io, cmd_args, environ_map, .{ .cmd_name = "std",