| ... | @@ -2,286 +2,38 @@ const builtin = @import("builtin"); | ... | @@ -2,286 +2,38 @@ const builtin = @import("builtin"); |
| 2 | const io = @import("std").io; | 2 | const io = @import("std").io; |
| 3 | const os = @import("std").os; | 3 | const os = @import("std").os; |
| 4 | const heap = @import("std").heap; | 4 | const heap = @import("std").heap; |
| | 5 | const warn = @import("std").debug.warn; |
| 5 | | 6 | |
| 6 | // TODO: sync up CLI with c++ code | | |
| 7 | // TODO: concurrency | | |
| 8 | | 7 | |
| 9 | error InvalidArgument; | 8 | const Token = struct { |
| 10 | error MissingArg0; | | |
| 11 | | 9 | |
| 12 | var arg0: []u8 = undefined; | 10 | }; |
| 13 | | 11 | |
| 14 | var stderr_file: io.File = undefined; | 12 | const Tokenizer = struct { |
| 15 | const stderr = &stderr_file.out_stream; | 13 | |
| | 14 | pub fn next() -> Token { |
| 16 | | 15 | |
| 17 | pub fn main() -> %void { | | |
| 18 | stderr_file = %return io.getStdErr(); | | |
| 19 | if (internal_main()) |_| { | | |
| 20 | return; | | |
| 21 | } else |err| { | | |
| 22 | if (err == error.InvalidArgument) { | | |
| 23 | stderr.print("\n") %% return err; | | |
| 24 | printUsage(stderr) %% return err; | | |
| 25 | } else { | | |
| 26 | stderr.print("{}\n", err) %% return err; | | |
| 27 | } | | |
| 28 | return err; | | |
| 29 | } | 16 | } |
| 30 | } | | |
| 31 | | 17 | |
| 32 | pub fn internal_main() -> %void { | 18 | }; |
| 33 | var args_it = os.args(); | | |
| 34 | | 19 | |
| 35 | var incrementing_allocator = heap.IncrementingAllocator.init(10 * 1024 * 1024) %% |err| { | 20 | |
| 36 | io.stderr.printf("Unable to allocate memory") %% {}; | 21 | pub fn main() -> %void { |
| | 22 | main2() %% |err| { |
| | 23 | warn("{}\n", @errorName(err)); |
| 37 | return err; | 24 | return err; |
| 38 | }; | 25 | }; |
| | 26 | } |
| | 27 | |
| | 28 | pub fn main2() -> %void { |
| | 29 | var incrementing_allocator = %return heap.IncrementingAllocator.init(10 * 1024 * 1024); |
| 39 | defer incrementing_allocator.deinit(); | 30 | defer incrementing_allocator.deinit(); |
| 40 | | 31 | |
| 41 | const allocator = &incrementing_allocator.allocator; | 32 | const allocator = &incrementing_allocator.allocator; |
| 42 | | | |
| 43 | arg0 = %return (args_it.next(allocator) ?? error.MissingArg0); | | |
| 44 | defer allocator.free(arg0); | | |
| 45 | | | |
| 46 | var build_mode = builtin.Mode.Debug; | | |
| 47 | var strip = false; | | |
| 48 | var is_static = false; | | |
| 49 | var verbose = false; | | |
| 50 | var verbose_link = false; | | |
| 51 | var verbose_ir = false; | | |
| 52 | var mwindows = false; | | |
| 53 | var mconsole = false; | | |
| 54 | | | |
| 55 | while (args_it.next()) |arg_or_err| { | | |
| 56 | const arg = %return arg_or_err; | | |
| 57 | | 33 | |
| 58 | if (arg[0] == '-') { | 34 | const target_file = "input.zig"; // TODO |
| 59 | if (strcmp(arg, "--release-fast") == 0) { | | |
| 60 | build_mode = builtin.Mode.ReleaseFast; | | |
| 61 | } else if (strcmp(arg, "--release-safe") == 0) { | | |
| 62 | build_mode = builtin.Mode.ReleaseSafe; | | |
| 63 | } else if (strcmp(arg, "--strip") == 0) { | | |
| 64 | strip = true; | | |
| 65 | } else if (strcmp(arg, "--static") == 0) { | | |
| 66 | is_static = true; | | |
| 67 | } else if (strcmp(arg, "--verbose") == 0) { | | |
| 68 | verbose = true; | | |
| 69 | } else if (strcmp(arg, "--verbose-link") == 0) { | | |
| 70 | verbose_link = true; | | |
| 71 | } else if (strcmp(arg, "--verbose-ir") == 0) { | | |
| 72 | verbose_ir = true; | | |
| 73 | } else if (strcmp(arg, "-mwindows") == 0) { | | |
| 74 | mwindows = true; | | |
| 75 | } else if (strcmp(arg, "-mconsole") == 0) { | | |
| 76 | mconsole = true; | | |
| 77 | } else if (strcmp(arg, "-municode") == 0) { | | |
| 78 | municode = true; | | |
| 79 | } else if (strcmp(arg, "-rdynamic") == 0) { | | |
| 80 | rdynamic = true; | | |
| 81 | } else if (strcmp(arg, "--each-lib-rpath") == 0) { | | |
| 82 | each_lib_rpath = true; | | |
| 83 | } else if (strcmp(arg, "--enable-timing-info") == 0) { | | |
| 84 | timing_info = true; | | |
| 85 | } else if (strcmp(arg, "--test-cmd-bin") == 0) { | | |
| 86 | test_exec_args.append(nullptr); | | |
| 87 | } else if (arg[1] == 'L' && arg[2] != 0) { | | |
| 88 | // alias for --library-path | | |
| 89 | lib_dirs.append(&arg[2]); | | |
| 90 | } else if (strcmp(arg, "--pkg-begin") == 0) { | | |
| 91 | if (i + 2 >= argc) { | | |
| 92 | fprintf(stderr, "Expected 2 arguments after --pkg-begin\n"); | | |
| 93 | return usage(arg0); | | |
| 94 | } | | |
| 95 | CliPkg *new_cur_pkg = allocate<CliPkg>(1); | | |
| 96 | i += 1; | | |
| 97 | new_cur_pkg->name = argv[i]; | | |
| 98 | i += 1; | | |
| 99 | new_cur_pkg->path = argv[i]; | | |
| 100 | new_cur_pkg->parent = cur_pkg; | | |
| 101 | cur_pkg->children.append(new_cur_pkg); | | |
| 102 | cur_pkg = new_cur_pkg; | | |
| 103 | } else if (strcmp(arg, "--pkg-end") == 0) { | | |
| 104 | if (cur_pkg->parent == nullptr) { | | |
| 105 | fprintf(stderr, "Encountered --pkg-end with no matching --pkg-begin\n"); | | |
| 106 | return EXIT_FAILURE; | | |
| 107 | } | | |
| 108 | cur_pkg = cur_pkg->parent; | | |
| 109 | } else if (i + 1 >= argc) { | | |
| 110 | fprintf(stderr, "Expected another argument after %s\n", arg); | | |
| 111 | return usage(arg0); | | |
| 112 | } else { | | |
| 113 | i += 1; | | |
| 114 | if (strcmp(arg, "--output") == 0) { | | |
| 115 | out_file = argv[i]; | | |
| 116 | } else if (strcmp(arg, "--output-h") == 0) { | | |
| 117 | out_file_h = argv[i]; | | |
| 118 | } else if (strcmp(arg, "--color") == 0) { | | |
| 119 | if (strcmp(argv[i], "auto") == 0) { | | |
| 120 | color = ErrColorAuto; | | |
| 121 | } else if (strcmp(argv[i], "on") == 0) { | | |
| 122 | color = ErrColorOn; | | |
| 123 | } else if (strcmp(argv[i], "off") == 0) { | | |
| 124 | color = ErrColorOff; | | |
| 125 | } else { | | |
| 126 | fprintf(stderr, "--color options are 'auto', 'on', or 'off'\n"); | | |
| 127 | return usage(arg0); | | |
| 128 | } | | |
| 129 | } else if (strcmp(arg, "--name") == 0) { | | |
| 130 | out_name = argv[i]; | | |
| 131 | } else if (strcmp(arg, "--libc-lib-dir") == 0) { | | |
| 132 | libc_lib_dir = argv[i]; | | |
| 133 | } else if (strcmp(arg, "--libc-static-lib-dir") == 0) { | | |
| 134 | libc_static_lib_dir = argv[i]; | | |
| 135 | } else if (strcmp(arg, "--libc-include-dir") == 0) { | | |
| 136 | libc_include_dir = argv[i]; | | |
| 137 | } else if (strcmp(arg, "--msvc-lib-dir") == 0) { | | |
| 138 | msvc_lib_dir = argv[i]; | | |
| 139 | } else if (strcmp(arg, "--kernel32-lib-dir") == 0) { | | |
| 140 | kernel32_lib_dir = argv[i]; | | |
| 141 | } else if (strcmp(arg, "--zig-install-prefix") == 0) { | | |
| 142 | zig_install_prefix = argv[i]; | | |
| 143 | } else if (strcmp(arg, "--dynamic-linker") == 0) { | | |
| 144 | dynamic_linker = argv[i]; | | |
| 145 | } else if (strcmp(arg, "-isystem") == 0) { | | |
| 146 | clang_argv.append("-isystem"); | | |
| 147 | clang_argv.append(argv[i]); | | |
| 148 | } else if (strcmp(arg, "-dirafter") == 0) { | | |
| 149 | clang_argv.append("-dirafter"); | | |
| 150 | clang_argv.append(argv[i]); | | |
| 151 | } else if (strcmp(arg, "-mllvm") == 0) { | | |
| 152 | clang_argv.append("-mllvm"); | | |
| 153 | clang_argv.append(argv[i]); | | |
| 154 | | 35 | |
| 155 | llvm_argv.append(argv[i]); | 36 | const target_file_buf = %return io.readFileAlloc(target_file, allocator); |
| 156 | } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) { | | |
| 157 | lib_dirs.append(argv[i]); | | |
| 158 | } else if (strcmp(arg, "--library") == 0) { | | |
| 159 | link_libs.append(argv[i]); | | |
| 160 | } else if (strcmp(arg, "--object") == 0) { | | |
| 161 | objects.append(argv[i]); | | |
| 162 | } else if (strcmp(arg, "--assembly") == 0) { | | |
| 163 | asm_files.append(argv[i]); | | |
| 164 | } else if (strcmp(arg, "--cache-dir") == 0) { | | |
| 165 | cache_dir = argv[i]; | | |
| 166 | } else if (strcmp(arg, "--target-arch") == 0) { | | |
| 167 | target_arch = argv[i]; | | |
| 168 | } else if (strcmp(arg, "--target-os") == 0) { | | |
| 169 | target_os = argv[i]; | | |
| 170 | } else if (strcmp(arg, "--target-environ") == 0) { | | |
| 171 | target_environ = argv[i]; | | |
| 172 | } else if (strcmp(arg, "-mmacosx-version-min") == 0) { | | |
| 173 | mmacosx_version_min = argv[i]; | | |
| 174 | } else if (strcmp(arg, "-mios-version-min") == 0) { | | |
| 175 | mios_version_min = argv[i]; | | |
| 176 | } else if (strcmp(arg, "-framework") == 0) { | | |
| 177 | frameworks.append(argv[i]); | | |
| 178 | } else if (strcmp(arg, "--linker-script") == 0) { | | |
| 179 | linker_script = argv[i]; | | |
| 180 | } else if (strcmp(arg, "-rpath") == 0) { | | |
| 181 | rpath_list.append(argv[i]); | | |
| 182 | } else if (strcmp(arg, "--test-filter") == 0) { | | |
| 183 | test_filter = argv[i]; | | |
| 184 | } else if (strcmp(arg, "--test-name-prefix") == 0) { | | |
| 185 | test_name_prefix = argv[i]; | | |
| 186 | } else if (strcmp(arg, "--ver-major") == 0) { | | |
| 187 | ver_major = atoi(argv[i]); | | |
| 188 | } else if (strcmp(arg, "--ver-minor") == 0) { | | |
| 189 | ver_minor = atoi(argv[i]); | | |
| 190 | } else if (strcmp(arg, "--ver-patch") == 0) { | | |
| 191 | ver_patch = atoi(argv[i]); | | |
| 192 | } else if (strcmp(arg, "--test-cmd") == 0) { | | |
| 193 | test_exec_args.append(argv[i]); | | |
| 194 | } else { | | |
| 195 | fprintf(stderr, "Invalid argument: %s\n", arg); | | |
| 196 | return usage(arg0); | | |
| 197 | } | | |
| 198 | } | | |
| 199 | } | | |
| 200 | } | | |
| 201 | } | | |
| 202 | | 37 | |
| 203 | fn printUsage(outstream: &io.OutStream) -> %void { | 38 | warn("{}", target_file_buf); |
| 204 | %return outstream.print("Usage: {} [command] [options]\n", arg0); | | |
| 205 | %return outstream.write( | | |
| 206 | \\Commands: | | |
| 207 | \\ build build project from build.zig | | |
| 208 | \\ build-exe [source] create executable from source or object files | | |
| 209 | \\ build-lib [source] create library from source or object files | | |
| 210 | \\ build-obj [source] create object from source or assembly | | |
| 211 | \\ translate-c [source] convert c code to zig code | | |
| 212 | \\ targets list available compilation targets | | |
| 213 | \\ test [source] create and run a test build | | |
| 214 | \\ version print version number and exit | | |
| 215 | \\ zen print zen of zig and exit | | |
| 216 | \\Compile Options: | | |
| 217 | \\ --assembly [source] add assembly file to build | | |
| 218 | \\ --cache-dir [path] override the cache directory | | |
| 219 | \\ --color [auto|off|on] enable or disable colored error messages | | |
| 220 | \\ --enable-timing-info print timing diagnostics | | |
| 221 | \\ --libc-include-dir [path] directory where libc stdlib.h resides | | |
| 222 | \\ --name [name] override output name | | |
| 223 | \\ --output [file] override destination path | | |
| 224 | \\ --output-h [file] override generated header file path | | |
| 225 | \\ --pkg-begin [name] [path] make package available to import and push current pkg | | |
| 226 | \\ --pkg-end pop current pkg | | |
| 227 | \\ --release-fast build with optimizations on and safety off | | |
| 228 | \\ --release-safe build with optimizations on and safety on | | |
| 229 | \\ --static output will be statically linked | | |
| 230 | \\ --strip exclude debug symbols | | |
| 231 | \\ --target-arch [name] specify target architecture | | |
| 232 | \\ --target-environ [name] specify target environment | | |
| 233 | \\ --target-os [name] specify target operating system | | |
| 234 | \\ --verbose turn on compiler debug output | | |
| 235 | \\ --verbose-link turn on compiler debug output for linking only | | |
| 236 | \\ --verbose-ir turn on compiler debug output for IR only | | |
| 237 | \\ --zig-install-prefix [path] override directory where zig thinks it is installed | | |
| 238 | \\ -dirafter [dir] same as -isystem but do it last | | |
| 239 | \\ -isystem [dir] add additional search path for other .h files | | |
| 240 | \\ -mllvm [arg] additional arguments to forward to LLVM's option processing | | |
| 241 | \\Link Options: | | |
| 242 | \\ --ar-path [path] set the path to ar | | |
| 243 | \\ --dynamic-linker [path] set the path to ld.so | | |
| 244 | \\ --each-lib-rpath add rpath for each used dynamic library | | |
| 245 | \\ --libc-lib-dir [path] directory where libc crt1.o resides | | |
| 246 | \\ --libc-static-lib-dir [path] directory where libc crtbegin.o resides | | |
| 247 | \\ --msvc-lib-dir [path] (windows) directory where vcruntime.lib resides | | |
| 248 | \\ --kernel32-lib-dir [path] (windows) directory where kernel32.lib resides | | |
| 249 | \\ --library [lib] link against lib | | |
| 250 | \\ --library-path [dir] add a directory to the library search path | | |
| 251 | \\ --linker-script [path] use a custom linker script | | |
| 252 | \\ --object [obj] add object file to build | | |
| 253 | \\ -L[dir] alias for --library-path | | |
| 254 | \\ -rdynamic add all symbols to the dynamic symbol table | | |
| 255 | \\ -rpath [path] add directory to the runtime library search path | | |
| 256 | \\ -mconsole (windows) --subsystem console to the linker | | |
| 257 | \\ -mwindows (windows) --subsystem windows to the linker | | |
| 258 | \\ -municode (windows) link with unicode | | |
| 259 | \\ -framework [name] (darwin) link against framework | | |
| 260 | \\ -mios-version-min [ver] (darwin) set iOS deployment target | | |
| 261 | \\ -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target | | |
| 262 | \\ --ver-major [ver] dynamic library semver major version | | |
| 263 | \\ --ver-minor [ver] dynamic library semver minor version | | |
| 264 | \\ --ver-patch [ver] dynamic library semver patch version | | |
| 265 | \\Test Options: | | |
| 266 | \\ --test-filter [text] skip tests that do not match filter | | |
| 267 | \\ --test-name-prefix [text] add prefix to all tests | | |
| 268 | \\ --test-cmd [arg] specify test execution command one arg at a time | | |
| 269 | \\ --test-cmd-bin appends test binary path to test cmd args | | |
| 270 | \\ | | |
| 271 | ); | | |
| 272 | } | 39 | } |
| 273 | | | |
| 274 | const ZIG_ZEN = | | |
| 275 | \\ * Communicate intent precisely. | | |
| 276 | \\ * Edge cases matter. | | |
| 277 | \\ * Favor reading code over writing code. | | |
| 278 | \\ * Only one obvious way to do things. | | |
| 279 | \\ * Runtime crashes are better than bugs. | | |
| 280 | \\ * Compile errors are better than runtime crashes. | | |
| 281 | \\ * Incremental improvements. | | |
| 282 | \\ * Avoid local maximums. | | |
| 283 | \\ * Reduce the amount one must remember. | | |
| 284 | \\ * Minimize energy spent on coding style. | | |
| 285 | \\ * Together we serve end users. | | |
| 286 | \\ | | |
| 287 | ; | | |