| ... | @@ -92,23 +92,23 @@ pub fn main() !void { | ... | @@ -92,23 +92,23 @@ pub fn main() !void { |
| 92 | // before arg parsing, check for the NO_COLOR environment variable | 92 | // before arg parsing, check for the NO_COLOR environment variable |
| 93 | // if it exists, default the color setting to .off | 93 | // if it exists, default the color setting to .off |
| 94 | // explicit --color arguments will still override this setting. | 94 | // explicit --color arguments will still override this setting. |
| 95 | builder.color = if (std.process.hasEnvVarConstant("NO_COLOR")) .off else .auto; | 95 | builder.color = if (process.hasEnvVarConstant("NO_COLOR")) .off else .auto; |
| 96 | | 96 | |
| 97 | while (nextArg(args, &arg_idx)) |arg| { | 97 | while (nextArg(args, &arg_idx)) |arg| { |
| 98 | if (mem.startsWith(u8, arg, "-D")) { | 98 | if (mem.startsWith(u8, arg, "-D")) { |
| 99 | const option_contents = arg[2..]; | 99 | const option_contents = arg[2..]; |
| 100 | if (option_contents.len == 0) { | 100 | if (option_contents.len == 0) { |
| 101 | std.debug.print("Expected option name after '-D'\n\n", .{}); | 101 | std.debug.print("Expected option name after '-D'\n\n", .{}); |
| 102 | return usageAndErr(builder, false, stderr_stream); | 102 | usageAndErr(builder, false, stderr_stream); |
| 103 | } | 103 | } |
| 104 | if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| { | 104 | if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| { |
| 105 | const option_name = option_contents[0..name_end]; | 105 | const option_name = option_contents[0..name_end]; |
| 106 | const option_value = option_contents[name_end + 1 ..]; | 106 | const option_value = option_contents[name_end + 1 ..]; |
| 107 | if (try builder.addUserInputOption(option_name, option_value)) | 107 | if (try builder.addUserInputOption(option_name, option_value)) |
| 108 | return usageAndErr(builder, false, stderr_stream); | 108 | usageAndErr(builder, false, stderr_stream); |
| 109 | } else { | 109 | } else { |
| 110 | if (try builder.addUserInputFlag(option_contents)) | 110 | if (try builder.addUserInputFlag(option_contents)) |
| 111 | return usageAndErr(builder, false, stderr_stream); | 111 | usageAndErr(builder, false, stderr_stream); |
| 112 | } | 112 | } |
| 113 | } else if (mem.startsWith(u8, arg, "-")) { | 113 | } else if (mem.startsWith(u8, arg, "-")) { |
| 114 | if (mem.eql(u8, arg, "--verbose")) { | 114 | if (mem.eql(u8, arg, "--verbose")) { |
| ... | @@ -118,61 +118,61 @@ pub fn main() !void { | ... | @@ -118,61 +118,61 @@ pub fn main() !void { |
| 118 | } else if (mem.eql(u8, arg, "-p") or mem.eql(u8, arg, "--prefix")) { | 118 | } else if (mem.eql(u8, arg, "-p") or mem.eql(u8, arg, "--prefix")) { |
| 119 | install_prefix = nextArg(args, &arg_idx) orelse { | 119 | install_prefix = nextArg(args, &arg_idx) orelse { |
| 120 | std.debug.print("Expected argument after {s}\n\n", .{arg}); | 120 | std.debug.print("Expected argument after {s}\n\n", .{arg}); |
| 121 | return usageAndErr(builder, false, stderr_stream); | 121 | usageAndErr(builder, false, stderr_stream); |
| 122 | }; | 122 | }; |
| 123 | } else if (mem.eql(u8, arg, "-l") or mem.eql(u8, arg, "--list-steps")) { | 123 | } else if (mem.eql(u8, arg, "-l") or mem.eql(u8, arg, "--list-steps")) { |
| 124 | return steps(builder, false, stdout_stream); | 124 | return steps(builder, false, stdout_stream); |
| 125 | } else if (mem.eql(u8, arg, "--prefix-lib-dir")) { | 125 | } else if (mem.eql(u8, arg, "--prefix-lib-dir")) { |
| 126 | dir_list.lib_dir = nextArg(args, &arg_idx) orelse { | 126 | dir_list.lib_dir = nextArg(args, &arg_idx) orelse { |
| 127 | std.debug.print("Expected argument after {s}\n\n", .{arg}); | 127 | std.debug.print("Expected argument after {s}\n\n", .{arg}); |
| 128 | return usageAndErr(builder, false, stderr_stream); | 128 | usageAndErr(builder, false, stderr_stream); |
| 129 | }; | 129 | }; |
| 130 | } else if (mem.eql(u8, arg, "--prefix-exe-dir")) { | 130 | } else if (mem.eql(u8, arg, "--prefix-exe-dir")) { |
| 131 | dir_list.exe_dir = nextArg(args, &arg_idx) orelse { | 131 | dir_list.exe_dir = nextArg(args, &arg_idx) orelse { |
| 132 | std.debug.print("Expected argument after {s}\n\n", .{arg}); | 132 | std.debug.print("Expected argument after {s}\n\n", .{arg}); |
| 133 | return usageAndErr(builder, false, stderr_stream); | 133 | usageAndErr(builder, false, stderr_stream); |
| 134 | }; | 134 | }; |
| 135 | } else if (mem.eql(u8, arg, "--prefix-include-dir")) { | 135 | } else if (mem.eql(u8, arg, "--prefix-include-dir")) { |
| 136 | dir_list.include_dir = nextArg(args, &arg_idx) orelse { | 136 | dir_list.include_dir = nextArg(args, &arg_idx) orelse { |
| 137 | std.debug.print("Expected argument after {s}\n\n", .{arg}); | 137 | std.debug.print("Expected argument after {s}\n\n", .{arg}); |
| 138 | return usageAndErr(builder, false, stderr_stream); | 138 | usageAndErr(builder, false, stderr_stream); |
| 139 | }; | 139 | }; |
| 140 | } else if (mem.eql(u8, arg, "--sysroot")) { | 140 | } else if (mem.eql(u8, arg, "--sysroot")) { |
| 141 | const sysroot = nextArg(args, &arg_idx) orelse { | 141 | const sysroot = nextArg(args, &arg_idx) orelse { |
| 142 | std.debug.print("Expected argument after --sysroot\n\n", .{}); | 142 | std.debug.print("Expected argument after --sysroot\n\n", .{}); |
| 143 | return usageAndErr(builder, false, stderr_stream); | 143 | usageAndErr(builder, false, stderr_stream); |
| 144 | }; | 144 | }; |
| 145 | builder.sysroot = sysroot; | 145 | builder.sysroot = sysroot; |
| 146 | } else if (mem.eql(u8, arg, "--search-prefix")) { | 146 | } else if (mem.eql(u8, arg, "--search-prefix")) { |
| 147 | const search_prefix = nextArg(args, &arg_idx) orelse { | 147 | const search_prefix = nextArg(args, &arg_idx) orelse { |
| 148 | std.debug.print("Expected argument after --search-prefix\n\n", .{}); | 148 | std.debug.print("Expected argument after --search-prefix\n\n", .{}); |
| 149 | return usageAndErr(builder, false, stderr_stream); | 149 | usageAndErr(builder, false, stderr_stream); |
| 150 | }; | 150 | }; |
| 151 | builder.addSearchPrefix(search_prefix); | 151 | builder.addSearchPrefix(search_prefix); |
| 152 | } else if (mem.eql(u8, arg, "--libc")) { | 152 | } else if (mem.eql(u8, arg, "--libc")) { |
| 153 | const libc_file = nextArg(args, &arg_idx) orelse { | 153 | const libc_file = nextArg(args, &arg_idx) orelse { |
| 154 | std.debug.print("Expected argument after --libc\n\n", .{}); | 154 | std.debug.print("Expected argument after --libc\n\n", .{}); |
| 155 | return usageAndErr(builder, false, stderr_stream); | 155 | usageAndErr(builder, false, stderr_stream); |
| 156 | }; | 156 | }; |
| 157 | builder.libc_file = libc_file; | 157 | builder.libc_file = libc_file; |
| 158 | } else if (mem.eql(u8, arg, "--color")) { | 158 | } else if (mem.eql(u8, arg, "--color")) { |
| 159 | const next_arg = nextArg(args, &arg_idx) orelse { | 159 | const next_arg = nextArg(args, &arg_idx) orelse { |
| 160 | std.debug.print("expected [auto|on|off] after --color", .{}); | 160 | std.debug.print("expected [auto|on|off] after --color", .{}); |
| 161 | return usageAndErr(builder, false, stderr_stream); | 161 | usageAndErr(builder, false, stderr_stream); |
| 162 | }; | 162 | }; |
| 163 | builder.color = std.meta.stringToEnum(@TypeOf(builder.color), next_arg) orelse { | 163 | builder.color = std.meta.stringToEnum(@TypeOf(builder.color), next_arg) orelse { |
| 164 | std.debug.print("expected [auto|on|off] after --color, found '{s}'", .{next_arg}); | 164 | std.debug.print("expected [auto|on|off] after --color, found '{s}'", .{next_arg}); |
| 165 | return usageAndErr(builder, false, stderr_stream); | 165 | usageAndErr(builder, false, stderr_stream); |
| 166 | }; | 166 | }; |
| 167 | } else if (mem.eql(u8, arg, "--zig-lib-dir")) { | 167 | } else if (mem.eql(u8, arg, "--zig-lib-dir")) { |
| 168 | builder.zig_lib_dir = nextArg(args, &arg_idx) orelse { | 168 | builder.zig_lib_dir = nextArg(args, &arg_idx) orelse { |
| 169 | std.debug.print("Expected argument after --zig-lib-dir\n\n", .{}); | 169 | std.debug.print("Expected argument after --zig-lib-dir\n\n", .{}); |
| 170 | return usageAndErr(builder, false, stderr_stream); | 170 | usageAndErr(builder, false, stderr_stream); |
| 171 | }; | 171 | }; |
| 172 | } else if (mem.eql(u8, arg, "--debug-log")) { | 172 | } else if (mem.eql(u8, arg, "--debug-log")) { |
| 173 | const next_arg = nextArg(args, &arg_idx) orelse { | 173 | const next_arg = nextArg(args, &arg_idx) orelse { |
| 174 | std.debug.print("Expected argument after {s}\n\n", .{arg}); | 174 | std.debug.print("Expected argument after {s}\n\n", .{arg}); |
| 175 | return usageAndErr(builder, false, stderr_stream); | 175 | usageAndErr(builder, false, stderr_stream); |
| 176 | }; | 176 | }; |
| 177 | try debug_log_scopes.append(next_arg); | 177 | try debug_log_scopes.append(next_arg); |
| 178 | } else if (mem.eql(u8, arg, "--debug-compile-errors")) { | 178 | } else if (mem.eql(u8, arg, "--debug-compile-errors")) { |
| ... | @@ -180,7 +180,7 @@ pub fn main() !void { | ... | @@ -180,7 +180,7 @@ pub fn main() !void { |
| 180 | } else if (mem.eql(u8, arg, "--glibc-runtimes")) { | 180 | } else if (mem.eql(u8, arg, "--glibc-runtimes")) { |
| 181 | builder.glibc_runtimes_dir = nextArg(args, &arg_idx) orelse { | 181 | builder.glibc_runtimes_dir = nextArg(args, &arg_idx) orelse { |
| 182 | std.debug.print("Expected argument after --glibc-runtimes\n\n", .{}); | 182 | std.debug.print("Expected argument after --glibc-runtimes\n\n", .{}); |
| 183 | return usageAndErr(builder, false, stderr_stream); | 183 | usageAndErr(builder, false, stderr_stream); |
| 184 | }; | 184 | }; |
| 185 | } else if (mem.eql(u8, arg, "--verbose-link")) { | 185 | } else if (mem.eql(u8, arg, "--verbose-link")) { |
| 186 | builder.verbose_link = true; | 186 | builder.verbose_link = true; |
| ... | @@ -231,7 +231,7 @@ pub fn main() !void { | ... | @@ -231,7 +231,7 @@ pub fn main() !void { |
| 231 | break; | 231 | break; |
| 232 | } else { | 232 | } else { |
| 233 | std.debug.print("Unrecognized argument: {s}\n\n", .{arg}); | 233 | std.debug.print("Unrecognized argument: {s}\n\n", .{arg}); |
| 234 | return usageAndErr(builder, false, stderr_stream); | 234 | usageAndErr(builder, false, stderr_stream); |
| 235 | } | 235 | } |
| 236 | } else { | 236 | } else { |
| 237 | try targets.append(arg); | 237 | try targets.append(arg); |
| ... | @@ -243,13 +243,10 @@ pub fn main() !void { | ... | @@ -243,13 +243,10 @@ pub fn main() !void { |
| 243 | try builder.runBuild(root); | 243 | try builder.runBuild(root); |
| 244 | | 244 | |
| 245 | if (builder.validateUserInputDidItFail()) | 245 | if (builder.validateUserInputDidItFail()) |
| 246 | return usageAndErr(builder, true, stderr_stream); | 246 | usageAndErr(builder, true, stderr_stream); |
| 247 | | 247 | |
| 248 | builder.make(targets.items) catch |err| { | 248 | make(builder, targets.items) catch |err| { |
| 249 | switch (err) { | 249 | switch (err) { |
| 250 | error.InvalidStepName => { | | |
| 251 | return usageAndErr(builder, true, stderr_stream); | | |
| 252 | }, | | |
| 253 | error.UncleanExit => process.exit(1), | 250 | error.UncleanExit => process.exit(1), |
| 254 | // This error is intended to indicate that the step has already | 251 | // This error is intended to indicate that the step has already |
| 255 | // logged an error message and so printing the error return trace | 252 | // logged an error message and so printing the error return trace |
| ... | @@ -261,6 +258,48 @@ pub fn main() !void { | ... | @@ -261,6 +258,48 @@ pub fn main() !void { |
| 261 | }; | 258 | }; |
| 262 | } | 259 | } |
| 263 | | 260 | |
| | 261 | fn make(b: *std.Build, step_names: []const []const u8) !void { |
| | 262 | var wanted_steps = ArrayList(*std.Build.Step).init(b.allocator); |
| | 263 | defer wanted_steps.deinit(); |
| | 264 | |
| | 265 | if (step_names.len == 0) { |
| | 266 | try wanted_steps.append(b.default_step); |
| | 267 | } else { |
| | 268 | for (step_names) |step_name| { |
| | 269 | const s = b.top_level_steps.get(step_name) orelse { |
| | 270 | std.debug.print("no step named '{s}'. Access the help menu with 'zig build -h'\n", .{step_name}); |
| | 271 | process.exit(1); |
| | 272 | }; |
| | 273 | try wanted_steps.append(&s.step); |
| | 274 | } |
| | 275 | } |
| | 276 | |
| | 277 | for (wanted_steps.items) |s| { |
| | 278 | try makeOneStep(b, s); |
| | 279 | } |
| | 280 | } |
| | 281 | |
| | 282 | fn makeOneStep(b: *std.Build, s: *std.Build.Step) anyerror!void { |
| | 283 | if (s.loop_flag) { |
| | 284 | std.debug.print("dependency loop detected:\n {s}\n", .{s.name}); |
| | 285 | return error.DependencyLoopDetected; |
| | 286 | } |
| | 287 | s.loop_flag = true; |
| | 288 | |
| | 289 | for (s.dependencies.items) |dep| { |
| | 290 | makeOneStep(b, dep) catch |err| { |
| | 291 | if (err == error.DependencyLoopDetected) { |
| | 292 | std.debug.print(" {s}\n", .{s.name}); |
| | 293 | } |
| | 294 | return err; |
| | 295 | }; |
| | 296 | } |
| | 297 | |
| | 298 | s.loop_flag = false; |
| | 299 | |
| | 300 | try s.make(); |
| | 301 | } |
| | 302 | |
| 264 | fn steps(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !void { | 303 | fn steps(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !void { |
| 265 | // run the build script to collect the options | 304 | // run the build script to collect the options |
| 266 | if (!already_ran_build) { | 305 | if (!already_ran_build) { |
| ... | @@ -269,7 +308,7 @@ fn steps(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi | ... | @@ -269,7 +308,7 @@ fn steps(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi |
| 269 | } | 308 | } |
| 270 | | 309 | |
| 271 | const allocator = builder.allocator; | 310 | const allocator = builder.allocator; |
| 272 | for (builder.top_level_steps.items) |top_level_step| { | 311 | for (builder.top_level_steps.values()) |top_level_step| { |
| 273 | const name = if (&top_level_step.step == builder.default_step) | 312 | const name = if (&top_level_step.step == builder.default_step) |
| 274 | try fmt.allocPrint(allocator, "{s} (default)", .{top_level_step.step.name}) | 313 | try fmt.allocPrint(allocator, "{s} (default)", .{top_level_step.step.name}) |
| 275 | else | 314 | else |
| ... | @@ -374,7 +413,7 @@ fn usage(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi | ... | @@ -374,7 +413,7 @@ fn usage(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi |
| 374 | ); | 413 | ); |
| 375 | } | 414 | } |
| 376 | | 415 | |
| 377 | fn usageAndErr(builder: *std.Build, already_ran_build: bool, out_stream: anytype) void { | 416 | fn usageAndErr(builder: *std.Build, already_ran_build: bool, out_stream: anytype) noreturn { |
| 378 | usage(builder, already_ran_build, out_stream) catch {}; | 417 | usage(builder, already_ran_build, out_stream) catch {}; |
| 379 | process.exit(1); | 418 | process.exit(1); |
| 380 | } | 419 | } |