better handle program arguments with commands

This commit is contained in:
David Gonzalez Martin 2024-01-29 09:11:59 +01:00
parent 9f452afa43
commit 2171511c91
4 changed files with 102 additions and 45 deletions

View File

@ -32,9 +32,25 @@ fn reportUnterminatedArgumentError(string: []const u8) noreturn {
std.debug.panic("Unterminated argument: {s}", .{string}); std.debug.panic("Unterminated argument: {s}", .{string});
} }
fn parseArguments(context: *const Context) !Descriptor { pub fn foo(context: *const Context) !Descriptor {
const allocator = context.allocator; _ = context; // autofix
const arguments = (try std.process.argsAlloc(allocator))[1..]; }
pub fn buildExecutable(allocator: Allocator, arguments: [][:0]u8) !void {
const context: *Context = try allocator.create(Context);
const self_exe_path = try std.fs.selfExePathAlloc(allocator);
const self_exe_dir_path = std.fs.path.dirname(self_exe_path).?;
context.* = .{
.allocator = allocator,
.cwd_absolute_path = try realpathAlloc(allocator, "."),
.executable_absolute_path = self_exe_path,
.directory_absolute_path = self_exe_dir_path,
.build_directory = try std.fs.cwd().makeOpenPath("nat", .{}),
};
try context.build_directory.makePath(cache_dir_name);
try context.build_directory.makePath(installation_dir_name);
var maybe_executable_path: ?[]const u8 = null; var maybe_executable_path: ?[]const u8 = null;
var maybe_main_package_path: ?[]const u8 = null; var maybe_main_package_path: ?[]const u8 = null;
@ -196,7 +212,9 @@ fn parseArguments(context: *const Context) !Descriptor {
break :blk result; break :blk result;
}; };
return .{ const unit = try context.allocator.create(Unit);
unit.* = .{
.descriptor = .{
.main_package_path = main_package_path, .main_package_path = main_package_path,
.executable_path = executable_path, .executable_path = executable_path,
.target = target, .target = target,
@ -210,29 +228,9 @@ fn parseArguments(context: *const Context) !Descriptor {
}, },
.generate_debug_information = generate_debug_information, .generate_debug_information = generate_debug_information,
.name = executable_name, .name = executable_name,
}; },
}
pub fn init(allocator: Allocator) !void {
const context: *Context = try allocator.create(Context);
const self_exe_path = try std.fs.selfExePathAlloc(allocator);
const self_exe_dir_path = std.fs.path.dirname(self_exe_path).?;
context.* = .{
.allocator = allocator,
.cwd_absolute_path = try realpathAlloc(allocator, "."),
.executable_absolute_path = self_exe_path,
.directory_absolute_path = self_exe_dir_path,
.build_directory = try std.fs.cwd().makeOpenPath("nat", .{}),
}; };
try context.build_directory.makePath(cache_dir_name);
try context.build_directory.makePath(installation_dir_name);
const unit = try context.allocator.create(Unit);
unit.* = .{
.descriptor = try parseArguments(context),
};
try unit.compile(context); try unit.compile(context);
} }

View File

@ -1,14 +1,66 @@
const std = @import("std"); const std = @import("std");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const equal = std.mem.eql;
const Compilation = @import("Compilation.zig"); const Compilation = @import("Compilation.zig");
pub const panic = Compilation.panic; pub const panic = Compilation.panic;
pub fn main() !void { const env_detecting_libc_paths = "NATIVITY_IS_DETECTING_LIBC_PATHS";
var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);
try Compilation.init(arena_allocator.allocator()); fn todo() noreturn {
@setCold(true);
@panic("TODO");
} }
test { pub fn main() !void {
_ = Compilation; var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = arena_allocator.allocator();
const arguments = try std.process.argsAlloc(allocator);
if (arguments.len <= 1) {
return error.InvalidInput;
}
if (std.process.can_execv and std.os.getenvZ(env_detecting_libc_paths) != null) {
todo();
}
const command = arguments[1];
const command_arguments = arguments[2..];
if (equal(u8, command, "build")) {
todo();
} else if (equal(u8, command, "clang") or equal(u8, command, "-cc1") or equal(u8, command, "-cc1as")) {
const exit_code = try clangMain(allocator, arguments);
std.process.exit(exit_code);
} else if (equal(u8, command, "cc")) {
// TODO: transform our arguments to Clang and invoke it
todo();
} else if (equal(u8, command, "c++")) {
// TODO: transform our arguments to Clang and invoke it
todo();
} else if (equal(u8, command, "exe")) {
try Compilation.buildExecutable(allocator, command_arguments);
} else if (equal(u8, command, "lib")) {
todo();
} else if (equal(u8, command, "obj")) {
todo();
} else {
todo();
}
}
fn argsCopyZ(alloc: Allocator, args: []const []const u8) ![:null]?[*:0]u8 {
var argv = try alloc.allocSentinel(?[*:0]u8, args.len, null);
for (args, 0..) |arg, i| {
argv[i] = try alloc.dupeZ(u8, arg); // TODO If there was an argsAllocZ we could avoid this allocation.
}
return argv;
}
extern "c" fn NativityClangMain(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
fn clangMain(allocator: Allocator, arguments: []const []const u8) !u8 {
const argv = try argsCopyZ(allocator, arguments);
const exit_code = NativityClangMain(@as(c_int, @intCast(arguments.len)), argv.ptr);
return @as(u8, @bitCast(@as(i8, @truncate(exit_code))));
} }

View File

@ -98,8 +98,14 @@ pub fn build(b: *std.Build) !void {
const llvm_include_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_path, "/include" }); const llvm_include_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_path, "/include" });
const llvm_lib_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_path, "/lib" }); const llvm_lib_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_path, "/lib" });
compiler.addIncludePath(std.Build.LazyPath.relative(llvm_include_dir)); compiler.addIncludePath(std.Build.LazyPath.relative(llvm_include_dir));
compiler.addCSourceFile(.{ const cpp_files = .{
.file = std.Build.LazyPath.relative("bootstrap/backend/llvm.cpp"), "bootstrap/backend/llvm.cpp",
"bootstrap/frontend/clang/main.cpp",
"bootstrap/frontend/clang/cc1.cpp",
"bootstrap/frontend/clang/cc1as.cpp",
};
compiler.addCSourceFiles(.{
.files = &cpp_files,
.flags = &.{"-g"}, .flags = &.{"-g"},
}); });

View File

@ -39,7 +39,8 @@ pub fn main() !void {
const source_file_path = try std.mem.concat(allocator, u8, &.{standalone_test_dir_path, "/", standalone_test_name, "/main.nat"}); const source_file_path = try std.mem.concat(allocator, u8, &.{standalone_test_dir_path, "/", standalone_test_name, "/main.nat"});
const process_run = try std.ChildProcess.run(.{ const process_run = try std.ChildProcess.run(.{
.allocator = allocator, .allocator = allocator,
.argv = &.{"zig-out/bin/nat", "-main_source_file", source_file_path}, // TODO: delete -main_source_file?
.argv = &.{"zig-out/bin/nat", "exe", "-main_source_file", source_file_path},
}); });
const result: TestError!bool = switch (process_run.term) { const result: TestError!bool = switch (process_run.term) {
.Exited => |exit_code| if (exit_code == 0) true else error.abnormal_exit_code, .Exited => |exit_code| if (exit_code == 0) true else error.abnormal_exit_code,