aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Coff.zig21
-rw-r--r--src/link/Elf.zig26
-rw-r--r--src/link/MachO.zig23
-rw-r--r--src/link/Wasm.zig22
4 files changed, 62 insertions, 30 deletions
diff --git a/src/link/Coff.zig b/src/link/Coff.zig
index e6788120a0..ec06c28b44 100644
--- a/src/link/Coff.zig
+++ b/src/link/Coff.zig
@@ -880,6 +880,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
const arena = arena_allocator.allocator();
const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
+ const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
// 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.
@@ -891,15 +892,22 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
.target = self.base.options.target,
.output_mode = .Obj,
});
- const o_directory = module.zig_cache_artifact_directory;
- const full_obj_path = try o_directory.join(arena, &[_][]const u8{obj_basename});
- break :blk full_obj_path;
+ switch (self.base.options.cache_mode) {
+ .incremental => break :blk try module.zig_cache_artifact_directory.join(
+ arena,
+ &[_][]const u8{obj_basename},
+ ),
+ .whole => break :blk try fs.path.join(arena, &.{
+ fs.path.dirname(full_out_path).?, obj_basename,
+ }),
+ }
}
try self.flushModule(comp);
- const obj_basename = self.base.intermediary_basename.?;
- const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
- break :blk full_obj_path;
+
+ break :blk try fs.path.join(arena, &.{
+ fs.path.dirname(full_out_path).?, self.base.intermediary_basename.?,
+ });
} else null;
const is_lib = self.base.options.output_mode == .Lib;
@@ -978,7 +986,6 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
};
}
- const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
if (self.base.options.output_mode == .Obj) {
// LLD's COFF driver does not support the equivalent of `-r` so we do a simple file copy
// here. TODO: think carefully about how we can avoid this redundant operation when doing
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index 5f3771a3cb..105b012fbf 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -297,6 +297,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
else => return error.UnsupportedELFArchitecture,
};
const self = try gpa.create(Elf);
+ errdefer gpa.destroy(self);
self.* = .{
.base = .{
.tag = .elf,
@@ -306,6 +307,9 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
},
.ptr_width = ptr_width,
};
+ // TODO get rid of the sub_path parameter to LlvmObject.create
+ // and create the llvm_object here. Also openPath needs to
+ // not override this field or there will be a memory leak.
return self;
}
@@ -1298,6 +1302,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
const arena = arena_allocator.allocator();
const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
+ const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
// 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.
@@ -1309,15 +1314,22 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
.target = self.base.options.target,
.output_mode = .Obj,
});
- const o_directory = module.zig_cache_artifact_directory;
- const full_obj_path = try o_directory.join(arena, &[_][]const u8{obj_basename});
- break :blk full_obj_path;
+ switch (self.base.options.cache_mode) {
+ .incremental => break :blk try module.zig_cache_artifact_directory.join(
+ arena,
+ &[_][]const u8{obj_basename},
+ ),
+ .whole => break :blk try fs.path.join(arena, &.{
+ fs.path.dirname(full_out_path).?, obj_basename,
+ }),
+ }
}
try self.flushModule(comp);
- const obj_basename = self.base.intermediary_basename.?;
- const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
- break :blk full_obj_path;
+
+ break :blk try fs.path.join(arena, &.{
+ fs.path.dirname(full_out_path).?, self.base.intermediary_basename.?,
+ });
} else null;
const is_obj = self.base.options.output_mode == .Obj;
@@ -1434,8 +1446,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
};
}
- const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
-
// Due to a deficiency in LLD, we need to special-case BPF to a simple file copy when generating
// relocatables. Normally, we would expect `lld -r` to work. However, because LLD wants to resolve
// BPF relocations which it shouldn't, it fails before even generating the relocatable.
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index f970ffb5f2..ed720080af 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -423,6 +423,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
const arena = arena_allocator.allocator();
const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
+ const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
// 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.
@@ -433,15 +434,24 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
.target = self.base.options.target,
.output_mode = .Obj,
});
- const o_directory = module.zig_cache_artifact_directory;
- const full_obj_path = try o_directory.join(arena, &[_][]const u8{obj_basename});
- break :blk full_obj_path;
+ switch (self.base.options.cache_mode) {
+ .incremental => break :blk try module.zig_cache_artifact_directory.join(
+ arena,
+ &[_][]const u8{obj_basename},
+ ),
+ .whole => break :blk try fs.path.join(arena, &.{
+ fs.path.dirname(full_out_path).?, obj_basename,
+ }),
+ }
}
const obj_basename = self.base.intermediary_basename orelse break :blk null;
+
try self.flushObject(comp);
- const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
- break :blk full_obj_path;
+
+ break :blk try fs.path.join(arena, &.{
+ fs.path.dirname(full_out_path).?, obj_basename,
+ });
} else null;
const is_lib = self.base.options.output_mode == .Lib;
@@ -534,7 +544,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
else => |e| return e,
};
}
- const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
if (self.base.options.output_mode == .Obj) {
// LLD's MachO driver does not support the equivalent of `-r` so we do a simple file copy
@@ -1269,7 +1278,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const
for (files) |file_name| {
const full_path = full_path: {
var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
- const path = try std.fs.realpath(file_name, &buffer);
+ const path = try fs.realpath(file_name, &buffer);
break :full_path try self.base.allocator.dupe(u8, path);
};
defer self.base.allocator.free(full_path);
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index 5f8f48d1b1..220ab2f53c 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -1050,6 +1050,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
const arena = arena_allocator.allocator();
const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
+ const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
// 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.
@@ -1061,15 +1062,22 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
.target = self.base.options.target,
.output_mode = .Obj,
});
- const o_directory = module.zig_cache_artifact_directory;
- const full_obj_path = try o_directory.join(arena, &[_][]const u8{obj_basename});
- break :blk full_obj_path;
+ switch (self.base.options.cache_mode) {
+ .incremental => break :blk try module.zig_cache_artifact_directory.join(
+ arena,
+ &[_][]const u8{obj_basename},
+ ),
+ .whole => break :blk try fs.path.join(arena, &.{
+ fs.path.dirname(full_out_path).?, obj_basename,
+ }),
+ }
}
try self.flushModule(comp);
- const obj_basename = self.base.intermediary_basename.?;
- const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
- break :blk full_obj_path;
+
+ break :blk try fs.path.join(arena, &.{
+ fs.path.dirname(full_out_path).?, self.base.intermediary_basename.?,
+ });
} else null;
const is_obj = self.base.options.output_mode == .Obj;
@@ -1143,8 +1151,6 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
};
}
- const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
-
if (self.base.options.output_mode == .Obj) {
// LLD's WASM driver does not support the equivalent of `-r` so we do a simple file copy
// here. TODO: think carefully about how we can avoid this redundant operation when doing