mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
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").heap;
|
|
|
|
// 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
|
|
\\ translate-c [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.
|
|
\\
|
|
;
|