| ... | ... | @@ -2,286 +2,38 @@ const builtin = @import("builtin"); |
| 2 | 2 | const io = @import("std").io; |
| 3 | 3 | const os = @import("std").os; |
| 4 | 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; |
| 10 | | error MissingArg0; |
| 8 | const Token = struct { |
| 11 | 9 | |
| 12 | | var arg0: []u8 = undefined; |
| 10 | }; |
| 13 | 11 | |
| 14 | | var stderr_file: io.File = undefined; |
| 15 | | const stderr = &stderr_file.out_stream; |
| 12 | const Tokenizer = struct { |
| 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 { |
| 33 | | var args_it = os.args(); |
| 18 | }; |
| 34 | 19 | |
| 35 | | var incrementing_allocator = heap.IncrementingAllocator.init(10 * 1024 * 1024) %% |err| { |
| 36 | | io.stderr.printf("Unable to allocate memory") %% {}; |
| 20 | |
| 21 | pub fn main() -> %void { |
| 22 | main2() %% |err| { |
| 23 | warn("{}\n", @errorName(err)); |
| 37 | 24 | return err; |
| 38 | 25 | }; |
| 26 | } |
| 27 | |
| 28 | pub fn main2() -> %void { |
| 29 | var incrementing_allocator = %return heap.IncrementingAllocator.init(10 * 1024 * 1024); |
| 39 | 30 | defer incrementing_allocator.deinit(); |
| 40 | 31 | |
| 41 | 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] == '-') { |
| 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]); |
| 34 | const target_file = "input.zig"; // TODO |
| 154 | 35 | |
| 155 | | llvm_argv.append(argv[i]); |
| 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 | | } |
| 36 | const target_file_buf = %return io.readFileAlloc(target_file, allocator); |
| 202 | 37 | |
| 203 | | fn printUsage(outstream: &io.OutStream) -> %void { |
| 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 | | ); |
| 38 | warn("{}", target_file_buf); |
| 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 | | ; |