aboutsummaryrefslogtreecommitdiff
path: root/src/link.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-10-10 00:41:58 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-10-10 14:21:52 -0700
commit14c8e270bb47c4e10ee3392661d4c62ab5c2f89d (patch)
treec74fe79e74d3fc6bff7dd61f372153906e29e040 /src/link.zig
parent58349b2c8ebc57718bbfbf939c30b586d5c85466 (diff)
downloadzig-14c8e270bb47c4e10ee3392661d4c62ab5c2f89d.tar.gz
zig-14c8e270bb47c4e10ee3392661d4c62ab5c2f89d.zip
link: fix false positive crtbegin/crtend detection
Embrace the Path abstraction, doing more operations based on directory handles rather than absolute file paths. Most of the diff noise here comes from this one. Fix sorting of crtbegin/crtend atoms. Previously it would look at all path components for those strings. Make the C runtime path detection partially a pure function, and move some logic to glibc.zig where it belongs.
Diffstat (limited to 'src/link.zig')
-rw-r--r--src/link.zig27
1 files changed, 12 insertions, 15 deletions
diff --git a/src/link.zig b/src/link.zig
index 879fca9a84..64115ab3ee 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -11,7 +11,7 @@ const wasi_libc = @import("wasi_libc.zig");
const Air = @import("Air.zig");
const Allocator = std.mem.Allocator;
const Cache = std.Build.Cache;
-const Path = Cache.Path;
+const Path = std.Build.Cache.Path;
const Compilation = @import("Compilation.zig");
const LibCInstallation = std.zig.LibCInstallation;
const Liveness = @import("Liveness.zig");
@@ -34,7 +34,7 @@ pub const SystemLib = struct {
/// 1. Windows DLLs that zig ships such as advapi32.
/// 2. extern "foo" fn declarations where we find out about libraries too late
/// TODO: make this non-optional and resolve those two cases somehow.
- path: ?[]const u8,
+ path: ?Path,
};
pub fn hashAddSystemLibs(
@@ -46,7 +46,7 @@ pub fn hashAddSystemLibs(
for (hm.values()) |value| {
man.hash.add(value.needed);
man.hash.add(value.weak);
- if (value.path) |p| _ = try man.addFile(p, null);
+ if (value.path) |p| _ = try man.addFilePath(p, null);
}
}
@@ -551,7 +551,7 @@ pub const File = struct {
LLDCrashed,
LLDReportedFailure,
LLD_LinkingIsTODO_ForSpirV,
- LibCInstallationMissingCRTDir,
+ LibCInstallationMissingCrtDir,
LibCInstallationNotAvailable,
LinkingWithoutZigSourceUnimplemented,
MalformedArchive,
@@ -606,18 +606,15 @@ pub const File = struct {
const comp = base.comp;
if (comp.clang_preprocessor_mode == .yes or comp.clang_preprocessor_mode == .pch) {
dev.check(.clang_command);
- const gpa = comp.gpa;
const emit = base.emit;
// 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. See also the corresponding TODO in Coff linking.
- const full_out_path = try emit.root_dir.join(gpa, &[_][]const u8{emit.sub_path});
- defer gpa.free(full_out_path);
assert(comp.c_object_table.count() == 1);
const the_key = comp.c_object_table.keys()[0];
const cached_pp_file_path = the_key.status.success.object_path;
- try fs.cwd().copyFile(cached_pp_file_path, fs.cwd(), full_out_path, .{});
+ try cached_pp_file_path.root_dir.handle.copyFile(cached_pp_file_path.sub_path, emit.root_dir.handle, emit.sub_path, .{});
return;
}
@@ -781,7 +778,7 @@ pub const File = struct {
log.debug("zcu_obj_path={s}", .{if (zcu_obj_path) |s| s else "(null)"});
- const compiler_rt_path: ?[]const u8 = if (comp.include_compiler_rt)
+ const compiler_rt_path: ?Path = if (comp.include_compiler_rt)
comp.compiler_rt_obj.?.full_object_path
else
null;
@@ -806,18 +803,18 @@ pub const File = struct {
base.releaseLock();
for (objects) |obj| {
- _ = try man.addFile(obj.path, null);
+ _ = try man.addFilePath(obj.path, null);
man.hash.add(obj.must_link);
man.hash.add(obj.loption);
}
for (comp.c_object_table.keys()) |key| {
- _ = try man.addFile(key.status.success.object_path, null);
+ _ = try man.addFilePath(key.status.success.object_path, null);
}
for (comp.win32_resource_table.keys()) |key| {
_ = try man.addFile(key.status.success.res_path, null);
}
try man.addOptionalFile(zcu_obj_path);
- try man.addOptionalFile(compiler_rt_path);
+ try man.addOptionalFilePath(compiler_rt_path);
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
_ = try man.hit();
@@ -851,10 +848,10 @@ pub const File = struct {
defer object_files.deinit();
for (objects) |obj| {
- object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj.path));
+ object_files.appendAssumeCapacity(try obj.path.toStringZ(arena));
}
for (comp.c_object_table.keys()) |key| {
- object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.object_path));
+ object_files.appendAssumeCapacity(try key.status.success.object_path.toStringZ(arena));
}
for (comp.win32_resource_table.keys()) |key| {
object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.res_path));
@@ -863,7 +860,7 @@ pub const File = struct {
object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));
}
if (compiler_rt_path) |p| {
- object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));
+ object_files.appendAssumeCapacity(try p.toStringZ(arena));
}
if (comp.verbose_link) {