mirror of
https://github.com/ziglang/zig.git
synced 2026-01-15 20:05:16 +00:00
see #383 there is a plan to unify most of the reflection into 2 builtin functions, as outlined in the above issue, but this gives us needed features for now, and we can iterate on the design in future commits
288 lines
14 KiB
Zig
288 lines
14 KiB
Zig
const builtin = @import("builtin");
|
|
const io = @import("std").io;
|
|
const os = @import("std").os;
|
|
const heap = @import("std").mem;
|
|
|
|
// TODO: sync up CLI with c++ code
|
|
// TODO: concurrency
|
|
|
|
error InvalidArgument;
|
|
error MissingArg0;
|
|
|
|
var arg0: []u8 = undefined;
|
|
|
|
var stderr_file: io.File = undefined;
|
|
const stderr = &stderr_file.out_stream;
|
|
|
|
pub fn main() -> %void {
|
|
stderr_file = %return io.getStdErr();
|
|
if (internal_main()) |_| {
|
|
return;
|
|
} else |err| {
|
|
if (err == error.InvalidArgument) {
|
|
stderr.print("\n") %% return err;
|
|
printUsage(stderr) %% return err;
|
|
} else {
|
|
stderr.print("{}\n", err) %% return err;
|
|
}
|
|
return err;
|
|
}
|
|
}
|
|
|
|
pub fn internal_main() -> %void {
|
|
var args_it = os.args();
|
|
|
|
var incrementing_allocator = heap.IncrementingAllocator.init(10 * 1024 * 1024) %% |err| {
|
|
io.stderr.printf("Unable to allocate memory") %% {};
|
|
return err;
|
|
};
|
|
defer incrementing_allocator.deinit();
|
|
|
|
const allocator = &incrementing_allocator.allocator;
|
|
|
|
arg0 = %return (args_it.next(allocator) ?? error.MissingArg0);
|
|
defer allocator.free(arg0);
|
|
|
|
var build_mode = builtin.Mode.Debug;
|
|
var strip = false;
|
|
var is_static = false;
|
|
var verbose = false;
|
|
var verbose_link = false;
|
|
var verbose_ir = false;
|
|
var mwindows = false;
|
|
var mconsole = false;
|
|
|
|
while (args_it.next()) |arg_or_err| {
|
|
const arg = %return arg_or_err;
|
|
|
|
if (arg[0] == '-') {
|
|
if (strcmp(arg, "--release-fast") == 0) {
|
|
build_mode = builtin.Mode.ReleaseFast;
|
|
} else if (strcmp(arg, "--release-safe") == 0) {
|
|
build_mode = builtin.Mode.ReleaseSafe;
|
|
} else if (strcmp(arg, "--strip") == 0) {
|
|
strip = true;
|
|
} else if (strcmp(arg, "--static") == 0) {
|
|
is_static = true;
|
|
} else if (strcmp(arg, "--verbose") == 0) {
|
|
verbose = true;
|
|
} else if (strcmp(arg, "--verbose-link") == 0) {
|
|
verbose_link = true;
|
|
} else if (strcmp(arg, "--verbose-ir") == 0) {
|
|
verbose_ir = true;
|
|
} else if (strcmp(arg, "-mwindows") == 0) {
|
|
mwindows = true;
|
|
} else if (strcmp(arg, "-mconsole") == 0) {
|
|
mconsole = true;
|
|
} else if (strcmp(arg, "-municode") == 0) {
|
|
municode = true;
|
|
} else if (strcmp(arg, "-rdynamic") == 0) {
|
|
rdynamic = true;
|
|
} else if (strcmp(arg, "--each-lib-rpath") == 0) {
|
|
each_lib_rpath = true;
|
|
} else if (strcmp(arg, "--enable-timing-info") == 0) {
|
|
timing_info = true;
|
|
} else if (strcmp(arg, "--test-cmd-bin") == 0) {
|
|
test_exec_args.append(nullptr);
|
|
} else if (arg[1] == 'L' && arg[2] != 0) {
|
|
// alias for --library-path
|
|
lib_dirs.append(&arg[2]);
|
|
} else if (strcmp(arg, "--pkg-begin") == 0) {
|
|
if (i + 2 >= argc) {
|
|
fprintf(stderr, "Expected 2 arguments after --pkg-begin\n");
|
|
return usage(arg0);
|
|
}
|
|
CliPkg *new_cur_pkg = allocate<CliPkg>(1);
|
|
i += 1;
|
|
new_cur_pkg->name = argv[i];
|
|
i += 1;
|
|
new_cur_pkg->path = argv[i];
|
|
new_cur_pkg->parent = cur_pkg;
|
|
cur_pkg->children.append(new_cur_pkg);
|
|
cur_pkg = new_cur_pkg;
|
|
} else if (strcmp(arg, "--pkg-end") == 0) {
|
|
if (cur_pkg->parent == nullptr) {
|
|
fprintf(stderr, "Encountered --pkg-end with no matching --pkg-begin\n");
|
|
return EXIT_FAILURE;
|
|
}
|
|
cur_pkg = cur_pkg->parent;
|
|
} else if (i + 1 >= argc) {
|
|
fprintf(stderr, "Expected another argument after %s\n", arg);
|
|
return usage(arg0);
|
|
} else {
|
|
i += 1;
|
|
if (strcmp(arg, "--output") == 0) {
|
|
out_file = argv[i];
|
|
} else if (strcmp(arg, "--output-h") == 0) {
|
|
out_file_h = argv[i];
|
|
} else if (strcmp(arg, "--color") == 0) {
|
|
if (strcmp(argv[i], "auto") == 0) {
|
|
color = ErrColorAuto;
|
|
} else if (strcmp(argv[i], "on") == 0) {
|
|
color = ErrColorOn;
|
|
} else if (strcmp(argv[i], "off") == 0) {
|
|
color = ErrColorOff;
|
|
} else {
|
|
fprintf(stderr, "--color options are 'auto', 'on', or 'off'\n");
|
|
return usage(arg0);
|
|
}
|
|
} else if (strcmp(arg, "--name") == 0) {
|
|
out_name = argv[i];
|
|
} else if (strcmp(arg, "--libc-lib-dir") == 0) {
|
|
libc_lib_dir = argv[i];
|
|
} else if (strcmp(arg, "--libc-static-lib-dir") == 0) {
|
|
libc_static_lib_dir = argv[i];
|
|
} else if (strcmp(arg, "--libc-include-dir") == 0) {
|
|
libc_include_dir = argv[i];
|
|
} else if (strcmp(arg, "--msvc-lib-dir") == 0) {
|
|
msvc_lib_dir = argv[i];
|
|
} else if (strcmp(arg, "--kernel32-lib-dir") == 0) {
|
|
kernel32_lib_dir = argv[i];
|
|
} else if (strcmp(arg, "--zig-install-prefix") == 0) {
|
|
zig_install_prefix = argv[i];
|
|
} else if (strcmp(arg, "--dynamic-linker") == 0) {
|
|
dynamic_linker = argv[i];
|
|
} else if (strcmp(arg, "-isystem") == 0) {
|
|
clang_argv.append("-isystem");
|
|
clang_argv.append(argv[i]);
|
|
} else if (strcmp(arg, "-dirafter") == 0) {
|
|
clang_argv.append("-dirafter");
|
|
clang_argv.append(argv[i]);
|
|
} else if (strcmp(arg, "-mllvm") == 0) {
|
|
clang_argv.append("-mllvm");
|
|
clang_argv.append(argv[i]);
|
|
|
|
llvm_argv.append(argv[i]);
|
|
} else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) {
|
|
lib_dirs.append(argv[i]);
|
|
} else if (strcmp(arg, "--library") == 0) {
|
|
link_libs.append(argv[i]);
|
|
} else if (strcmp(arg, "--object") == 0) {
|
|
objects.append(argv[i]);
|
|
} else if (strcmp(arg, "--assembly") == 0) {
|
|
asm_files.append(argv[i]);
|
|
} else if (strcmp(arg, "--cache-dir") == 0) {
|
|
cache_dir = argv[i];
|
|
} else if (strcmp(arg, "--target-arch") == 0) {
|
|
target_arch = argv[i];
|
|
} else if (strcmp(arg, "--target-os") == 0) {
|
|
target_os = argv[i];
|
|
} else if (strcmp(arg, "--target-environ") == 0) {
|
|
target_environ = argv[i];
|
|
} else if (strcmp(arg, "-mmacosx-version-min") == 0) {
|
|
mmacosx_version_min = argv[i];
|
|
} else if (strcmp(arg, "-mios-version-min") == 0) {
|
|
mios_version_min = argv[i];
|
|
} else if (strcmp(arg, "-framework") == 0) {
|
|
frameworks.append(argv[i]);
|
|
} else if (strcmp(arg, "--linker-script") == 0) {
|
|
linker_script = argv[i];
|
|
} else if (strcmp(arg, "-rpath") == 0) {
|
|
rpath_list.append(argv[i]);
|
|
} else if (strcmp(arg, "--test-filter") == 0) {
|
|
test_filter = argv[i];
|
|
} else if (strcmp(arg, "--test-name-prefix") == 0) {
|
|
test_name_prefix = argv[i];
|
|
} else if (strcmp(arg, "--ver-major") == 0) {
|
|
ver_major = atoi(argv[i]);
|
|
} else if (strcmp(arg, "--ver-minor") == 0) {
|
|
ver_minor = atoi(argv[i]);
|
|
} else if (strcmp(arg, "--ver-patch") == 0) {
|
|
ver_patch = atoi(argv[i]);
|
|
} else if (strcmp(arg, "--test-cmd") == 0) {
|
|
test_exec_args.append(argv[i]);
|
|
} else {
|
|
fprintf(stderr, "Invalid argument: %s\n", arg);
|
|
return usage(arg0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn printUsage(outstream: &io.OutStream) -> %void {
|
|
%return outstream.print("Usage: {} [command] [options]\n", arg0);
|
|
%return outstream.write(
|
|
\\Commands:
|
|
\\ build build project from build.zig
|
|
\\ build-exe [source] create executable from source or object files
|
|
\\ build-lib [source] create library from source or object files
|
|
\\ build-obj [source] create object from source or assembly
|
|
\\ parsec [source] convert c code to zig code
|
|
\\ targets list available compilation targets
|
|
\\ test [source] create and run a test build
|
|
\\ version print version number and exit
|
|
\\ zen print zen of zig and exit
|
|
\\Compile Options:
|
|
\\ --assembly [source] add assembly file to build
|
|
\\ --cache-dir [path] override the cache directory
|
|
\\ --color [auto|off|on] enable or disable colored error messages
|
|
\\ --enable-timing-info print timing diagnostics
|
|
\\ --libc-include-dir [path] directory where libc stdlib.h resides
|
|
\\ --name [name] override output name
|
|
\\ --output [file] override destination path
|
|
\\ --output-h [file] override generated header file path
|
|
\\ --pkg-begin [name] [path] make package available to import and push current pkg
|
|
\\ --pkg-end pop current pkg
|
|
\\ --release-fast build with optimizations on and safety off
|
|
\\ --release-safe build with optimizations on and safety on
|
|
\\ --static output will be statically linked
|
|
\\ --strip exclude debug symbols
|
|
\\ --target-arch [name] specify target architecture
|
|
\\ --target-environ [name] specify target environment
|
|
\\ --target-os [name] specify target operating system
|
|
\\ --verbose turn on compiler debug output
|
|
\\ --verbose-link turn on compiler debug output for linking only
|
|
\\ --verbose-ir turn on compiler debug output for IR only
|
|
\\ --zig-install-prefix [path] override directory where zig thinks it is installed
|
|
\\ -dirafter [dir] same as -isystem but do it last
|
|
\\ -isystem [dir] add additional search path for other .h files
|
|
\\ -mllvm [arg] additional arguments to forward to LLVM's option processing
|
|
\\Link Options:
|
|
\\ --ar-path [path] set the path to ar
|
|
\\ --dynamic-linker [path] set the path to ld.so
|
|
\\ --each-lib-rpath add rpath for each used dynamic library
|
|
\\ --libc-lib-dir [path] directory where libc crt1.o resides
|
|
\\ --libc-static-lib-dir [path] directory where libc crtbegin.o resides
|
|
\\ --msvc-lib-dir [path] (windows) directory where vcruntime.lib resides
|
|
\\ --kernel32-lib-dir [path] (windows) directory where kernel32.lib resides
|
|
\\ --library [lib] link against lib
|
|
\\ --library-path [dir] add a directory to the library search path
|
|
\\ --linker-script [path] use a custom linker script
|
|
\\ --object [obj] add object file to build
|
|
\\ -L[dir] alias for --library-path
|
|
\\ -rdynamic add all symbols to the dynamic symbol table
|
|
\\ -rpath [path] add directory to the runtime library search path
|
|
\\ -mconsole (windows) --subsystem console to the linker
|
|
\\ -mwindows (windows) --subsystem windows to the linker
|
|
\\ -municode (windows) link with unicode
|
|
\\ -framework [name] (darwin) link against framework
|
|
\\ -mios-version-min [ver] (darwin) set iOS deployment target
|
|
\\ -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target
|
|
\\ --ver-major [ver] dynamic library semver major version
|
|
\\ --ver-minor [ver] dynamic library semver minor version
|
|
\\ --ver-patch [ver] dynamic library semver patch version
|
|
\\Test Options:
|
|
\\ --test-filter [text] skip tests that do not match filter
|
|
\\ --test-name-prefix [text] add prefix to all tests
|
|
\\ --test-cmd [arg] specify test execution command one arg at a time
|
|
\\ --test-cmd-bin appends test binary path to test cmd args
|
|
\\
|
|
);
|
|
}
|
|
|
|
const ZIG_ZEN =
|
|
\\ * Communicate intent precisely.
|
|
\\ * Edge cases matter.
|
|
\\ * Favor reading code over writing code.
|
|
\\ * Only one obvious way to do things.
|
|
\\ * Runtime crashes are better than bugs.
|
|
\\ * Compile errors are better than runtime crashes.
|
|
\\ * Incremental improvements.
|
|
\\ * Avoid local maximums.
|
|
\\ * Reduce the amount one must remember.
|
|
\\ * Minimize energy spent on coding style.
|
|
\\ * Together we serve end users.
|
|
\\
|
|
;
|