authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-22 01:49:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-22 01:54:38-04:00
log8866bef92c8b674c2a444c94326c57984597ab05
treecfe58074556705cd98182d37886b793a0dbf88c5
parentbe2a4c42bdfdbf9130eaeee3ce66085cb862dcd1

clean up self hosted main. delete unsupported commands


4 files changed, 121 insertions(+), 459 deletions(-)

src-self-hosted/arg.zig+2-2
...@@ -168,7 +168,7 @@ pub const Args = struct {...@@ -168,7 +168,7 @@ pub const Args = struct {
168 }168 }
169169
170 // e.g. --names value1 value2 value3170 // e.g. --names value1 value2 value3
171 pub fn many(self: *Args, name: []const u8) ?[]const []const u8 {171 pub fn many(self: *Args, name: []const u8) []const []const u8 {
172 if (self.flags.get(name)) |entry| {172 if (self.flags.get(name)) |entry| {
173 switch (entry.value) {173 switch (entry.value) {
174 FlagArg.Many => |inner| {174 FlagArg.Many => |inner| {
...@@ -177,7 +177,7 @@ pub const Args = struct {...@@ -177,7 +177,7 @@ pub const Args = struct {
177 else => @panic("attempted to retrieve flag with wrong type"),177 else => @panic("attempted to retrieve flag with wrong type"),
178 }178 }
179 } else {179 } else {
180 return null;180 return []const []const u8{};
181 }181 }
182 }182 }
183};183};
src-self-hosted/main.zig+116-430
...@@ -26,15 +26,11 @@ const usage =...@@ -26,15 +26,11 @@ const usage =
26 \\26 \\
27 \\Commands:27 \\Commands:
28 \\28 \\
29 \\ build Build project from build.zig
30 \\ build-exe [source] Create executable from source or object files29 \\ build-exe [source] Create executable from source or object files
31 \\ build-lib [source] Create library from source or object files30 \\ build-lib [source] Create library from source or object files
32 \\ build-obj [source] Create object from source or assembly31 \\ build-obj [source] Create object from source or assembly
33 \\ fmt [source] Parse file and render in canonical zig format32 \\ fmt [source] Parse file and render in canonical zig format
34 \\ run [source] Create executable and run immediately
35 \\ targets List available compilation targets33 \\ targets List available compilation targets
36 \\ test [source] Create and run a test build
37 \\ translate-c [source] Convert c code to zig code
38 \\ version Print version number and exit34 \\ version Print version number and exit
39 \\ zen Print zen of zig and exit35 \\ zen Print zen of zig and exit
40 \\36 \\
...@@ -47,7 +43,7 @@ const Command = struct {...@@ -47,7 +43,7 @@ const Command = struct {
47};43};
4844
49pub fn main() !void {45pub fn main() !void {
50 var allocator = std.heap.c_allocator;46 const allocator = std.heap.c_allocator;
5147
52 var stdout_file = try std.io.getStdOut();48 var stdout_file = try std.io.getStdOut();
53 var stdout_out_stream = std.io.FileOutStream.init(&stdout_file);49 var stdout_out_stream = std.io.FileOutStream.init(&stdout_file);
...@@ -58,18 +54,16 @@ pub fn main() !void {...@@ -58,18 +54,16 @@ pub fn main() !void {
58 stderr = &stderr_out_stream.stream;54 stderr = &stderr_out_stream.stream;
5955
60 const args = try os.argsAlloc(allocator);56 const args = try os.argsAlloc(allocator);
61 defer os.argsFree(allocator, args);57 // TODO I'm getting unreachable code here, which shouldn't happen
58 //defer os.argsFree(allocator, args);
6259
63 if (args.len <= 1) {60 if (args.len <= 1) {
61 try stderr.write("expected command argument\n\n");
64 try stderr.write(usage);62 try stderr.write(usage);
65 os.exit(1);63 os.exit(1);
66 }64 }
6765
68 const commands = []Command{66 const commands = []Command{
69 Command{
70 .name = "build",
71 .exec = cmdBuild,
72 },
73 Command{67 Command{
74 .name = "build-exe",68 .name = "build-exe",
75 .exec = cmdBuildExe,69 .exec = cmdBuildExe,
...@@ -86,22 +80,10 @@ pub fn main() !void {...@@ -86,22 +80,10 @@ pub fn main() !void {
86 .name = "fmt",80 .name = "fmt",
87 .exec = cmdFmt,81 .exec = cmdFmt,
88 },82 },
89 Command{
90 .name = "run",
91 .exec = cmdRun,
92 },
93 Command{83 Command{
94 .name = "targets",84 .name = "targets",
95 .exec = cmdTargets,85 .exec = cmdTargets,
96 },86 },
97 Command{
98 .name = "test",
99 .exec = cmdTest,
100 },
101 Command{
102 .name = "translate-c",
103 .exec = cmdTranslateC,
104 },
105 Command{87 Command{
106 .name = "version",88 .name = "version",
107 .exec = cmdVersion,89 .exec = cmdVersion,
...@@ -124,177 +106,15 @@ pub fn main() !void {...@@ -124,177 +106,15 @@ pub fn main() !void {
124106
125 for (commands) |command| {107 for (commands) |command| {
126 if (mem.eql(u8, command.name, args[1])) {108 if (mem.eql(u8, command.name, args[1])) {
127 try command.exec(allocator, args[2..]);109 return command.exec(allocator, args[2..]);
128 return;
129 }110 }
130 }111 }
131112
132 try stderr.print("unknown command: {}\n\n", args[1]);113 try stderr.print("unknown command: {}\n\n", args[1]);
133 try stderr.write(usage);114 try stderr.write(usage);
115 os.exit(1);
134}116}
135117
136// cmd:build ///////////////////////////////////////////////////////////////////////////////////////
137
138const usage_build =
139 \\usage: zig build <options>
140 \\
141 \\General Options:
142 \\ --help Print this help and exit
143 \\ --init Generate a build.zig template
144 \\ --build-file [file] Override path to build.zig
145 \\ --cache-dir [path] Override path to cache directory
146 \\ --verbose Print commands before executing them
147 \\ --prefix [path] Override default install prefix
148 \\
149 \\Project-Specific Options:
150 \\
151 \\ Project-specific options become available when the build file is found.
152 \\
153 \\Advanced Options:
154 \\ --build-file [file] Override path to build.zig
155 \\ --cache-dir [path] Override path to cache directory
156 \\ --verbose-tokenize Enable compiler debug output for tokenization
157 \\ --verbose-ast Enable compiler debug output for parsing into an AST
158 \\ --verbose-link Enable compiler debug output for linking
159 \\ --verbose-ir Enable compiler debug output for Zig IR
160 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
161 \\ --verbose-cimport Enable compiler debug output for C imports
162 \\
163 \\
164;
165
166const args_build_spec = []Flag{
167 Flag.Bool("--help"),
168 Flag.Bool("--init"),
169 Flag.Arg1("--build-file"),
170 Flag.Arg1("--cache-dir"),
171 Flag.Bool("--verbose"),
172 Flag.Arg1("--prefix"),
173
174 Flag.Arg1("--build-file"),
175 Flag.Arg1("--cache-dir"),
176 Flag.Bool("--verbose-tokenize"),
177 Flag.Bool("--verbose-ast"),
178 Flag.Bool("--verbose-link"),
179 Flag.Bool("--verbose-ir"),
180 Flag.Bool("--verbose-llvm-ir"),
181 Flag.Bool("--verbose-cimport"),
182};
183
184const missing_build_file =
185 \\No 'build.zig' file found.
186 \\
187 \\Initialize a 'build.zig' template file with `zig build --init`,
188 \\or build an executable directly with `zig build-exe $FILENAME.zig`.
189 \\
190 \\See: `zig build --help` or `zig help` for more options.
191 \\
192;
193
194fn cmdBuild(allocator: *Allocator, args: []const []const u8) !void {
195 var flags = try Args.parse(allocator, args_build_spec, args);
196 defer flags.deinit();
197
198 if (flags.present("help")) {
199 try stderr.write(usage_build);
200 os.exit(0);
201 }
202
203 const zig_lib_dir = try introspect.resolveZigLibDir(allocator);
204 defer allocator.free(zig_lib_dir);
205
206 const zig_std_dir = try os.path.join(allocator, zig_lib_dir, "std");
207 defer allocator.free(zig_std_dir);
208
209 const special_dir = try os.path.join(allocator, zig_std_dir, "special");
210 defer allocator.free(special_dir);
211
212 const build_runner_path = try os.path.join(allocator, special_dir, "build_runner.zig");
213 defer allocator.free(build_runner_path);
214
215 const build_file = flags.single("build-file") orelse "build.zig";
216 const build_file_abs = try os.path.resolve(allocator, ".", build_file);
217 defer allocator.free(build_file_abs);
218
219 const build_file_exists = os.File.access(allocator, build_file_abs, os.default_file_mode) catch false;
220
221 if (flags.present("init")) {
222 if (build_file_exists) {
223 try stderr.print("build.zig already exists\n");
224 os.exit(1);
225 }
226
227 // need a new scope for proper defer scope finalization on exit
228 {
229 const build_template_path = try os.path.join(allocator, special_dir, "build_file_template.zig");
230 defer allocator.free(build_template_path);
231
232 try os.copyFile(allocator, build_template_path, build_file_abs);
233 try stderr.print("wrote build.zig template\n");
234 }
235
236 os.exit(0);
237 }
238
239 if (!build_file_exists) {
240 try stderr.write(missing_build_file);
241 os.exit(1);
242 }
243
244 // TODO: Invoke build.zig entrypoint directly?
245 var zig_exe_path = try os.selfExePath(allocator);
246 defer allocator.free(zig_exe_path);
247
248 var build_args = ArrayList([]const u8).init(allocator);
249 defer build_args.deinit();
250
251 const build_file_basename = os.path.basename(build_file_abs);
252 const build_file_dirname = os.path.dirname(build_file_abs) orelse ".";
253
254 var full_cache_dir: []u8 = undefined;
255 if (flags.single("cache-dir")) |cache_dir| {
256 full_cache_dir = try os.path.resolve(allocator, ".", cache_dir, full_cache_dir);
257 } else {
258 full_cache_dir = try os.path.join(allocator, build_file_dirname, "zig-cache");
259 }
260 defer allocator.free(full_cache_dir);
261
262 const path_to_build_exe = try os.path.join(allocator, full_cache_dir, "build");
263 defer allocator.free(path_to_build_exe);
264
265 try build_args.append(path_to_build_exe);
266 try build_args.append(zig_exe_path);
267 try build_args.append(build_file_dirname);
268 try build_args.append(full_cache_dir);
269
270 var proc = try os.ChildProcess.init(build_args.toSliceConst(), allocator);
271 defer proc.deinit();
272
273 var term = try proc.spawnAndWait();
274 switch (term) {
275 os.ChildProcess.Term.Exited => |status| {
276 if (status != 0) {
277 try stderr.print("{} exited with status {}\n", build_args.at(0), status);
278 os.exit(1);
279 }
280 },
281 os.ChildProcess.Term.Signal => |signal| {
282 try stderr.print("{} killed by signal {}\n", build_args.at(0), signal);
283 os.exit(1);
284 },
285 os.ChildProcess.Term.Stopped => |signal| {
286 try stderr.print("{} stopped by signal {}\n", build_args.at(0), signal);
287 os.exit(1);
288 },
289 os.ChildProcess.Term.Unknown => |status| {
290 try stderr.print("{} encountered unknown failure {}\n", build_args.at(0), status);
291 os.exit(1);
292 },
293 }
294}
295
296// cmd:build-exe ///////////////////////////////////////////////////////////////////////////////////
297
298const usage_build_generic =118const usage_build_generic =
299 \\usage: zig build-exe <options> [file]119 \\usage: zig build-exe <options> [file]
300 \\ zig build-lib <options> [file]120 \\ zig build-lib <options> [file]
...@@ -315,8 +135,11 @@ const usage_build_generic =...@@ -315,8 +135,11 @@ const usage_build_generic =
315 \\ --output-h [file] Override generated header file path135 \\ --output-h [file] Override generated header file path
316 \\ --pkg-begin [name] [path] Make package available to import and push current pkg136 \\ --pkg-begin [name] [path] Make package available to import and push current pkg
317 \\ --pkg-end Pop current pkg137 \\ --pkg-end Pop current pkg
318 \\ --release-fast Build with optimizations on and safety off138 \\ --mode [mode] Set the build mode
319 \\ --release-safe Build with optimizations on and safety on139 \\ debug (default) optimizations off, safety on
140 \\ release-fast optimizations on, safety off
141 \\ release-safe optimizations on, safety on
142 \\ release-small optimize for small binary, safety off
320 \\ --static Output will be statically linked143 \\ --static Output will be statically linked
321 \\ --strip Exclude debug symbols144 \\ --strip Exclude debug symbols
322 \\ --target-arch [name] Specify target architecture145 \\ --target-arch [name] Specify target architecture
...@@ -367,6 +190,12 @@ const args_build_generic = []Flag{...@@ -367,6 +190,12 @@ const args_build_generic = []Flag{
367 "off",190 "off",
368 "on",191 "on",
369 }),192 }),
193 Flag.Option("--mode", []const []const u8{
194 "debug",
195 "release-fast",
196 "release-safe",
197 "release-small",
198 }),
370199
371 Flag.ArgMergeN("--assembly", 1),200 Flag.ArgMergeN("--assembly", 1),
372 Flag.Arg1("--cache-dir"),201 Flag.Arg1("--cache-dir"),
...@@ -383,8 +212,6 @@ const args_build_generic = []Flag{...@@ -383,8 +212,6 @@ const args_build_generic = []Flag{
383 // NOTE: Parsed manually after initial check212 // NOTE: Parsed manually after initial check
384 Flag.ArgN("--pkg-begin", 2),213 Flag.ArgN("--pkg-begin", 2),
385 Flag.Bool("--pkg-end"),214 Flag.Bool("--pkg-end"),
386 Flag.Bool("--release-fast"),
387 Flag.Bool("--release-safe"),
388 Flag.Bool("--static"),215 Flag.Bool("--static"),
389 Flag.Bool("--strip"),216 Flag.Bool("--strip"),
390 Flag.Arg1("--target-arch"),217 Flag.Arg1("--target-arch"),
...@@ -431,16 +258,25 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo...@@ -431,16 +258,25 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
431 defer flags.deinit();258 defer flags.deinit();
432259
433 if (flags.present("help")) {260 if (flags.present("help")) {
434 try stderr.write(usage_build_generic);261 try stdout.write(usage_build_generic);
435 os.exit(0);262 os.exit(0);
436 }263 }
437264
438 var build_mode = builtin.Mode.Debug;265 const build_mode = blk: {
439 if (flags.present("release-fast")) {266 if (flags.single("mode")) |mode_flag| {
440 build_mode = builtin.Mode.ReleaseFast;267 if (mem.eql(u8, mode_flag, "debug")) {
441 } else if (flags.present("release-safe")) {268 break :blk builtin.Mode.Debug;
442 build_mode = builtin.Mode.ReleaseSafe;269 } else if (mem.eql(u8, mode_flag, "release-fast")) {
443 }270 break :blk builtin.Mode.ReleaseFast;
271 } else if (mem.eql(u8, mode_flag, "release-safe")) {
272 break :blk builtin.Mode.ReleaseSafe;
273 } else if (mem.eql(u8, mode_flag, "release-small")) {
274 break :blk builtin.Mode.ReleaseSmall;
275 } else unreachable;
276 } else {
277 break :blk builtin.Mode.Debug;
278 }
279 };
444280
445 const color = blk: {281 const color = blk: {
446 if (flags.single("color")) |color_flag| {282 if (flags.single("color")) |color_flag| {
...@@ -456,20 +292,21 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo...@@ -456,20 +292,21 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
456 }292 }
457 };293 };
458294
459 var emit_type = Module.Emit.Binary;295 const emit_type = blk: {
460 if (flags.single("emit")) |emit_flag| {296 if (flags.single("emit")) |emit_flag| {
461 if (mem.eql(u8, emit_flag, "asm")) {297 if (mem.eql(u8, emit_flag, "asm")) {
462 emit_type = Module.Emit.Assembly;298 break :blk Module.Emit.Assembly;
463 } else if (mem.eql(u8, emit_flag, "bin")) {299 } else if (mem.eql(u8, emit_flag, "bin")) {
464 emit_type = Module.Emit.Binary;300 break :blk Module.Emit.Binary;
465 } else if (mem.eql(u8, emit_flag, "llvm-ir")) {301 } else if (mem.eql(u8, emit_flag, "llvm-ir")) {
466 emit_type = Module.Emit.LlvmIr;302 break :blk Module.Emit.LlvmIr;
303 } else unreachable;
467 } else {304 } else {
468 unreachable;305 break :blk Module.Emit.Binary;
469 }306 }
470 }307 };
471308
472 var cur_pkg = try Module.CliPkg.init(allocator, "", "", null); // TODO: Need a path, name?309 var cur_pkg = try CliPkg.init(allocator, "", "", null);
473 defer cur_pkg.deinit();310 defer cur_pkg.deinit();
474311
475 var i: usize = 0;312 var i: usize = 0;
...@@ -482,15 +319,16 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo...@@ -482,15 +319,16 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
482 i += 1;319 i += 1;
483 const new_pkg_path = args[i];320 const new_pkg_path = args[i];
484321
485 var new_cur_pkg = try Module.CliPkg.init(allocator, new_pkg_name, new_pkg_path, cur_pkg);322 var new_cur_pkg = try CliPkg.init(allocator, new_pkg_name, new_pkg_path, cur_pkg);
486 try cur_pkg.children.append(new_cur_pkg);323 try cur_pkg.children.append(new_cur_pkg);
487 cur_pkg = new_cur_pkg;324 cur_pkg = new_cur_pkg;
488 } else if (mem.eql(u8, "--pkg-end", arg_name)) {325 } else if (mem.eql(u8, "--pkg-end", arg_name)) {
489 if (cur_pkg.parent == null) {326 if (cur_pkg.parent) |parent| {
327 cur_pkg = parent;
328 } else {
490 try stderr.print("encountered --pkg-end with no matching --pkg-begin\n");329 try stderr.print("encountered --pkg-end with no matching --pkg-begin\n");
491 os.exit(1);330 os.exit(1);
492 }331 }
493 cur_pkg = cur_pkg.parent.?;
494 }332 }
495 }333 }
496334
...@@ -499,43 +337,42 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo...@@ -499,43 +337,42 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
499 os.exit(1);337 os.exit(1);
500 }338 }
501339
502 var in_file: ?[]const u8 = undefined;340 const provided_name = flags.single("name");
503 switch (flags.positionals.len) {341 const root_source_file = switch (flags.positionals.len) {
504 0 => {342 0 => null,
505 try stderr.write("--name [name] not provided and unable to infer\n");343 1 => flags.positionals.at(0),
506 os.exit(1);
507 },
508 1 => {
509 in_file = flags.positionals.at(0);
510 },
511 else => {344 else => {
512 try stderr.write("only one zig input file is accepted during build\n");345 try stderr.print("unexpected extra parameter: {}\n", flags.positionals.at(1));
513 os.exit(1);346 os.exit(1);
514 },347 },
515 }348 };
516349
517 const basename = os.path.basename(in_file.?);350 const root_name = if (provided_name) |n| n else blk: {
518 var it = mem.split(basename, ".");351 if (root_source_file) |file| {
519 const root_name = it.next() orelse {352 const basename = os.path.basename(file);
520 try stderr.write("file name cannot be empty\n");353 var it = mem.split(basename, ".");
521 os.exit(1);354 break :blk it.next() orelse basename;
355 } else {
356 try stderr.write("--name [name] not provided and unable to infer\n");
357 os.exit(1);
358 }
522 };359 };
523360
524 const asm_a = flags.many("assembly");361 const assembly_files = flags.many("assembly");
525 const obj_a = flags.many("object");362 const link_objects = flags.many("object");
526 if (in_file == null and (obj_a == null or obj_a.?.len == 0) and (asm_a == null or asm_a.?.len == 0)) {363 if (root_source_file == null and link_objects.len == 0 and assembly_files.len == 0) {
527 try stderr.write("Expected source file argument or at least one --object or --assembly argument\n");364 try stderr.write("Expected source file argument or at least one --object or --assembly argument\n");
528 os.exit(1);365 os.exit(1);
529 }366 }
530367
531 if (out_type == Module.Kind.Obj and (obj_a != null and obj_a.?.len != 0)) {368 if (out_type == Module.Kind.Obj and link_objects.len != 0) {
532 try stderr.write("When building an object file, --object arguments are invalid\n");369 try stderr.write("When building an object file, --object arguments are invalid\n");
533 os.exit(1);370 os.exit(1);
534 }371 }
535372
536 const zig_root_source_file = in_file;373 const rel_cache_dir = flags.single("cache-dir") orelse "zig-cache"[0..];
537374 const full_cache_dir = os.path.resolve(allocator, ".", rel_cache_dir) catch {
538 const full_cache_dir = os.path.resolve(allocator, ".", flags.single("cache-dir") orelse "zig-cache"[0..]) catch {375 try stderr.print("invalid cache dir: {}\n", rel_cache_dir);
539 os.exit(1);376 os.exit(1);
540 };377 };
541 defer allocator.free(full_cache_dir);378 defer allocator.free(full_cache_dir);
...@@ -546,7 +383,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo...@@ -546,7 +383,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
546 var module = try Module.create(383 var module = try Module.create(
547 allocator,384 allocator,
548 root_name,385 root_name,
549 zig_root_source_file,386 root_source_file,
550 Target.Native,387 Target.Native,
551 out_type,388 out_type,
552 build_mode,389 build_mode,
...@@ -561,24 +398,21 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo...@@ -561,24 +398,21 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
561398
562 module.is_test = false;399 module.is_test = false;
563400
564 if (flags.single("linker-script")) |linker_script| {401 module.linker_script = flags.single("linker-script");
565 module.linker_script = linker_script;
566 }
567
568 module.each_lib_rpath = flags.present("each-lib-rpath");402 module.each_lib_rpath = flags.present("each-lib-rpath");
569403
570 var clang_argv_buf = ArrayList([]const u8).init(allocator);404 var clang_argv_buf = ArrayList([]const u8).init(allocator);
571 defer clang_argv_buf.deinit();405 defer clang_argv_buf.deinit();
572 if (flags.many("mllvm")) |mllvm_flags| {
573 for (mllvm_flags) |mllvm| {
574 try clang_argv_buf.append("-mllvm");
575 try clang_argv_buf.append(mllvm);
576 }
577406
578 module.llvm_argv = mllvm_flags;407 const mllvm_flags = flags.many("mllvm");
579 module.clang_argv = clang_argv_buf.toSliceConst();408 for (mllvm_flags) |mllvm| {
409 try clang_argv_buf.append("-mllvm");
410 try clang_argv_buf.append(mllvm);
580 }411 }
581412
413 module.llvm_argv = mllvm_flags;
414 module.clang_argv = clang_argv_buf.toSliceConst();
415
582 module.strip = flags.present("strip");416 module.strip = flags.present("strip");
583 module.is_static = flags.present("static");417 module.is_static = flags.present("static");
584418
...@@ -610,18 +444,9 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo...@@ -610,18 +444,9 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
610 module.verbose_cimport = flags.present("verbose-cimport");444 module.verbose_cimport = flags.present("verbose-cimport");
611445
612 module.err_color = color;446 module.err_color = color;
613447 module.lib_dirs = flags.many("library-path");
614 if (flags.many("library-path")) |lib_dirs| {448 module.darwin_frameworks = flags.many("framework");
615 module.lib_dirs = lib_dirs;449 module.rpath_list = flags.many("rpath");
616 }
617
618 if (flags.many("framework")) |frameworks| {
619 module.darwin_frameworks = frameworks;
620 }
621
622 if (flags.many("rpath")) |rpath_list| {
623 module.rpath_list = rpath_list;
624 }
625450
626 if (flags.single("output-h")) |output_h| {451 if (flags.single("output-h")) |output_h| {
627 module.out_h_path = output_h;452 module.out_h_path = output_h;
...@@ -644,41 +469,25 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo...@@ -644,41 +469,25 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
644 }469 }
645470
646 module.emit_file_type = emit_type;471 module.emit_file_type = emit_type;
647 if (flags.many("object")) |objects| {472 module.link_objects = link_objects;
648 module.link_objects = objects;473 module.assembly_files = assembly_files;
649 }
650 if (flags.many("assembly")) |assembly_files| {
651 module.assembly_files = assembly_files;
652 }
653474
654 try module.build();475 try module.build();
655 try module.link(flags.single("out-file") orelse null);476 try module.link(flags.single("out-file"));
656
657 if (flags.present("print-timing-info")) {
658 // codegen_print_timing_info(g, stderr);
659 }
660
661 try stderr.print("building {}: {}\n", @tagName(out_type), in_file);
662}477}
663478
664fn cmdBuildExe(allocator: *Allocator, args: []const []const u8) !void {479fn cmdBuildExe(allocator: *Allocator, args: []const []const u8) !void {
665 try buildOutputType(allocator, args, Module.Kind.Exe);480 return buildOutputType(allocator, args, Module.Kind.Exe);
666}481}
667482
668// cmd:build-lib ///////////////////////////////////////////////////////////////////////////////////
669
670fn cmdBuildLib(allocator: *Allocator, args: []const []const u8) !void {483fn cmdBuildLib(allocator: *Allocator, args: []const []const u8) !void {
671 try buildOutputType(allocator, args, Module.Kind.Lib);484 return buildOutputType(allocator, args, Module.Kind.Lib);
672}485}
673486
674// cmd:build-obj ///////////////////////////////////////////////////////////////////////////////////
675
676fn cmdBuildObj(allocator: *Allocator, args: []const []const u8) !void {487fn cmdBuildObj(allocator: *Allocator, args: []const []const u8) !void {
677 try buildOutputType(allocator, args, Module.Kind.Obj);488 return buildOutputType(allocator, args, Module.Kind.Obj);
678}489}
679490
680// cmd:fmt /////////////////////////////////////////////////////////////////////////////////////////
681
682const usage_fmt =491const usage_fmt =
683 \\usage: zig fmt [file]...492 \\usage: zig fmt [file]...
684 \\493 \\
...@@ -735,7 +544,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {...@@ -735,7 +544,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
735 defer flags.deinit();544 defer flags.deinit();
736545
737 if (flags.present("help")) {546 if (flags.present("help")) {
738 try stderr.write(usage_fmt);547 try stdout.write(usage_fmt);
739 os.exit(0);548 os.exit(0);
740 }549 }
741550
...@@ -863,162 +672,16 @@ fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void {...@@ -863,162 +672,16 @@ fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void {
863 }672 }
864}673}
865674
866// cmd:version /////////////////////////////////////////////////////////////////////////////////////
867
868fn cmdVersion(allocator: *Allocator, args: []const []const u8) !void {675fn cmdVersion(allocator: *Allocator, args: []const []const u8) !void {
869 try stdout.print("{}\n", std.cstr.toSliceConst(c.ZIG_VERSION_STRING));676 try stdout.print("{}\n", std.cstr.toSliceConst(c.ZIG_VERSION_STRING));
870}677}
871678
872// cmd:test ////////////////////////////////////////////////////////////////////////////////////////
873
874const usage_test =
875 \\usage: zig test [file]...
876 \\
877 \\Options:
878 \\ --help Print this help and exit
879 \\
880 \\
881;
882
883const args_test_spec = []Flag{Flag.Bool("--help")};679const args_test_spec = []Flag{Flag.Bool("--help")};
884680
885fn cmdTest(allocator: *Allocator, args: []const []const u8) !void {
886 var flags = try Args.parse(allocator, args_build_spec, args);
887 defer flags.deinit();
888
889 if (flags.present("help")) {
890 try stderr.write(usage_test);
891 os.exit(0);
892 }
893
894 if (flags.positionals.len != 1) {
895 try stderr.write("expected exactly one zig source file\n");
896 os.exit(1);
897 }
898
899 // compile the test program into the cache and run
900
901 // NOTE: May be overlap with buildOutput, take the shared part out.
902 try stderr.print("testing file {}\n", flags.positionals.at(0));
903}
904
905// cmd:run /////////////////////////////////////////////////////////////////////////////////////////
906
907// Run should be simple and not expose the full set of arguments provided by build-exe. If specific
908// build requirements are need, the user should `build-exe` then `run` manually.
909const usage_run =
910 \\usage: zig run [file] -- <runtime args>
911 \\
912 \\Options:
913 \\ --help Print this help and exit
914 \\
915 \\
916;
917
918const args_run_spec = []Flag{Flag.Bool("--help")};
919
920fn cmdRun(allocator: *Allocator, args: []const []const u8) !void {
921 var compile_args = args;
922 var runtime_args: []const []const u8 = []const []const u8{};
923
924 for (args) |argv, i| {
925 if (mem.eql(u8, argv, "--")) {
926 compile_args = args[0..i];
927 runtime_args = args[i + 1 ..];
928 break;
929 }
930 }
931 var flags = try Args.parse(allocator, args_run_spec, compile_args);
932 defer flags.deinit();
933
934 if (flags.present("help")) {
935 try stderr.write(usage_run);
936 os.exit(0);
937 }
938
939 if (flags.positionals.len != 1) {
940 try stderr.write("expected exactly one zig source file\n");
941 os.exit(1);
942 }
943
944 try stderr.print("runtime args:\n");
945 for (runtime_args) |cargs| {
946 try stderr.print("{}\n", cargs);
947 }
948}
949
950// cmd:translate-c /////////////////////////////////////////////////////////////////////////////////
951
952const usage_translate_c =
953 \\usage: zig translate-c [file]
954 \\
955 \\Options:
956 \\ --help Print this help and exit
957 \\ --enable-timing-info Print timing diagnostics
958 \\ --output [path] Output file to write generated zig file (default: stdout)
959 \\
960 \\
961;
962
963const args_translate_c_spec = []Flag{
964 Flag.Bool("--help"),
965 Flag.Bool("--enable-timing-info"),
966 Flag.Arg1("--libc-include-dir"),
967 Flag.Arg1("--output"),
968};
969
970fn cmdTranslateC(allocator: *Allocator, args: []const []const u8) !void {
971 var flags = try Args.parse(allocator, args_translate_c_spec, args);
972 defer flags.deinit();
973
974 if (flags.present("help")) {
975 try stderr.write(usage_translate_c);
976 os.exit(0);
977 }
978
979 if (flags.positionals.len != 1) {
980 try stderr.write("expected exactly one c source file\n");
981 os.exit(1);
982 }
983
984 // set up codegen
985
986 const zig_root_source_file = null;
987
988 // NOTE: translate-c shouldn't require setting up the full codegen instance as it does in
989 // the C++ compiler.
990
991 // codegen_create(g);
992 // codegen_set_out_name(g, null);
993 // codegen_translate_c(g, flags.positional.at(0))
994
995 var output_stream = stdout;
996 if (flags.single("output")) |output_file| {
997 var file = try os.File.openWrite(allocator, output_file);
998 defer file.close();
999
1000 var file_stream = io.FileOutStream.init(&file);
1001 // TODO: Not being set correctly, still stdout
1002 output_stream = &file_stream.stream;
1003 }
1004
1005 // ast_render(g, output_stream, g->root_import->root, 4);
1006 try output_stream.write("pub const example = 10;\n");
1007
1008 if (flags.present("enable-timing-info")) {
1009 // codegen_print_timing_info(g, stdout);
1010 try stderr.write("printing timing info for translate-c\n");
1011 }
1012}
1013
1014// cmd:help ////////////////////////////////////////////////////////////////////////////////////////
1015
1016fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void {681fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void {
1017 try stderr.write(usage);682 try stdout.write(usage);
1018}683}
1019684
1020// cmd:zen /////////////////////////////////////////////////////////////////////////////////////////
1021
1022const info_zen =685const info_zen =
1023 \\686 \\
1024 \\ * Communicate intent precisely.687 \\ * Communicate intent precisely.
...@@ -1040,8 +703,6 @@ fn cmdZen(allocator: *Allocator, args: []const []const u8) !void {...@@ -1040,8 +703,6 @@ fn cmdZen(allocator: *Allocator, args: []const []const u8) !void {
1040 try stdout.write(info_zen);703 try stdout.write(info_zen);
1041}704}
1042705
1043// cmd:internal ////////////////////////////////////////////////////////////////////////////////////
1044
1045const usage_internal =706const usage_internal =
1046 \\usage: zig internal [subcommand]707 \\usage: zig internal [subcommand]
1047 \\708 \\
...@@ -1095,3 +756,28 @@ fn cmdInternalBuildInfo(allocator: *Allocator, args: []const []const u8) !void {...@@ -1095,3 +756,28 @@ fn cmdInternalBuildInfo(allocator: *Allocator, args: []const []const u8) !void {
1095 std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB),756 std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB),
1096 );757 );
1097}758}
759
760const CliPkg = struct {
761 name: []const u8,
762 path: []const u8,
763 children: ArrayList(*CliPkg),
764 parent: ?*CliPkg,
765
766 pub fn init(allocator: *mem.Allocator, name: []const u8, path: []const u8, parent: ?*CliPkg) !*CliPkg {
767 var pkg = try allocator.create(CliPkg{
768 .name = name,
769 .path = path,
770 .children = ArrayList(*CliPkg).init(allocator),
771 .parent = parent,
772 });
773 return pkg;
774 }
775
776 pub fn deinit(self: *CliPkg) void {
777 for (self.children.toSliceConst()) |child| {
778 child.deinit();
779 }
780 self.children.deinit();
781 }
782};
783
src-self-hosted/module.zig-24
...@@ -103,30 +103,6 @@ pub const Module = struct {...@@ -103,30 +103,6 @@ pub const Module = struct {
103 LlvmIr,103 LlvmIr,
104 };104 };
105105
106 pub const CliPkg = struct {
107 name: []const u8,
108 path: []const u8,
109 children: ArrayList(*CliPkg),
110 parent: ?*CliPkg,
111
112 pub fn init(allocator: *mem.Allocator, name: []const u8, path: []const u8, parent: ?*CliPkg) !*CliPkg {
113 var pkg = try allocator.create(CliPkg{
114 .name = name,
115 .path = path,
116 .children = ArrayList(*CliPkg).init(allocator),
117 .parent = parent,
118 });
119 return pkg;
120 }
121
122 pub fn deinit(self: *CliPkg) void {
123 for (self.children.toSliceConst()) |child| {
124 child.deinit();
125 }
126 self.children.deinit();
127 }
128 };
129
130 pub fn create(106 pub fn create(
131 allocator: *mem.Allocator,107 allocator: *mem.Allocator,
132 name: []const u8,108 name: []const u8,
test/cases/bugs/1111.zig+3-3
...@@ -5,8 +5,8 @@ const Foo = extern enum {...@@ -5,8 +5,8 @@ const Foo = extern enum {
5test "issue 1111 fixed" {5test "issue 1111 fixed" {
6 const v = Foo.Bar;6 const v = Foo.Bar;
77
8 switch(v) {8 switch (v) {
9 Foo.Bar => return,9 Foo.Bar => return,
10 else => return,10 else => return,
11 }11 }
12}12}