aboutsummaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-07-22 14:44:06 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-07-22 19:51:32 -0700
commita5fb28070f37c2cad92ac8805bcc704e872fc538 (patch)
tree05e8432688cd83fcb4989a13087c01c74df172c5 /src/main.zig
parent36295d712fbd561c3de9b3eb46e776d63e646e9a (diff)
downloadzig-a5fb28070f37c2cad92ac8805bcc704e872fc538.tar.gz
zig-a5fb28070f37c2cad92ac8805bcc704e872fc538.zip
add -femit-llvm-bc CLI option and implement it
* Added doc comments for `std.Target.ObjectFormat` enum * `std.Target.oFileExt` is removed because it is incorrect for Plan-9 targets. Instead, use `std.Target.ObjectFormat.fileExt` and pass a CPU architecture. * Added `Compilation.Directory.joinZ` for when a null byte is desired. * Improvements to `Compilation.create` logic for computing `use_llvm` and reporting errors in contradictory flags. `-femit-llvm-ir` and `-femit-llvm-bc` will now imply `-fLLVM`. * Fix compilation when passing `.bc` files on the command line. * Improvements to the stage2 LLVM backend: - cleaned up error messages and error reporting. Properly bubble up some errors rather than dumping to stderr; others turn into panics. - properly call ZigLLVMCreateTargetMachine and ZigLLVMTargetMachineEmitToFile and implement calculation of the respective parameters (cpu features, code model, abi name, lto, tsan, etc). - LLVM module verification only runs in debug builds of the compiler - use LLVMDumpModule rather than printToString because in the case that we incorrectly pass a null pointer to LLVM it may crash during dumping the module and having it partially printed is helpful in this case. - support -femit-asm, -fno-emit-bin, -femit-llvm-ir, -femit-llvm-bc - Support LLVM backend when used with Mach-O and WASM linkers.
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig38
1 files changed, 31 insertions, 7 deletions
diff --git a/src/main.zig b/src/main.zig
index 9a51eba5f6..db7fc17df0 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -301,6 +301,8 @@ const usage_build_generic =
\\ -fno-emit-asm (default) Do not output .s (assembly code)
\\ -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-llvm-bc[=path] Produce a LLVM module as a .bc file (requires LLVM extensions)
+ \\ -fno-emit-llvm-bc (default) Do not produce a LLVM module as a .bc file
\\ -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
@@ -359,7 +361,7 @@ const usage_build_generic =
\\ --single-threaded Code assumes it is only used single-threaded
\\ -ofmt=[mode] Override target object format
\\ elf Executable and Linking Format
- \\ c Compile to C source code
+ \\ c C source code
\\ wasm WebAssembly
\\ coff Common Object File Format (Windows)
\\ macho macOS relocatables
@@ -551,6 +553,7 @@ fn buildOutputType(
var emit_bin: EmitBin = .yes_default_path;
var emit_asm: Emit = .no;
var emit_llvm_ir: Emit = .no;
+ var emit_llvm_bc: Emit = .no;
var emit_docs: Emit = .no;
var emit_analysis: Emit = .no;
var target_arch_os_abi: []const u8 = "native";
@@ -1010,6 +1013,12 @@ fn buildOutputType(
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-llvm-bc")) {
+ emit_llvm_bc = .yes_default_path;
+ } else if (mem.startsWith(u8, arg, "-femit-llvm-bc=")) {
+ emit_llvm_bc = .{ .yes = arg["-femit-llvm-bc=".len..] };
+ } else if (mem.eql(u8, arg, "-fno-emit-llvm-bc")) {
+ emit_llvm_bc = .no;
} else if (mem.eql(u8, arg, "-femit-docs")) {
emit_docs = .yes_default_path;
} else if (mem.startsWith(u8, arg, "-femit-docs=")) {
@@ -1815,10 +1824,10 @@ fn buildOutputType(
var emit_h_resolved = emit_h.resolve(default_h_basename) catch |err| {
switch (emit_h) {
.yes => {
- fatal("unable to open directory from argument 'femit-h', '{s}': {s}", .{ emit_h.yes, @errorName(err) });
+ fatal("unable to open directory from argument '-femit-h', '{s}': {s}", .{ emit_h.yes, @errorName(err) });
},
.yes_default_path => {
- fatal("unable to open directory from arguments 'name' or 'soname', '{s}': {s}", .{ default_h_basename, @errorName(err) });
+ fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{ default_h_basename, @errorName(err) });
},
.no => unreachable,
}
@@ -1829,10 +1838,10 @@ fn buildOutputType(
var emit_asm_resolved = emit_asm.resolve(default_asm_basename) catch |err| {
switch (emit_asm) {
.yes => {
- fatal("unable to open directory from argument 'femit-asm', '{s}': {s}", .{ emit_asm.yes, @errorName(err) });
+ fatal("unable to open directory from argument '-femit-asm', '{s}': {s}", .{ emit_asm.yes, @errorName(err) });
},
.yes_default_path => {
- fatal("unable to open directory from arguments 'name' or 'soname', '{s}': {s}", .{ default_asm_basename, @errorName(err) });
+ fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{ default_asm_basename, @errorName(err) });
},
.no => unreachable,
}
@@ -1843,16 +1852,30 @@ fn buildOutputType(
var emit_llvm_ir_resolved = emit_llvm_ir.resolve(default_llvm_ir_basename) catch |err| {
switch (emit_llvm_ir) {
.yes => {
- fatal("unable to open directory from argument 'femit-llvm-ir', '{s}': {s}", .{ emit_llvm_ir.yes, @errorName(err) });
+ fatal("unable to open directory from argument '-femit-llvm-ir', '{s}': {s}", .{ emit_llvm_ir.yes, @errorName(err) });
},
.yes_default_path => {
- fatal("unable to open directory from arguments 'name' or 'soname', '{s}': {s}", .{ default_llvm_ir_basename, @errorName(err) });
+ fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{ default_llvm_ir_basename, @errorName(err) });
},
.no => unreachable,
}
};
defer emit_llvm_ir_resolved.deinit();
+ const default_llvm_bc_basename = try std.fmt.allocPrint(arena, "{s}.bc", .{root_name});
+ var emit_llvm_bc_resolved = emit_llvm_bc.resolve(default_llvm_bc_basename) catch |err| {
+ switch (emit_llvm_bc) {
+ .yes => {
+ fatal("unable to open directory from argument '-femit-llvm-bc', '{s}': {s}", .{ emit_llvm_bc.yes, @errorName(err) });
+ },
+ .yes_default_path => {
+ fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{ default_llvm_bc_basename, @errorName(err) });
+ },
+ .no => unreachable,
+ }
+ };
+ defer emit_llvm_bc_resolved.deinit();
+
const default_analysis_basename = try std.fmt.allocPrint(arena, "{s}-analysis.json", .{root_name});
var emit_analysis_resolved = emit_analysis.resolve(default_analysis_basename) catch |err| {
switch (emit_analysis) {
@@ -1988,6 +2011,7 @@ fn buildOutputType(
.emit_h = emit_h_resolved.data,
.emit_asm = emit_asm_resolved.data,
.emit_llvm_ir = emit_llvm_ir_resolved.data,
+ .emit_llvm_bc = emit_llvm_bc_resolved.data,
.emit_docs = emit_docs_resolved.data,
.emit_analysis = emit_analysis_resolved.data,
.link_mode = link_mode,