mirror of
https://github.com/ziglang/zig.git
synced 2024-11-14 16:13:24 +00:00
also find static libc files on the host
and don't look for glibc files on windows
This commit is contained in:
parent
2d8ea78249
commit
5d75d8f6fc
@ -1780,32 +1780,14 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
||||
const paths = try lci.resolveCrtPaths(arena, basenames, target);
|
||||
|
||||
const fields = @typeInfo(@TypeOf(paths)).@"struct".fields;
|
||||
try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, fields.len);
|
||||
try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, fields.len + 1);
|
||||
inline for (fields) |field| {
|
||||
if (@field(paths, field.name)) |path| {
|
||||
comp.link_task_queue.shared.appendAssumeCapacity(.{ .load_object = path });
|
||||
}
|
||||
}
|
||||
|
||||
const flags = target_util.libcFullLinkFlags(target);
|
||||
try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, flags.len);
|
||||
for (flags) |flag| {
|
||||
assert(mem.startsWith(u8, flag, "-l"));
|
||||
const lib_name = flag["-l".len..];
|
||||
const suffix = switch (comp.config.link_mode) {
|
||||
.static => target.staticLibSuffix(),
|
||||
.dynamic => target.dynamicLibSuffix(),
|
||||
};
|
||||
const sep = std.fs.path.sep_str;
|
||||
const lib_path = try std.fmt.allocPrint(arena, "{s}" ++ sep ++ "lib{s}{s}", .{
|
||||
lci.crt_dir.?, lib_name, suffix,
|
||||
});
|
||||
const resolved_path = Path.initCwd(lib_path);
|
||||
comp.link_task_queue.shared.appendAssumeCapacity(switch (comp.config.link_mode) {
|
||||
.static => .{ .load_archive = resolved_path },
|
||||
.dynamic => .{ .load_dso = resolved_path },
|
||||
});
|
||||
}
|
||||
// Loads the libraries provided by `target_util.libcFullLinkFlags(target)`.
|
||||
comp.link_task_queue.shared.appendAssumeCapacity(.load_host_libc);
|
||||
} else if (target.isMusl() and !target.isWasm()) {
|
||||
if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
|
||||
|
||||
|
64
src/link.zig
64
src/link.zig
@ -25,6 +25,7 @@ const lldMain = @import("main.zig").lldMain;
|
||||
const Package = @import("Package.zig");
|
||||
const dev = @import("dev.zig");
|
||||
const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue;
|
||||
const target_util = @import("target.zig");
|
||||
|
||||
pub const LdScript = @import("link/LdScript.zig");
|
||||
|
||||
@ -1364,6 +1365,10 @@ pub const File = struct {
|
||||
/// Loads the objects, shared objects, and archives that are already
|
||||
/// known from the command line.
|
||||
load_explicitly_provided,
|
||||
/// Loads the shared objects and archives by resolving
|
||||
/// `target_util.libcFullLinkFlags()` against the host libc
|
||||
/// installation.
|
||||
load_host_libc,
|
||||
/// Tells the linker to load an object file by path.
|
||||
load_object: Path,
|
||||
/// Tells the linker to load a static library by path.
|
||||
@ -1393,6 +1398,45 @@ pub const File = struct {
|
||||
};
|
||||
}
|
||||
},
|
||||
.load_host_libc => {
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
const flags = target_util.libcFullLinkFlags(target);
|
||||
const crt_dir = comp.libc_installation.?.crt_dir.?;
|
||||
const sep = std.fs.path.sep_str;
|
||||
const diags = &comp.link_diags;
|
||||
for (flags) |flag| {
|
||||
assert(mem.startsWith(u8, flag, "-l"));
|
||||
const lib_name = flag["-l".len..];
|
||||
switch (comp.config.link_mode) {
|
||||
.dynamic => d: {
|
||||
const path = Path.initCwd(
|
||||
std.fmt.allocPrint(comp.arena, "{s}" ++ sep ++ "{s}{s}{s}", .{
|
||||
crt_dir, target.libPrefix(), lib_name, target.dynamicLibSuffix(),
|
||||
}) catch return diags.setAllocFailure(),
|
||||
);
|
||||
base.openLoadDso(path, .{
|
||||
.preferred_mode = .dynamic,
|
||||
.search_strategy = .paths_first,
|
||||
}) catch |err| switch (err) {
|
||||
error.FileNotFound => break :d, // also try static
|
||||
error.LinkFailure => return, // error reported via diags
|
||||
else => |e| diags.addParseError(path, "failed to parse shared library: {s}", .{@errorName(e)}),
|
||||
};
|
||||
continue;
|
||||
},
|
||||
.static => {},
|
||||
}
|
||||
const path = Path.initCwd(
|
||||
std.fmt.allocPrint(comp.arena, "{s}" ++ sep ++ "{s}{s}{s}", .{
|
||||
crt_dir, target.libPrefix(), lib_name, target.staticLibSuffix(),
|
||||
}) catch return diags.setAllocFailure(),
|
||||
);
|
||||
base.openLoadArchive(path) catch |err| switch (err) {
|
||||
error.LinkFailure => return, // error reported via diags
|
||||
else => |e| diags.addParseError(path, "failed to parse archive: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
},
|
||||
.load_object => |path| {
|
||||
base.openLoadObject(path) catch |err| switch (err) {
|
||||
error.LinkFailure => return, // error reported via link_diags
|
||||
@ -1873,7 +1917,7 @@ pub fn resolveInputs(
|
||||
}
|
||||
}
|
||||
|
||||
const AccessLibPathResult = enum { ok, no_match };
|
||||
const ResolveLibInputResult = enum { ok, no_match };
|
||||
const fatal = std.process.fatal;
|
||||
|
||||
fn resolveLibInput(
|
||||
@ -1892,7 +1936,7 @@ fn resolveLibInput(
|
||||
target: std.Target,
|
||||
link_mode: std.builtin.LinkMode,
|
||||
color: std.zig.Color,
|
||||
) Allocator.Error!AccessLibPathResult {
|
||||
) Allocator.Error!ResolveLibInputResult {
|
||||
try resolved_inputs.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
const lib_name = name_query.name;
|
||||
@ -1909,7 +1953,7 @@ fn resolveLibInput(
|
||||
else => |e| fatal("unable to search for tbd library '{}': {s}", .{ test_path, @errorName(e) }),
|
||||
};
|
||||
errdefer file.close();
|
||||
return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, name_query.query);
|
||||
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
|
||||
}
|
||||
|
||||
{
|
||||
@ -1947,7 +1991,7 @@ fn resolveLibInput(
|
||||
}),
|
||||
};
|
||||
errdefer file.close();
|
||||
return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, name_query.query);
|
||||
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
|
||||
}
|
||||
|
||||
// In the case of MinGW, the main check will be .lib but we also need to
|
||||
@ -1963,19 +2007,19 @@ fn resolveLibInput(
|
||||
else => |e| fatal("unable to search for static library '{}': {s}", .{ test_path, @errorName(e) }),
|
||||
};
|
||||
errdefer file.close();
|
||||
return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, name_query.query);
|
||||
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
|
||||
}
|
||||
|
||||
return .no_match;
|
||||
}
|
||||
|
||||
fn finishAccessLibPath(
|
||||
fn finishResolveLibInput(
|
||||
resolved_inputs: *std.ArrayListUnmanaged(Input),
|
||||
path: Path,
|
||||
file: std.fs.File,
|
||||
link_mode: std.builtin.LinkMode,
|
||||
query: UnresolvedInput.Query,
|
||||
) AccessLibPathResult {
|
||||
) ResolveLibInputResult {
|
||||
switch (link_mode) {
|
||||
.static => resolved_inputs.appendAssumeCapacity(.{ .archive = .{
|
||||
.path = path,
|
||||
@ -2052,7 +2096,7 @@ fn resolvePathInputLib(
|
||||
pq: UnresolvedInput.PathQuery,
|
||||
link_mode: std.builtin.LinkMode,
|
||||
color: std.zig.Color,
|
||||
) Allocator.Error!AccessLibPathResult {
|
||||
) Allocator.Error!ResolveLibInputResult {
|
||||
try resolved_inputs.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
const test_path: Path = pq.path;
|
||||
@ -2074,7 +2118,7 @@ fn resolvePathInputLib(
|
||||
if (n != ld_script_bytes.items.len) break :elf_file;
|
||||
if (!mem.eql(u8, ld_script_bytes.items[0..4], "\x7fELF")) break :elf_file;
|
||||
// Appears to be an ELF file.
|
||||
return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, pq.query);
|
||||
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
|
||||
}
|
||||
const stat = file.stat() catch |err|
|
||||
fatal("failed to stat {}: {s}", .{ test_path, @errorName(err) });
|
||||
@ -2140,7 +2184,7 @@ fn resolvePathInputLib(
|
||||
}),
|
||||
};
|
||||
errdefer file.close();
|
||||
return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, pq.query);
|
||||
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
|
||||
}
|
||||
|
||||
pub fn openObject(path: Path, must_link: bool, hidden: bool) !Input.Object {
|
||||
|
@ -291,10 +291,11 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {
|
||||
// Solaris releases after 10 merged the threading libraries into libc.
|
||||
.solaris, .illumos => &.{ "-lm", "-lsocket", "-lnsl", "-lc" },
|
||||
.haiku => &.{ "-lm", "-lroot", "-lpthread", "-lc", "-lnetwork" },
|
||||
else => if (target.isAndroid() or target.abi.isOpenHarmony())
|
||||
&.{ "-lm", "-lc", "-ldl" }
|
||||
else
|
||||
&.{ "-lm", "-lpthread", "-lc", "-ldl", "-lrt", "-lutil" },
|
||||
.linux => switch (target.abi) {
|
||||
.android, .androideabi, .ohos, .ohoseabi => &.{ "-lm", "-lc", "-ldl" },
|
||||
else => &.{ "-lm", "-lpthread", "-lc", "-ldl", "-lrt", "-lutil" },
|
||||
},
|
||||
else => &.{},
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user