aboutsummaryrefslogtreecommitdiff
path: root/src/link.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-09-25 20:52:02 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-09-25 20:52:02 -0700
commita337046832b936d912b6902e331cb58bdc513a2d (patch)
tree2475300223038682fad3477d5e59473b78992a5b /src/link.zig
parentaded86e6909e01dfb45b35204e9dedf6aabb3d58 (diff)
downloadzig-a337046832b936d912b6902e331cb58bdc513a2d.tar.gz
zig-a337046832b936d912b6902e331cb58bdc513a2d.zip
stage2: properly handle zig cc used as a preprocessor
This cleans up how the CLI parses and handles -E, -S, and -c. Compilation explicitly acknowledges when it is being used to do C preprocessing. -S is properly translated to -fno-emit-bin -femit-asm but Compilation does not yet handle -femit-asm. There is not yet a mechanism for skipping the linking step when there is only a single object file, and so to make this work we have to do a file copy in link.flush() to copy the file from zig-cache into the output directory.
Diffstat (limited to 'src/link.zig')
-rw-r--r--src/link.zig21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/link.zig b/src/link.zig
index 4c485063bd..6e8fd3fdc7 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -1,16 +1,18 @@
const std = @import("std");
const mem = std.mem;
const Allocator = std.mem.Allocator;
+const fs = std.fs;
+const log = std.log.scoped(.link);
+const assert = std.debug.assert;
+
const Compilation = @import("Compilation.zig");
const Module = @import("Module.zig");
-const fs = std.fs;
const trace = @import("tracy.zig").trace;
const Package = @import("Package.zig");
const Type = @import("type.zig").Type;
const Cache = @import("Cache.zig");
const build_options = @import("build_options");
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
-const log = std.log.scoped(.link);
pub const producer_string = if (std.builtin.is_test) "zig test" else "zig " ++ build_options.version;
@@ -303,6 +305,21 @@ 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 {
+ 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,
+ });
+ defer comp.gpa.free(full_out_path);
+ assert(comp.c_object_table.count() == 1);
+ const the_entry = comp.c_object_table.items()[0];
+ const cached_pp_file_path = the_entry.key.status.success.object_path;
+ try fs.cwd().copyFile(cached_pp_file_path, fs.cwd(), full_out_path, .{});
+ return;
+ }
const use_lld = build_options.have_llvm and base.options.use_lld;
if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static and
!base.options.target.isWasm())