const std = #import("std"); const assert = std.assert; const Allocator = std.Allocator; const Target = std.Target; const Optimization = std.builtin.Optimization; const Executable = struct{ target: Target, main_source_path: [:0]const u8, link_libc: bool = false, name: [:0]const u8, c_source_files: []const [:0]const u8 = .{}.&, optimization: Optimization = .none, generate_debug_information: bool = true, const compile = fn(executable: Executable) *!void { const argument_count = std.start.argument_count; const argument_values = std.start.argument_values; assert(ok = argument_count >= 3); const compiler_path = argument_values[2]; try executable.compile_with_compiler_path(compiler_path); } const CompileError = error{ bad_exit_code, signaled, stopped, unknown_reason, }; const compile_with_compiler_path = fn(executable: Executable, compiler_path: [&:0]const u8) *!void { const pid = try std.os.duplicate_process(); if (pid == 0) { var link_libc_arg: [&:0]const u8 = undefined; if (executable.link_libc) { link_libc_arg = "true"; } else { link_libc_arg = "false"; } if (executable.c_source_files.length > 0) { assert(executable.c_source_files.length == 1); const argv = [_:null] ?[&:0]const u8{ compiler_path, "exe", "-main_source_file", executable.main_source_path.pointer, "-link_libc", link_libc_arg, "-name", executable.name.pointer, "-c_source_files", executable.c_source_files[0].pointer }; try std.os.execute(path = compiler_path, argv = argv.&, env = std.start.environment_values); } else { const argv = [_:null] ?[&:0]const u8{ compiler_path, "exe", "-main_source_file", executable.main_source_path.pointer, "-link_libc", link_libc_arg, "-name", executable.name.pointer }; try std.os.execute(path = compiler_path, argv = argv.&, env = std.start.environment_values); } } else { const raw_status = try std.os.waitpid(pid, flags = 0); if (std.os.ifexited(status = raw_status)) { const exit_status = std.os.exitstatus(status = raw_status); if (exit_status != 0) { return CompileError.bad_exit_code; } } else if (std.os.ifsignaled(status = raw_status)) { return CompileError.signaled; } else if (std.os.ifstopped(status = raw_status)) { return CompileError.stopped; } else { return CompileError.unknown_reason; } } } };