diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-09-26 12:42:07 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-09-26 12:42:07 -0700 |
| commit | 26f2f9bf1c774caf246317b3fc032449e982a150 (patch) | |
| tree | 43bc4d4b19cea9a245d87f105841d075ab75f5ab /src/link.zig | |
| parent | 9b83112a1f6af758a1a995ea8838a2319d2fbc1e (diff) | |
| download | zig-26f2f9bf1c774caf246317b3fc032449e982a150.tar.gz zig-26f2f9bf1c774caf246317b3fc032449e982a150.zip | |
stage2: implement -fno-emit-bin
we are now passing the cli tests
Diffstat (limited to 'src/link.zig')
| -rw-r--r-- | src/link.zig | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/src/link.zig b/src/link.zig index 6e8fd3fdc7..6cf1d775e4 100644 --- a/src/link.zig +++ b/src/link.zig @@ -16,11 +16,17 @@ const LibCInstallation = @import("libc_installation.zig").LibCInstallation; pub const producer_string = if (std.builtin.is_test) "zig test" else "zig " ++ build_options.version; -pub const Options = struct { +pub const Emit = struct { /// Where the output will go. directory: Compilation.Directory, /// Path to the output file, relative to `directory`. sub_path: []const u8, +}; + +pub const Options = struct { + /// This is `null` when -fno-emit-bin is used. When `openPath` or `flush` is called, + /// it will have already been null-checked. + emit: ?Emit, target: std.Target, output_mode: std.builtin.OutputMode, link_mode: std.builtin.LinkMode, @@ -141,7 +147,7 @@ pub const File = struct { /// and does not cause Illegal Behavior. This operation is not atomic. pub fn openPath(allocator: *Allocator, options: Options) !*File { const use_stage1 = build_options.is_stage1 and options.use_llvm; - if (use_stage1) { + if (use_stage1 or options.emit == null) { return switch (options.object_format) { .coff, .pe => &(try Coff.createEmpty(allocator, options)).base, .elf => &(try Elf.createEmpty(allocator, options)).base, @@ -152,6 +158,7 @@ pub const File = struct { .raw => return error.RawObjectFormatUnimplemented, }; } + const emit = options.emit.?; const use_lld = build_options.have_llvm and options.use_lld; // comptime known false when !have_llvm const sub_path = if (use_lld) blk: { if (options.module == null) { @@ -167,8 +174,8 @@ pub const File = struct { }; } // Open a temporary object file, not the final output file because we want to link with LLD. - break :blk try std.fmt.allocPrint(allocator, "{}{}", .{ options.sub_path, options.target.oFileExt() }); - } else options.sub_path; + break :blk try std.fmt.allocPrint(allocator, "{}{}", .{ emit.sub_path, options.target.oFileExt() }); + } else emit.sub_path; errdefer if (use_lld) allocator.free(sub_path); const file: *File = switch (options.object_format) { @@ -199,7 +206,8 @@ pub const File = struct { switch (base.tag) { .coff, .elf, .macho => { if (base.file != null) return; - base.file = try base.options.directory.handle.createFile(base.options.sub_path, .{ + const emit = base.options.emit orelse return; + base.file = try emit.directory.handle.createFile(emit.sub_path, .{ .truncate = false, .read = true, .mode = determineMode(base.options), @@ -305,14 +313,14 @@ pub const File = struct { /// Commit pending changes and write headers. Takes into account final output mode /// and `use_lld`, not only `effectiveOutputMode`. pub fn flush(base: *File, comp: *Compilation) !void { + const emit = base.options.emit orelse return; // -fno-emit-bin + if (comp.clang_preprocessor_mode == .yes) { // TODO: avoid extra link step when it's just 1 object file (the `zig cc -c` case) // Until then, we do `lld -r -o output.o input.o` even though the output is the same // as the input. For the preprocessing case (`zig cc -E -o foo`) we copy the file // to the final location. - const full_out_path = try base.options.directory.join(comp.gpa, &[_][]const u8{ - base.options.sub_path, - }); + const full_out_path = try emit.directory.join(comp.gpa, &[_][]const u8{emit.sub_path}); defer comp.gpa.free(full_out_path); assert(comp.c_object_table.count() == 1); const the_entry = comp.c_object_table.items()[0]; @@ -402,7 +410,7 @@ pub const File = struct { defer arena_allocator.deinit(); const arena = &arena_allocator.allocator; - const directory = base.options.directory; // Just an alias to make it shorter to type. + const directory = base.options.emit.?.directory; // Just an alias to make it shorter to type. // If there is no Zig code to compile, then we should skip flushing the output file because it // will not be part of the linker line anyway. @@ -471,10 +479,7 @@ pub const File = struct { object_files.appendAssumeCapacity(try arena.dupeZ(u8, p)); } - const full_out_path = if (directory.path) |dir_path| - try std.fs.path.join(arena, &[_][]const u8{ dir_path, base.options.sub_path }) - else - base.options.sub_path; + const full_out_path = try directory.join(arena, &[_][]const u8{base.options.emit.?.sub_path}); const full_out_path_z = try arena.dupeZ(u8, full_out_path); if (base.options.verbose_link) { |
