implement -femit-asm, -femit-docs, -femit-llvm-ir, etc
These CLI options are now forwarded to the stage1 backend. We're not going to support the -mllvm CLI option any longer. As a compromise, we unconditionally tell LLVM to output intel x86 syntax when using -femit-asm. Simplify stage1 logic; it no longer has the concept of an output directory. --output-dir is no longer a valid CLI option. cmake uses the `-femit-bin=[path]` option. Note the changes to test/cli.zig. This breaks the CLI API that Godbolt is using so we're going to want to open a PR to help them upgrade to the new CLI for the upcoming Zig 0.7.0 release.master
parent
a337046832
commit
6af2990549
13
BRANCH_TODO
13
BRANCH_TODO
|
@ -1,13 +1,7 @@
|
||||||
|
* support -fno-emit-bin for godbolt
|
||||||
* tests passing with -Dskip-non-native
|
* tests passing with -Dskip-non-native
|
||||||
* `-ftime-report`
|
* `-ftime-report`
|
||||||
* -fstack-report print stack size diagnostics\n"
|
* -fstack-report print stack size diagnostics\n"
|
||||||
* -fdump-analysis write analysis.json file with type information\n"
|
|
||||||
* -femit-docs create a docs/ dir with html documentation\n"
|
|
||||||
* -fno-emit-docs do not produce docs/ dir with html documentation\n"
|
|
||||||
* -femit-asm output .s (assembly code)\n"
|
|
||||||
* -fno-emit-asm (default) do not output .s (assembly code)\n"
|
|
||||||
* -femit-llvm-ir produce a .ll file with LLVM IR\n"
|
|
||||||
* -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"
|
|
||||||
* mingw-w64
|
* mingw-w64
|
||||||
* MachO LLD linking
|
* MachO LLD linking
|
||||||
* COFF LLD linking
|
* COFF LLD linking
|
||||||
|
@ -17,8 +11,8 @@
|
||||||
* On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process.
|
* On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process.
|
||||||
* restore error messages for stage2_add_link_lib
|
* restore error messages for stage2_add_link_lib
|
||||||
* windows CUSTOMBUILD : error : unable to build compiler_rt: FileNotFound [D:\a\1\s\build\zig_install_lib_files.vcxproj]
|
* windows CUSTOMBUILD : error : unable to build compiler_rt: FileNotFound [D:\a\1\s\build\zig_install_lib_files.vcxproj]
|
||||||
* try building some software with zig cc
|
* try building some software with zig cc to make sure it didn't regress
|
||||||
* implement support for -femit-asm
|
* restore the legacy -femit-h feature using the stage1 backend
|
||||||
|
|
||||||
* implement proper parsing of clang stderr/stdout and exposing compile errors with the Compilation API
|
* implement proper parsing of clang stderr/stdout and exposing compile errors with the Compilation API
|
||||||
* implement proper parsing of LLD stderr/stdout and exposing compile errors with the Compilation API
|
* implement proper parsing of LLD stderr/stdout and exposing compile errors with the Compilation API
|
||||||
|
@ -56,3 +50,4 @@
|
||||||
* make std.Progress support multithreaded
|
* make std.Progress support multithreaded
|
||||||
* update musl.zig static data to use native path separator in static data rather than replacing '/' at runtime
|
* update musl.zig static data to use native path separator in static data rather than replacing '/' at runtime
|
||||||
* linking hello world with LLD, lld is silently calling exit(1) instead of reporting ok=false. when run standalone the error message is: ld.lld: error: section [index 3] has a sh_offset (0x57000) + sh_size (0x68) that is greater than the file size (0x57060)
|
* linking hello world with LLD, lld is silently calling exit(1) instead of reporting ok=false. when run standalone the error message is: ld.lld: error: section [index 3] has a sh_offset (0x57000) + sh_size (0x68) that is greater than the file size (0x57060)
|
||||||
|
* submit PR to godbolt and update the CLI options (see changes to test/cli.zig)
|
||||||
|
|
|
@ -449,7 +449,7 @@ endif()
|
||||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||||
set(ZIG1_RELEASE_ARG "")
|
set(ZIG1_RELEASE_ARG "")
|
||||||
else()
|
else()
|
||||||
set(ZIG1_RELEASE_ARG --release-fast --strip)
|
set(ZIG1_RELEASE_ARG -OReleaseFast --strip)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(BUILD_ZIG1_ARGS
|
set(BUILD_ZIG1_ARGS
|
||||||
|
@ -458,8 +458,8 @@ set(BUILD_ZIG1_ARGS
|
||||||
"-mcpu=${ZIG_TARGET_MCPU}"
|
"-mcpu=${ZIG_TARGET_MCPU}"
|
||||||
--name zig1
|
--name zig1
|
||||||
--override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
|
--override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
|
||||||
--output-dir "${CMAKE_BINARY_DIR}"
|
"-femit-bin=${ZIG1_OBJECT}"
|
||||||
${ZIG1_RELEASE_ARG}
|
"${ZIG1_RELEASE_ARG}"
|
||||||
-lc
|
-lc
|
||||||
--pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}"
|
--pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}"
|
||||||
--pkg-end
|
--pkg-end
|
||||||
|
|
|
@ -107,6 +107,12 @@ test_filter: ?[]const u8,
|
||||||
test_name_prefix: ?[]const u8,
|
test_name_prefix: ?[]const u8,
|
||||||
test_evented_io: bool,
|
test_evented_io: bool,
|
||||||
|
|
||||||
|
emit_h: ?EmitLoc,
|
||||||
|
emit_asm: ?EmitLoc,
|
||||||
|
emit_llvm_ir: ?EmitLoc,
|
||||||
|
emit_analysis: ?EmitLoc,
|
||||||
|
emit_docs: ?EmitLoc,
|
||||||
|
|
||||||
pub const InnerError = Module.InnerError;
|
pub const InnerError = Module.InnerError;
|
||||||
|
|
||||||
pub const CRTFile = struct {
|
pub const CRTFile = struct {
|
||||||
|
@ -296,6 +302,12 @@ pub const InitOptions = struct {
|
||||||
emit_h: ?EmitLoc = null,
|
emit_h: ?EmitLoc = null,
|
||||||
/// `null` means to not emit assembly.
|
/// `null` means to not emit assembly.
|
||||||
emit_asm: ?EmitLoc = null,
|
emit_asm: ?EmitLoc = null,
|
||||||
|
/// `null` means to not emit LLVM IR.
|
||||||
|
emit_llvm_ir: ?EmitLoc = null,
|
||||||
|
/// `null` means to not emit semantic analysis JSON.
|
||||||
|
emit_analysis: ?EmitLoc = null,
|
||||||
|
/// `null` means to not emit docs.
|
||||||
|
emit_docs: ?EmitLoc = null,
|
||||||
link_mode: ?std.builtin.LinkMode = null,
|
link_mode: ?std.builtin.LinkMode = null,
|
||||||
dll_export_fns: ?bool = false,
|
dll_export_fns: ?bool = false,
|
||||||
/// Normally when using LLD to link, Zig uses a file named "lld.id" in the
|
/// Normally when using LLD to link, Zig uses a file named "lld.id" in the
|
||||||
|
@ -442,7 +454,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
break :blk false;
|
break :blk false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const link_libc = options.link_libc or
|
const link_libc = options.link_libc or
|
||||||
(is_exe_or_dyn_lib and target_util.osRequiresLibC(options.target));
|
(is_exe_or_dyn_lib and target_util.osRequiresLibC(options.target));
|
||||||
|
|
||||||
|
@ -489,9 +500,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
break :pic explicit;
|
break :pic explicit;
|
||||||
} else must_pic;
|
} else must_pic;
|
||||||
|
|
||||||
if (options.emit_h != null) fatal("-femit-h not supported yet", .{}); // TODO
|
|
||||||
if (options.emit_asm != null) fatal("-femit-asm not supported yet", .{}); // TODO
|
|
||||||
|
|
||||||
const emit_bin = options.emit_bin orelse fatal("-fno-emit-bin not supported yet", .{}); // TODO
|
const emit_bin = options.emit_bin orelse fatal("-fno-emit-bin not supported yet", .{}); // TODO
|
||||||
|
|
||||||
// Make a decision on whether to use Clang for translate-c and compiling C files.
|
// Make a decision on whether to use Clang for translate-c and compiling C files.
|
||||||
|
@ -579,6 +587,12 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
cache.hash.add(options.link_libcpp);
|
cache.hash.add(options.link_libcpp);
|
||||||
cache.hash.add(options.output_mode);
|
cache.hash.add(options.output_mode);
|
||||||
cache.hash.add(options.machine_code_model);
|
cache.hash.add(options.machine_code_model);
|
||||||
|
cache.hash.add(options.emit_bin != null);
|
||||||
|
cache.hash.add(options.emit_h != null);
|
||||||
|
cache.hash.add(options.emit_asm != null);
|
||||||
|
cache.hash.add(options.emit_llvm_ir != null);
|
||||||
|
cache.hash.add(options.emit_analysis != null);
|
||||||
|
cache.hash.add(options.emit_docs != null);
|
||||||
// TODO audit this and make sure everything is in it
|
// TODO audit this and make sure everything is in it
|
||||||
|
|
||||||
const module: ?*Module = if (options.root_pkg) |root_pkg| blk: {
|
const module: ?*Module = if (options.root_pkg) |root_pkg| blk: {
|
||||||
|
@ -752,6 +766,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
.local_cache_directory = options.local_cache_directory,
|
.local_cache_directory = options.local_cache_directory,
|
||||||
.global_cache_directory = options.global_cache_directory,
|
.global_cache_directory = options.global_cache_directory,
|
||||||
.bin_file = bin_file,
|
.bin_file = bin_file,
|
||||||
|
.emit_h = options.emit_h,
|
||||||
|
.emit_asm = options.emit_asm,
|
||||||
|
.emit_llvm_ir = options.emit_llvm_ir,
|
||||||
|
.emit_analysis = options.emit_analysis,
|
||||||
|
.emit_docs = options.emit_docs,
|
||||||
.work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
|
.work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
|
||||||
.keep_source_files_loaded = options.keep_source_files_loaded,
|
.keep_source_files_loaded = options.keep_source_files_loaded,
|
||||||
.use_clang = use_clang,
|
.use_clang = use_clang,
|
||||||
|
@ -1450,8 +1469,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
|
||||||
|
|
||||||
try argv.ensureCapacity(argv.items.len + 3);
|
try argv.ensureCapacity(argv.items.len + 3);
|
||||||
switch (comp.clang_preprocessor_mode) {
|
switch (comp.clang_preprocessor_mode) {
|
||||||
.no => argv.appendSliceAssumeCapacity(&[_][]const u8{"-c", "-o", out_obj_path}),
|
.no => argv.appendSliceAssumeCapacity(&[_][]const u8{ "-c", "-o", out_obj_path }),
|
||||||
.yes => argv.appendSliceAssumeCapacity(&[_][]const u8{"-E", "-o", out_obj_path}),
|
.yes => argv.appendSliceAssumeCapacity(&[_][]const u8{ "-E", "-o", out_obj_path }),
|
||||||
.stdout => argv.appendAssumeCapacity("-E"),
|
.stdout => argv.appendAssumeCapacity("-E"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2498,15 +2517,35 @@ fn updateStage1Module(comp: *Compilation) !void {
|
||||||
comp.is_test,
|
comp.is_test,
|
||||||
) orelse return error.OutOfMemory;
|
) orelse return error.OutOfMemory;
|
||||||
|
|
||||||
|
const bin_basename = try std.zig.binNameAlloc(arena, .{
|
||||||
|
.root_name = comp.bin_file.options.root_name,
|
||||||
|
.target = target,
|
||||||
|
.output_mode = .Obj,
|
||||||
|
});
|
||||||
|
const emit_bin_path = try directory.join(arena, &[_][]const u8{bin_basename});
|
||||||
|
const emit_h_path = try stage1LocPath(arena, comp.emit_h, directory);
|
||||||
|
const emit_asm_path = try stage1LocPath(arena, comp.emit_asm, directory);
|
||||||
|
const emit_llvm_ir_path = try stage1LocPath(arena, comp.emit_llvm_ir, directory);
|
||||||
|
const emit_analysis_path = try stage1LocPath(arena, comp.emit_analysis, directory);
|
||||||
|
const emit_docs_path = try stage1LocPath(arena, comp.emit_docs, directory);
|
||||||
const stage1_pkg = try createStage1Pkg(arena, "root", mod.root_pkg, null);
|
const stage1_pkg = try createStage1Pkg(arena, "root", mod.root_pkg, null);
|
||||||
const output_dir = directory.path orelse ".";
|
|
||||||
const test_filter = comp.test_filter orelse ""[0..0];
|
const test_filter = comp.test_filter orelse ""[0..0];
|
||||||
const test_name_prefix = comp.test_name_prefix orelse ""[0..0];
|
const test_name_prefix = comp.test_name_prefix orelse ""[0..0];
|
||||||
stage1_module.* = .{
|
stage1_module.* = .{
|
||||||
.root_name_ptr = comp.bin_file.options.root_name.ptr,
|
.root_name_ptr = comp.bin_file.options.root_name.ptr,
|
||||||
.root_name_len = comp.bin_file.options.root_name.len,
|
.root_name_len = comp.bin_file.options.root_name.len,
|
||||||
.output_dir_ptr = output_dir.ptr,
|
.emit_o_ptr = emit_bin_path.ptr,
|
||||||
.output_dir_len = output_dir.len,
|
.emit_o_len = emit_bin_path.len,
|
||||||
|
.emit_h_ptr = emit_h_path.ptr,
|
||||||
|
.emit_h_len = emit_h_path.len,
|
||||||
|
.emit_asm_ptr = emit_asm_path.ptr,
|
||||||
|
.emit_asm_len = emit_asm_path.len,
|
||||||
|
.emit_llvm_ir_ptr = emit_llvm_ir_path.ptr,
|
||||||
|
.emit_llvm_ir_len = emit_llvm_ir_path.len,
|
||||||
|
.emit_analysis_json_ptr = emit_analysis_path.ptr,
|
||||||
|
.emit_analysis_json_len = emit_analysis_path.len,
|
||||||
|
.emit_docs_ptr = emit_docs_path.ptr,
|
||||||
|
.emit_docs_len = emit_docs_path.len,
|
||||||
.builtin_zig_path_ptr = builtin_zig_path.ptr,
|
.builtin_zig_path_ptr = builtin_zig_path.ptr,
|
||||||
.builtin_zig_path_len = builtin_zig_path.len,
|
.builtin_zig_path_len = builtin_zig_path.len,
|
||||||
.test_filter_ptr = test_filter.ptr,
|
.test_filter_ptr = test_filter.ptr,
|
||||||
|
@ -2530,11 +2569,6 @@ fn updateStage1Module(comp: *Compilation) !void {
|
||||||
.enable_stack_probing = comp.bin_file.options.stack_check,
|
.enable_stack_probing = comp.bin_file.options.stack_check,
|
||||||
.enable_time_report = comp.time_report,
|
.enable_time_report = comp.time_report,
|
||||||
.enable_stack_report = false,
|
.enable_stack_report = false,
|
||||||
.dump_analysis = false,
|
|
||||||
.enable_doc_generation = false,
|
|
||||||
.emit_bin = true,
|
|
||||||
.emit_asm = false,
|
|
||||||
.emit_llvm_ir = false,
|
|
||||||
.test_is_evented = comp.test_evented_io,
|
.test_is_evented = comp.test_evented_io,
|
||||||
.verbose_tokenize = comp.verbose_tokenize,
|
.verbose_tokenize = comp.verbose_tokenize,
|
||||||
.verbose_ast = comp.verbose_ast,
|
.verbose_ast = comp.verbose_ast,
|
||||||
|
@ -2565,6 +2599,12 @@ fn updateStage1Module(comp: *Compilation) !void {
|
||||||
comp.stage1_lock = man.toOwnedLock();
|
comp.stage1_lock = man.toOwnedLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stage1LocPath(arena: *Allocator, opt_loc: ?EmitLoc, cache_directory: Directory) ![]const u8 {
|
||||||
|
const loc = opt_loc orelse return "";
|
||||||
|
const directory = loc.directory orelse cache_directory;
|
||||||
|
return directory.join(arena, &[_][]const u8{loc.basename});
|
||||||
|
}
|
||||||
|
|
||||||
fn createStage1Pkg(
|
fn createStage1Pkg(
|
||||||
arena: *Allocator,
|
arena: *Allocator,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
|
|
|
@ -72,3 +72,6 @@ pub const OSType = extern enum(c_int) {
|
||||||
WASI = 34,
|
WASI = 34,
|
||||||
Emscripten = 35,
|
Emscripten = 35,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const ParseCommandLineOptions = ZigLLVMParseCommandLineOptions;
|
||||||
|
extern fn ZigLLVMParseCommandLineOptions(argc: usize, argv: [*]const [*:0]const u8) void;
|
||||||
|
|
157
src/main.zig
157
src/main.zig
|
@ -195,8 +195,20 @@ const usage_build_generic =
|
||||||
\\ -h, --help Print this help and exit
|
\\ -h, --help Print this help and exit
|
||||||
\\ --watch Enable compiler REPL
|
\\ --watch Enable compiler REPL
|
||||||
\\ --color [auto|off|on] Enable or disable colored error messages
|
\\ --color [auto|off|on] Enable or disable colored error messages
|
||||||
\\ -femit-bin[=path] (default) output machine code
|
\\ -femit-bin[=path] (default) Output machine code
|
||||||
\\ -fno-emit-bin Do not output machine code
|
\\ -fno-emit-bin Do not output machine code
|
||||||
|
\\ -femit-asm[=path] Output .s (assembly code)
|
||||||
|
\\ -fno-emit-asm (default) Do not output .s (assembly code)
|
||||||
|
\\ -femit-zir[=path] Produce a .zir file with Zig IR
|
||||||
|
\\ -fno-emit-zir (default) Do not produce a .zir file with Zig IR
|
||||||
|
\\ -femit-llvm-ir[=path] Produce a .ll file with LLVM IR (requires LLVM extensions)
|
||||||
|
\\ -fno-emit-llvm-ir (default) Do not produce a .ll file with LLVM IR
|
||||||
|
\\ -femit-h[=path] Generate a C header file (.h)
|
||||||
|
\\ -fno-emit-h (default) Do not generate a C header file (.h)
|
||||||
|
\\ -femit-docs[=path] Create a docs/ dir with html documentation
|
||||||
|
\\ -fno-emit-docs (default) Do not produce docs/ dir with html documentation
|
||||||
|
\\ -femit-analysis[=path] Write analysis JSON file with type information
|
||||||
|
\\ -fno-emit-analysis (default) Do not write analysis JSON file with type information
|
||||||
\\ --show-builtin Output the source of @import("builtin") then exit
|
\\ --show-builtin Output the source of @import("builtin") then exit
|
||||||
\\ --cache-dir [path] Override the local cache directory
|
\\ --cache-dir [path] Override the local cache directory
|
||||||
\\ --global-cache-dir [path] Override the global cache directory
|
\\ --global-cache-dir [path] Override the global cache directory
|
||||||
|
@ -210,10 +222,11 @@ const usage_build_generic =
|
||||||
\\ small|kernel|
|
\\ small|kernel|
|
||||||
\\ medium|large]
|
\\ medium|large]
|
||||||
\\ --name [name] Override root name (not a file path)
|
\\ --name [name] Override root name (not a file path)
|
||||||
\\ -ODebug (default) optimizations off, safety on
|
\\ -O [mode] Choose what to optimize for
|
||||||
\\ -OReleaseFast Optimizations on, safety off
|
\\ Debug (default) Optimizations off, safety on
|
||||||
\\ -OReleaseSafe Optimizations on, safety on
|
\\ ReleaseFast Optimizations on, safety off
|
||||||
\\ -OReleaseSmall Optimize for small binary, safety off
|
\\ ReleaseSafe Optimizations on, safety on
|
||||||
|
\\ ReleaseSmall Optimize for small binary, safety off
|
||||||
\\ --pkg-begin [name] [path] Make pkg available to import and push current pkg
|
\\ --pkg-begin [name] [path] Make pkg available to import and push current pkg
|
||||||
\\ --pkg-end Pop current pkg
|
\\ --pkg-end Pop current pkg
|
||||||
\\ --main-pkg-path Set the directory of the root package
|
\\ --main-pkg-path Set the directory of the root package
|
||||||
|
@ -290,9 +303,57 @@ const Emit = union(enum) {
|
||||||
no,
|
no,
|
||||||
yes_default_path,
|
yes_default_path,
|
||||||
yes: []const u8,
|
yes: []const u8,
|
||||||
|
|
||||||
|
const Resolved = struct {
|
||||||
|
data: ?Compilation.EmitLoc,
|
||||||
|
dir: ?fs.Dir,
|
||||||
|
|
||||||
|
fn deinit(self: *Resolved) void {
|
||||||
|
if (self.dir) |*dir| {
|
||||||
|
dir.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn resolve(emit: Emit, default_basename: []const u8) !Resolved {
|
||||||
|
var resolved: Resolved = .{ .data = null, .dir = null };
|
||||||
|
errdefer resolved.deinit();
|
||||||
|
|
||||||
|
switch (emit) {
|
||||||
|
.no => {},
|
||||||
|
.yes_default_path => {
|
||||||
|
resolved.data = Compilation.EmitLoc{
|
||||||
|
.directory = .{ .path = null, .handle = fs.cwd() },
|
||||||
|
.basename = default_basename,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
.yes => |full_path| {
|
||||||
|
const basename = fs.path.basename(full_path);
|
||||||
|
if (fs.path.dirname(full_path)) |dirname| {
|
||||||
|
const handle = try fs.cwd().openDir(dirname, .{});
|
||||||
|
resolved = .{
|
||||||
|
.dir = handle,
|
||||||
|
.data = Compilation.EmitLoc{
|
||||||
|
.basename = basename,
|
||||||
|
.directory = .{
|
||||||
|
.path = dirname,
|
||||||
|
.handle = handle,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
resolved.data = Compilation.EmitLoc{
|
||||||
|
.basename = basename,
|
||||||
|
.directory = .{ .path = null, .handle = fs.cwd() },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn buildOutputType(
|
fn buildOutputType(
|
||||||
gpa: *Allocator,
|
gpa: *Allocator,
|
||||||
arena: *Allocator,
|
arena: *Allocator,
|
||||||
all_args: []const []const u8,
|
all_args: []const []const u8,
|
||||||
|
@ -328,7 +389,10 @@ pub fn buildOutputType(
|
||||||
var show_builtin = false;
|
var show_builtin = false;
|
||||||
var emit_bin: Emit = .yes_default_path;
|
var emit_bin: Emit = .yes_default_path;
|
||||||
var emit_asm: Emit = .no;
|
var emit_asm: Emit = .no;
|
||||||
|
var emit_llvm_ir: Emit = .no;
|
||||||
var emit_zir: Emit = .no;
|
var emit_zir: Emit = .no;
|
||||||
|
var emit_docs: Emit = .no;
|
||||||
|
var emit_analysis: Emit = .no;
|
||||||
var target_arch_os_abi: []const u8 = "native";
|
var target_arch_os_abi: []const u8 = "native";
|
||||||
var target_mcpu: ?[]const u8 = null;
|
var target_mcpu: ?[]const u8 = null;
|
||||||
var target_dynamic_linker: ?[]const u8 = null;
|
var target_dynamic_linker: ?[]const u8 = null;
|
||||||
|
@ -667,6 +731,30 @@ pub fn buildOutputType(
|
||||||
emit_h = .{ .yes = arg["-femit-h=".len..] };
|
emit_h = .{ .yes = arg["-femit-h=".len..] };
|
||||||
} else if (mem.eql(u8, arg, "-fno-emit-h")) {
|
} else if (mem.eql(u8, arg, "-fno-emit-h")) {
|
||||||
emit_h = .no;
|
emit_h = .no;
|
||||||
|
} else if (mem.eql(u8, arg, "-femit-asm")) {
|
||||||
|
emit_asm = .yes_default_path;
|
||||||
|
} else if (mem.startsWith(u8, arg, "-femit-asm=")) {
|
||||||
|
emit_asm = .{ .yes = arg["-femit-asm=".len..] };
|
||||||
|
} else if (mem.eql(u8, arg, "-fno-emit-asm")) {
|
||||||
|
emit_asm = .no;
|
||||||
|
} else if (mem.eql(u8, arg, "-femit-llvm-ir")) {
|
||||||
|
emit_llvm_ir = .yes_default_path;
|
||||||
|
} else if (mem.startsWith(u8, arg, "-femit-llvm-ir=")) {
|
||||||
|
emit_llvm_ir = .{ .yes = arg["-femit-llvm-ir=".len..] };
|
||||||
|
} else if (mem.eql(u8, arg, "-fno-emit-llvm-ir")) {
|
||||||
|
emit_llvm_ir = .no;
|
||||||
|
} else if (mem.eql(u8, arg, "-femit-docs")) {
|
||||||
|
emit_docs = .yes_default_path;
|
||||||
|
} else if (mem.startsWith(u8, arg, "-femit-docs=")) {
|
||||||
|
emit_docs = .{ .yes = arg["-femit-docs=".len..] };
|
||||||
|
} else if (mem.eql(u8, arg, "-fno-emit-docs")) {
|
||||||
|
emit_docs = .no;
|
||||||
|
} else if (mem.eql(u8, arg, "-femit-analysis")) {
|
||||||
|
emit_analysis = .yes_default_path;
|
||||||
|
} else if (mem.startsWith(u8, arg, "-femit-analysis=")) {
|
||||||
|
emit_analysis = .{ .yes = arg["-femit-analysis=".len..] };
|
||||||
|
} else if (mem.eql(u8, arg, "-fno-emit-analysis")) {
|
||||||
|
emit_analysis = .no;
|
||||||
} else if (mem.eql(u8, arg, "-dynamic")) {
|
} else if (mem.eql(u8, arg, "-dynamic")) {
|
||||||
link_mode = .Dynamic;
|
link_mode = .Dynamic;
|
||||||
} else if (mem.eql(u8, arg, "-static")) {
|
} else if (mem.eql(u8, arg, "-static")) {
|
||||||
|
@ -1237,35 +1325,24 @@ pub fn buildOutputType(
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var cleanup_emit_h_dir: ?fs.Dir = null;
|
const default_h_basename = try std.fmt.allocPrint(arena, "{}.h", .{root_name});
|
||||||
defer if (cleanup_emit_h_dir) |*dir| dir.close();
|
var emit_h_resolved = try emit_h.resolve(default_h_basename);
|
||||||
|
defer emit_h_resolved.deinit();
|
||||||
|
|
||||||
const emit_h_loc: ?Compilation.EmitLoc = switch (emit_h) {
|
const default_asm_basename = try std.fmt.allocPrint(arena, "{}.s", .{root_name});
|
||||||
.no => null,
|
var emit_asm_resolved = try emit_asm.resolve(default_asm_basename);
|
||||||
.yes_default_path => Compilation.EmitLoc{
|
defer emit_asm_resolved.deinit();
|
||||||
.directory = .{ .path = null, .handle = fs.cwd() },
|
|
||||||
.basename = try std.fmt.allocPrint(arena, "{}.h", .{root_name}),
|
const default_llvm_ir_basename = try std.fmt.allocPrint(arena, "{}.ll", .{root_name});
|
||||||
},
|
var emit_llvm_ir_resolved = try emit_llvm_ir.resolve(default_llvm_ir_basename);
|
||||||
.yes => |full_path| b: {
|
defer emit_llvm_ir_resolved.deinit();
|
||||||
const basename = fs.path.basename(full_path);
|
|
||||||
if (fs.path.dirname(full_path)) |dirname| {
|
const default_analysis_basename = try std.fmt.allocPrint(arena, "{}-analysis.json", .{root_name});
|
||||||
const handle = try fs.cwd().openDir(dirname, .{});
|
var emit_analysis_resolved = try emit_analysis.resolve(default_analysis_basename);
|
||||||
cleanup_emit_h_dir = handle;
|
defer emit_analysis_resolved.deinit();
|
||||||
break :b Compilation.EmitLoc{
|
|
||||||
.basename = basename,
|
var emit_docs_resolved = try emit_docs.resolve("docs");
|
||||||
.directory = .{
|
defer emit_docs_resolved.deinit();
|
||||||
.path = dirname,
|
|
||||||
.handle = handle,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
break :b Compilation.EmitLoc{
|
|
||||||
.basename = basename,
|
|
||||||
.directory = .{ .path = null, .handle = fs.cwd() },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const zir_out_path: ?[]const u8 = switch (emit_zir) {
|
const zir_out_path: ?[]const u8 = switch (emit_zir) {
|
||||||
.no => null,
|
.no => null,
|
||||||
|
@ -1365,6 +1442,12 @@ pub fn buildOutputType(
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (build_options.have_llvm and emit_asm != .no) {
|
||||||
|
// LLVM has no way to set this non-globally.
|
||||||
|
const argv = [_][*:0]const u8{ "zig (LLVM option parsing)", "--x86-asm-syntax=intel" };
|
||||||
|
@import("llvm.zig").ParseCommandLineOptions(argv.len, &argv);
|
||||||
|
}
|
||||||
|
|
||||||
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
||||||
|
|
||||||
const comp = Compilation.create(gpa, .{
|
const comp = Compilation.create(gpa, .{
|
||||||
|
@ -1378,7 +1461,11 @@ pub fn buildOutputType(
|
||||||
.output_mode = output_mode,
|
.output_mode = output_mode,
|
||||||
.root_pkg = root_pkg,
|
.root_pkg = root_pkg,
|
||||||
.emit_bin = emit_bin_loc,
|
.emit_bin = emit_bin_loc,
|
||||||
.emit_h = emit_h_loc,
|
.emit_h = emit_h_resolved.data,
|
||||||
|
.emit_asm = emit_asm_resolved.data,
|
||||||
|
.emit_llvm_ir = emit_llvm_ir_resolved.data,
|
||||||
|
.emit_docs = emit_docs_resolved.data,
|
||||||
|
.emit_analysis = emit_analysis_resolved.data,
|
||||||
.link_mode = link_mode,
|
.link_mode = link_mode,
|
||||||
.dll_export_fns = dll_export_fns,
|
.dll_export_fns = dll_export_fns,
|
||||||
.object_format = object_format,
|
.object_format = object_format,
|
||||||
|
|
|
@ -75,8 +75,18 @@ pub const Pkg = extern struct {
|
||||||
pub const Module = extern struct {
|
pub const Module = extern struct {
|
||||||
root_name_ptr: [*]const u8,
|
root_name_ptr: [*]const u8,
|
||||||
root_name_len: usize,
|
root_name_len: usize,
|
||||||
output_dir_ptr: [*]const u8,
|
emit_o_ptr: [*]const u8,
|
||||||
output_dir_len: usize,
|
emit_o_len: usize,
|
||||||
|
emit_h_ptr: [*]const u8,
|
||||||
|
emit_h_len: usize,
|
||||||
|
emit_asm_ptr: [*]const u8,
|
||||||
|
emit_asm_len: usize,
|
||||||
|
emit_llvm_ir_ptr: [*]const u8,
|
||||||
|
emit_llvm_ir_len: usize,
|
||||||
|
emit_analysis_json_ptr: [*]const u8,
|
||||||
|
emit_analysis_json_len: usize,
|
||||||
|
emit_docs_ptr: [*]const u8,
|
||||||
|
emit_docs_len: usize,
|
||||||
builtin_zig_path_ptr: [*]const u8,
|
builtin_zig_path_ptr: [*]const u8,
|
||||||
builtin_zig_path_len: usize,
|
builtin_zig_path_len: usize,
|
||||||
test_filter_ptr: [*]const u8,
|
test_filter_ptr: [*]const u8,
|
||||||
|
@ -101,11 +111,6 @@ pub const Module = extern struct {
|
||||||
enable_stack_probing: bool,
|
enable_stack_probing: bool,
|
||||||
enable_time_report: bool,
|
enable_time_report: bool,
|
||||||
enable_stack_report: bool,
|
enable_stack_report: bool,
|
||||||
dump_analysis: bool,
|
|
||||||
enable_doc_generation: bool,
|
|
||||||
emit_bin: bool,
|
|
||||||
emit_asm: bool,
|
|
||||||
emit_llvm_ir: bool,
|
|
||||||
test_is_evented: bool,
|
test_is_evented: bool,
|
||||||
verbose_tokenize: bool,
|
verbose_tokenize: bool,
|
||||||
verbose_ast: bool,
|
verbose_ast: bool,
|
||||||
|
|
|
@ -2116,12 +2116,12 @@ struct CodeGen {
|
||||||
Buf llvm_triple_str;
|
Buf llvm_triple_str;
|
||||||
Buf global_asm;
|
Buf global_asm;
|
||||||
Buf o_file_output_path;
|
Buf o_file_output_path;
|
||||||
|
Buf h_file_output_path;
|
||||||
Buf asm_file_output_path;
|
Buf asm_file_output_path;
|
||||||
Buf llvm_ir_file_output_path;
|
Buf llvm_ir_file_output_path;
|
||||||
|
Buf analysis_json_output_path;
|
||||||
|
Buf docs_output_path;
|
||||||
Buf *cache_dir;
|
Buf *cache_dir;
|
||||||
// As an input parameter, mutually exclusive with enable_cache. But it gets
|
|
||||||
// populated in codegen_build_and_link.
|
|
||||||
Buf *output_dir;
|
|
||||||
Buf *c_artifact_dir;
|
Buf *c_artifact_dir;
|
||||||
const char **libc_include_dir_list;
|
const char **libc_include_dir_list;
|
||||||
size_t libc_include_dir_len;
|
size_t libc_include_dir_len;
|
||||||
|
@ -2186,11 +2186,6 @@ struct CodeGen {
|
||||||
bool dll_export_fns;
|
bool dll_export_fns;
|
||||||
bool have_stack_probing;
|
bool have_stack_probing;
|
||||||
bool function_sections;
|
bool function_sections;
|
||||||
bool enable_dump_analysis;
|
|
||||||
bool enable_doc_generation;
|
|
||||||
bool emit_bin;
|
|
||||||
bool emit_asm;
|
|
||||||
bool emit_llvm_ir;
|
|
||||||
bool test_is_evented;
|
bool test_is_evented;
|
||||||
bool valgrind_enabled;
|
bool valgrind_enabled;
|
||||||
|
|
||||||
|
|
|
@ -8243,9 +8243,9 @@ static void zig_llvm_emit_output(CodeGen *g) {
|
||||||
const char *bin_filename = nullptr;
|
const char *bin_filename = nullptr;
|
||||||
const char *llvm_ir_filename = nullptr;
|
const char *llvm_ir_filename = nullptr;
|
||||||
|
|
||||||
if (g->emit_bin) bin_filename = buf_ptr(&g->o_file_output_path);
|
if (buf_len(&g->o_file_output_path) != 0) bin_filename = buf_ptr(&g->o_file_output_path);
|
||||||
if (g->emit_asm) asm_filename = buf_ptr(&g->asm_file_output_path);
|
if (buf_len(&g->asm_file_output_path) != 0) asm_filename = buf_ptr(&g->asm_file_output_path);
|
||||||
if (g->emit_llvm_ir) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path);
|
if (buf_len(&g->llvm_ir_file_output_path) != 0) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path);
|
||||||
|
|
||||||
// Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire
|
// Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire
|
||||||
// pipeline multiple times if this is requested.
|
// pipeline multiple times if this is requested.
|
||||||
|
@ -8858,8 +8858,10 @@ static Error define_builtin_compile_vars(CodeGen *g) {
|
||||||
Buf *contents;
|
Buf *contents;
|
||||||
if (g->builtin_zig_path == nullptr) {
|
if (g->builtin_zig_path == nullptr) {
|
||||||
// Then this is zig0 building stage2. We can make many assumptions about the compilation.
|
// Then this is zig0 building stage2. We can make many assumptions about the compilation.
|
||||||
|
Buf *out_dir = buf_alloc();
|
||||||
|
os_path_split(&g->o_file_output_path, out_dir, nullptr);
|
||||||
g->builtin_zig_path = buf_alloc();
|
g->builtin_zig_path = buf_alloc();
|
||||||
os_path_join(g->output_dir, buf_create_from_str(builtin_zig_basename), g->builtin_zig_path);
|
os_path_join(out_dir, buf_create_from_str(builtin_zig_basename), g->builtin_zig_path);
|
||||||
|
|
||||||
Buf *resolve_paths[] = { g->builtin_zig_path, };
|
Buf *resolve_paths[] = { g->builtin_zig_path, };
|
||||||
*g->builtin_zig_path = os_path_resolve(resolve_paths, 1);
|
*g->builtin_zig_path = os_path_resolve(resolve_paths, 1);
|
||||||
|
@ -8870,7 +8872,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin");
|
g->compile_var_package = new_package(buf_ptr(out_dir), builtin_zig_basename, "builtin");
|
||||||
} else {
|
} else {
|
||||||
Buf *resolve_paths[] = { g->builtin_zig_path, };
|
Buf *resolve_paths[] = { g->builtin_zig_path, };
|
||||||
*g->builtin_zig_path = os_path_resolve(resolve_paths, 1);
|
*g->builtin_zig_path = os_path_resolve(resolve_paths, 1);
|
||||||
|
@ -9232,33 +9234,20 @@ void codegen_add_time_event(CodeGen *g, const char *name) {
|
||||||
g->timing_events.append({seconds, name});
|
g->timing_events.append({seconds, name});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resolve_out_paths(CodeGen *g) {
|
void codegen_build_object(CodeGen *g) {
|
||||||
assert(g->output_dir != nullptr);
|
g->have_err_ret_tracing = detect_err_ret_tracing(g);
|
||||||
assert(g->root_out_name != nullptr);
|
|
||||||
|
|
||||||
if (g->emit_bin) {
|
init(g);
|
||||||
Buf *o_basename = buf_create_from_buf(g->root_out_name);
|
|
||||||
buf_append_str(o_basename, target_o_file_ext(g->zig_target));
|
|
||||||
os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
|
|
||||||
}
|
|
||||||
if (g->emit_asm) {
|
|
||||||
Buf *asm_basename = buf_create_from_buf(g->root_out_name);
|
|
||||||
const char *asm_ext = target_asm_file_ext(g->zig_target);
|
|
||||||
buf_append_str(asm_basename, asm_ext);
|
|
||||||
os_path_join(g->output_dir, asm_basename, &g->asm_file_output_path);
|
|
||||||
}
|
|
||||||
if (g->emit_llvm_ir) {
|
|
||||||
Buf *llvm_ir_basename = buf_create_from_buf(g->root_out_name);
|
|
||||||
const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
|
|
||||||
buf_append_str(llvm_ir_basename, llvm_ir_ext);
|
|
||||||
os_path_join(g->output_dir, llvm_ir_basename, &g->llvm_ir_file_output_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void output_type_information(CodeGen *g) {
|
codegen_add_time_event(g, "Semantic Analysis");
|
||||||
if (g->enable_dump_analysis) {
|
const char *progress_name = "Semantic Analysis";
|
||||||
const char *analysis_json_filename = buf_ptr(buf_sprintf("%s" OS_SEP "%s-analysis.json",
|
codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
|
||||||
buf_ptr(g->output_dir), buf_ptr(g->root_out_name)));
|
progress_name, strlen(progress_name), 0));
|
||||||
|
|
||||||
|
gen_root_source(g);
|
||||||
|
|
||||||
|
if (buf_len(&g->analysis_json_output_path) != 0) {
|
||||||
|
const char *analysis_json_filename = buf_ptr(&g->analysis_json_output_path);
|
||||||
FILE *f = fopen(analysis_json_filename, "wb");
|
FILE *f = fopen(analysis_json_filename, "wb");
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
fprintf(stderr, "Unable to open '%s': %s\n", analysis_json_filename, strerror(errno));
|
fprintf(stderr, "Unable to open '%s': %s\n", analysis_json_filename, strerror(errno));
|
||||||
|
@ -9270,9 +9259,9 @@ static void output_type_information(CodeGen *g) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g->enable_doc_generation) {
|
if (buf_len(&g->docs_output_path) != 0) {
|
||||||
Error err;
|
Error err;
|
||||||
Buf *doc_dir_path = buf_sprintf("%s" OS_SEP "docs", buf_ptr(g->output_dir));
|
Buf *doc_dir_path = &g->docs_output_path;
|
||||||
if ((err = os_make_path(doc_dir_path))) {
|
if ((err = os_make_path(doc_dir_path))) {
|
||||||
fprintf(stderr, "Unable to create directory %s: %s\n", buf_ptr(doc_dir_path), err_str(err));
|
fprintf(stderr, "Unable to create directory %s: %s\n", buf_ptr(doc_dir_path), err_str(err));
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -9308,27 +9297,6 @@ static void output_type_information(CodeGen *g) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void codegen_build_object(CodeGen *g) {
|
|
||||||
assert(g->output_dir != nullptr);
|
|
||||||
|
|
||||||
g->have_err_ret_tracing = detect_err_ret_tracing(g);
|
|
||||||
|
|
||||||
init(g);
|
|
||||||
|
|
||||||
codegen_add_time_event(g, "Semantic Analysis");
|
|
||||||
const char *progress_name = "Semantic Analysis";
|
|
||||||
codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
|
|
||||||
progress_name, strlen(progress_name), 0));
|
|
||||||
|
|
||||||
gen_root_source(g);
|
|
||||||
|
|
||||||
resolve_out_paths(g);
|
|
||||||
|
|
||||||
if (g->enable_dump_analysis || g->enable_doc_generation) {
|
|
||||||
output_type_information(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
codegen_add_time_event(g, "Code Generation");
|
codegen_add_time_event(g, "Code Generation");
|
||||||
{
|
{
|
||||||
|
@ -9379,7 +9347,6 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
|
||||||
bool is_test_build)
|
bool is_test_build)
|
||||||
{
|
{
|
||||||
CodeGen *g = heap::c_allocator.create<CodeGen>();
|
CodeGen *g = heap::c_allocator.create<CodeGen>();
|
||||||
g->emit_bin = true;
|
|
||||||
g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");
|
g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");
|
||||||
|
|
||||||
g->subsystem = TargetSubsystemAuto;
|
g->subsystem = TargetSubsystemAuto;
|
||||||
|
|
|
@ -69,7 +69,13 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {
|
||||||
CodeGen *g = reinterpret_cast<CodeGen *>(stage1);
|
CodeGen *g = reinterpret_cast<CodeGen *>(stage1);
|
||||||
|
|
||||||
g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len);
|
g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len);
|
||||||
g->output_dir = buf_create_from_mem(stage1->output_dir_ptr, stage1->output_dir_len);
|
buf_init_from_mem(&g->o_file_output_path, stage1->emit_o_ptr, stage1->emit_o_len);
|
||||||
|
buf_init_from_mem(&g->h_file_output_path, stage1->emit_h_ptr, stage1->emit_h_len);
|
||||||
|
buf_init_from_mem(&g->asm_file_output_path, stage1->emit_asm_ptr, stage1->emit_asm_len);
|
||||||
|
buf_init_from_mem(&g->llvm_ir_file_output_path, stage1->emit_llvm_ir_ptr, stage1->emit_llvm_ir_len);
|
||||||
|
buf_init_from_mem(&g->analysis_json_output_path, stage1->emit_analysis_json_ptr, stage1->emit_analysis_json_len);
|
||||||
|
buf_init_from_mem(&g->docs_output_path, stage1->emit_docs_ptr, stage1->emit_docs_len);
|
||||||
|
|
||||||
if (stage1->builtin_zig_path_len != 0) {
|
if (stage1->builtin_zig_path_len != 0) {
|
||||||
g->builtin_zig_path = buf_create_from_mem(stage1->builtin_zig_path_ptr, stage1->builtin_zig_path_len);
|
g->builtin_zig_path = buf_create_from_mem(stage1->builtin_zig_path_ptr, stage1->builtin_zig_path_len);
|
||||||
}
|
}
|
||||||
|
@ -94,11 +100,6 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {
|
||||||
|
|
||||||
g->enable_time_report = stage1->enable_time_report;
|
g->enable_time_report = stage1->enable_time_report;
|
||||||
g->enable_stack_report = stage1->enable_stack_report;
|
g->enable_stack_report = stage1->enable_stack_report;
|
||||||
g->enable_dump_analysis = stage1->dump_analysis;
|
|
||||||
g->enable_doc_generation = stage1->enable_doc_generation;
|
|
||||||
g->emit_bin = stage1->emit_bin;
|
|
||||||
g->emit_asm = stage1->emit_asm;
|
|
||||||
g->emit_llvm_ir = stage1->emit_llvm_ir;
|
|
||||||
g->test_is_evented = stage1->test_is_evented;
|
g->test_is_evented = stage1->test_is_evented;
|
||||||
|
|
||||||
g->verbose_tokenize = stage1->verbose_tokenize;
|
g->verbose_tokenize = stage1->verbose_tokenize;
|
||||||
|
|
|
@ -141,8 +141,23 @@ struct ZigStage1 {
|
||||||
const char *root_name_ptr;
|
const char *root_name_ptr;
|
||||||
size_t root_name_len;
|
size_t root_name_len;
|
||||||
|
|
||||||
const char *output_dir_ptr;
|
const char *emit_o_ptr;
|
||||||
size_t output_dir_len;
|
size_t emit_o_len;
|
||||||
|
|
||||||
|
const char *emit_h_ptr;
|
||||||
|
size_t emit_h_len;
|
||||||
|
|
||||||
|
const char *emit_asm_ptr;
|
||||||
|
size_t emit_asm_len;
|
||||||
|
|
||||||
|
const char *emit_llvm_ir_ptr;
|
||||||
|
size_t emit_llvm_ir_len;
|
||||||
|
|
||||||
|
const char *emit_analysis_json_ptr;
|
||||||
|
size_t emit_analysis_json_len;
|
||||||
|
|
||||||
|
const char *emit_docs_ptr;
|
||||||
|
size_t emit_docs_len;
|
||||||
|
|
||||||
const char *builtin_zig_path_ptr;
|
const char *builtin_zig_path_ptr;
|
||||||
size_t builtin_zig_path_len;
|
size_t builtin_zig_path_len;
|
||||||
|
@ -173,11 +188,6 @@ struct ZigStage1 {
|
||||||
bool enable_stack_probing;
|
bool enable_stack_probing;
|
||||||
bool enable_time_report;
|
bool enable_time_report;
|
||||||
bool enable_stack_report;
|
bool enable_stack_report;
|
||||||
bool dump_analysis;
|
|
||||||
bool enable_doc_generation;
|
|
||||||
bool emit_bin;
|
|
||||||
bool emit_asm;
|
|
||||||
bool emit_llvm_ir;
|
|
||||||
bool test_is_evented;
|
bool test_is_evented;
|
||||||
bool verbose_tokenize;
|
bool verbose_tokenize;
|
||||||
bool verbose_ast;
|
bool verbose_ast;
|
||||||
|
|
|
@ -241,7 +241,7 @@ int main(int argc, char **argv) {
|
||||||
Error err;
|
Error err;
|
||||||
|
|
||||||
const char *in_file = nullptr;
|
const char *in_file = nullptr;
|
||||||
const char *output_dir = nullptr;
|
const char *emit_bin_path = nullptr;
|
||||||
bool strip = false;
|
bool strip = false;
|
||||||
const char *out_name = nullptr;
|
const char *out_name = nullptr;
|
||||||
bool verbose_tokenize = false;
|
bool verbose_tokenize = false;
|
||||||
|
@ -324,14 +324,14 @@ int main(int argc, char **argv) {
|
||||||
cur_pkg = cur_pkg->parent;
|
cur_pkg = cur_pkg->parent;
|
||||||
} else if (str_starts_with(arg, "-mcpu=")) {
|
} else if (str_starts_with(arg, "-mcpu=")) {
|
||||||
mcpu = arg + strlen("-mcpu=");
|
mcpu = arg + strlen("-mcpu=");
|
||||||
|
} else if (str_starts_with(arg, "-femit-bin=")) {
|
||||||
|
emit_bin_path = arg + strlen("-femit-bin=");
|
||||||
} else if (i + 1 >= argc) {
|
} else if (i + 1 >= argc) {
|
||||||
fprintf(stderr, "Expected another argument after %s\n", arg);
|
fprintf(stderr, "Expected another argument after %s\n", arg);
|
||||||
return print_error_usage(arg0);
|
return print_error_usage(arg0);
|
||||||
} else {
|
} else {
|
||||||
i += 1;
|
i += 1;
|
||||||
if (strcmp(arg, "--output-dir") == 0) {
|
if (strcmp(arg, "--color") == 0) {
|
||||||
output_dir = argv[i];
|
|
||||||
} else if (strcmp(arg, "--color") == 0) {
|
|
||||||
if (strcmp(argv[i], "auto") == 0) {
|
if (strcmp(argv[i], "auto") == 0) {
|
||||||
color = ErrColorAuto;
|
color = ErrColorAuto;
|
||||||
} else if (strcmp(argv[i], "on") == 0) {
|
} else if (strcmp(argv[i], "on") == 0) {
|
||||||
|
@ -443,15 +443,14 @@ int main(int argc, char **argv) {
|
||||||
stage1->verbose_llvm_ir = verbose_llvm_ir;
|
stage1->verbose_llvm_ir = verbose_llvm_ir;
|
||||||
stage1->verbose_cimport = verbose_cimport;
|
stage1->verbose_cimport = verbose_cimport;
|
||||||
stage1->verbose_llvm_cpu_features = verbose_llvm_cpu_features;
|
stage1->verbose_llvm_cpu_features = verbose_llvm_cpu_features;
|
||||||
stage1->output_dir_ptr = output_dir;
|
stage1->emit_o_ptr = emit_bin_path;
|
||||||
stage1->output_dir_len = strlen(output_dir);
|
stage1->emit_o_len = strlen(emit_bin_path);
|
||||||
stage1->root_pkg = cur_pkg;
|
stage1->root_pkg = cur_pkg;
|
||||||
stage1->err_color = color;
|
stage1->err_color = color;
|
||||||
stage1->link_libc = link_libc;
|
stage1->link_libc = link_libc;
|
||||||
stage1->link_libcpp = link_libcpp;
|
stage1->link_libcpp = link_libcpp;
|
||||||
stage1->subsystem = subsystem;
|
stage1->subsystem = subsystem;
|
||||||
stage1->pic = true;
|
stage1->pic = true;
|
||||||
stage1->emit_bin = true;
|
|
||||||
|
|
||||||
zig_stage1_build_object(stage1);
|
zig_stage1_build_object(stage1);
|
||||||
|
|
||||||
|
|
19
test/cli.zig
19
test/cli.zig
|
@ -118,17 +118,20 @@ fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void {
|
||||||
\\}
|
\\}
|
||||||
);
|
);
|
||||||
|
|
||||||
const args = [_][]const u8{
|
var args = std.ArrayList([]const u8).init(a);
|
||||||
|
try args.appendSlice(&[_][]const u8{
|
||||||
zig_exe, "build-obj",
|
zig_exe, "build-obj",
|
||||||
"--cache-dir", dir_path,
|
"--cache-dir", dir_path,
|
||||||
"--name", "example",
|
"--name", "example",
|
||||||
"--output-dir", dir_path,
|
"-fno-emit-bin", "-fno-emit-h",
|
||||||
"--emit", "asm",
|
"--strip", "-OReleaseFast",
|
||||||
"-mllvm", "--x86-asm-syntax=intel",
|
example_zig_path,
|
||||||
"--strip", "--release-fast",
|
});
|
||||||
example_zig_path, "--disable-gen-h",
|
|
||||||
};
|
const emit_asm_arg = try std.fmt.allocPrint(a, "-femit-asm={s}", .{example_s_path});
|
||||||
_ = try exec(dir_path, &args);
|
try args.append(emit_asm_arg);
|
||||||
|
|
||||||
|
_ = try exec(dir_path, args.items);
|
||||||
|
|
||||||
const out_asm = try std.fs.cwd().readFileAlloc(a, example_s_path, std.math.maxInt(usize));
|
const out_asm = try std.fs.cwd().readFileAlloc(a, example_s_path, std.math.maxInt(usize));
|
||||||
testing.expect(std.mem.indexOf(u8, out_asm, "square:") != null);
|
testing.expect(std.mem.indexOf(u8, out_asm, "square:") != null);
|
||||||
|
|
Loading…
Reference in New Issue