mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 03:03:09 +00:00
Compilation pipeline: linker input producing Job representation
Move all the remaining Jobs that produce linker inputs to be spawned earlier in the pipeline and registered with link_task_wait_group.
This commit is contained in:
parent
966169fa68
commit
28da530271
@ -291,8 +291,18 @@ const QueuedJobs = struct {
|
||||
update_builtin_zig: bool,
|
||||
musl_crt_file: [@typeInfo(musl.CrtFile).@"enum".fields.len]bool = [1]bool{false} ** @typeInfo(musl.CrtFile).@"enum".fields.len,
|
||||
glibc_crt_file: [@typeInfo(glibc.CrtFile).@"enum".fields.len]bool = [1]bool{false} ** @typeInfo(glibc.CrtFile).@"enum".fields.len,
|
||||
/// one of WASI libc static objects
|
||||
wasi_libc_crt_file: [@typeInfo(wasi_libc.CrtFile).@"enum".fields.len]bool = [1]bool{false} ** @typeInfo(wasi_libc.CrtFile).@"enum".fields.len,
|
||||
/// one of the mingw-w64 static objects
|
||||
mingw_crt_file: [@typeInfo(mingw.CrtFile).@"enum".fields.len]bool = [1]bool{false} ** @typeInfo(mingw.CrtFile).@"enum".fields.len,
|
||||
/// all of the glibc shared objects
|
||||
glibc_shared_objects: bool = false,
|
||||
/// libunwind.a, usually needed when linking libc
|
||||
libunwind: bool = false,
|
||||
libcxx: bool = false,
|
||||
libcxxabi: bool = false,
|
||||
libtsan: bool = false,
|
||||
zig_libc: bool = false,
|
||||
};
|
||||
|
||||
pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size;
|
||||
@ -388,20 +398,6 @@ const Job = union(enum) {
|
||||
/// Fully resolve the given `struct` or `union` type.
|
||||
resolve_type_fully: InternPool.Index,
|
||||
|
||||
/// one of the mingw-w64 static objects
|
||||
mingw_crt_file: mingw.CrtFile,
|
||||
|
||||
/// libunwind.a, usually needed when linking libc
|
||||
libunwind: void,
|
||||
libcxx: void,
|
||||
libcxxabi: void,
|
||||
libtsan: void,
|
||||
/// needed when not linking libc and using LLVM for code generation because it generates
|
||||
/// calls to, for example, memcpy and memset.
|
||||
zig_libc: void,
|
||||
/// one of WASI libc static objects
|
||||
wasi_libc_crt_file: wasi_libc.CrtFile,
|
||||
|
||||
/// The value is the index into `windows_libs`.
|
||||
windows_import_lib: usize,
|
||||
|
||||
@ -1846,24 +1842,19 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
||||
if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
|
||||
|
||||
for (comp.wasi_emulated_libs) |crt_file| {
|
||||
try comp.queueJob(.{
|
||||
.wasi_libc_crt_file = crt_file,
|
||||
});
|
||||
comp.remaining_prelink_tasks += 1;
|
||||
comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(crt_file)] = true;
|
||||
}
|
||||
try comp.queueJobs(&[_]Job{
|
||||
.{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(comp.config.wasi_exec_model) },
|
||||
.{ .wasi_libc_crt_file = .libc_a },
|
||||
});
|
||||
comp.remaining_prelink_tasks += @intCast(comp.wasi_emulated_libs.len);
|
||||
|
||||
comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.execModelCrtFile(comp.config.wasi_exec_model))] = true;
|
||||
comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.CrtFile.libc_a)] = true;
|
||||
comp.remaining_prelink_tasks += 2;
|
||||
} else if (target.isMinGW()) {
|
||||
if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
|
||||
|
||||
const crt_job: Job = .{ .mingw_crt_file = if (is_dyn_lib) .dllcrt2_o else .crt2_o };
|
||||
try comp.queueJobs(&.{
|
||||
.{ .mingw_crt_file = .mingw32_lib },
|
||||
crt_job,
|
||||
});
|
||||
const main_crt_file: mingw.CrtFile = if (is_dyn_lib) .dllcrt2_o else .crt2_o;
|
||||
comp.queued_jobs.mingw_crt_file[@intFromEnum(main_crt_file)] = true;
|
||||
comp.queued_jobs.mingw_crt_file[@intFromEnum(mingw.CrtFile.mingw32_lib)] = true;
|
||||
comp.remaining_prelink_tasks += 2;
|
||||
|
||||
// When linking mingw-w64 there are some import libs we always need.
|
||||
@ -1875,7 +1866,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
||||
else => return error.LibCUnavailable,
|
||||
}
|
||||
} else if (target.os.tag == .freestanding and capable_of_building_zig_libc) {
|
||||
try comp.queueJob(.{ .zig_libc = {} });
|
||||
comp.queued_jobs.zig_libc = true;
|
||||
comp.remaining_prelink_tasks += 1;
|
||||
} else {
|
||||
return error.LibCUnavailable;
|
||||
@ -1888,18 +1879,22 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
||||
for (0..count) |i| {
|
||||
try comp.queueJob(.{ .windows_import_lib = i });
|
||||
}
|
||||
// when integrating coff linker with prelink, the above
|
||||
// queueJob will need to change into something else since those
|
||||
// jobs are dispatched *after* the link_task_wait_group.wait()
|
||||
// that happens when separateCodegenThreadOk() is false.
|
||||
}
|
||||
if (comp.wantBuildLibUnwindFromSource()) {
|
||||
try comp.queueJob(.{ .libunwind = {} });
|
||||
comp.queued_jobs.libunwind = true;
|
||||
comp.remaining_prelink_tasks += 1;
|
||||
}
|
||||
if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.link_libcpp) {
|
||||
try comp.queueJob(.libcxx);
|
||||
try comp.queueJob(.libcxxabi);
|
||||
comp.queued_jobs.libcxx = true;
|
||||
comp.queued_jobs.libcxxabi = true;
|
||||
comp.remaining_prelink_tasks += 2;
|
||||
}
|
||||
if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.any_sanitize_thread) {
|
||||
try comp.queueJob(.libtsan);
|
||||
comp.queued_jobs.libtsan = true;
|
||||
comp.remaining_prelink_tasks += 1;
|
||||
}
|
||||
|
||||
@ -3726,6 +3721,30 @@ fn performAllTheWorkInner(
|
||||
comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "fuzzer.zig", .libfuzzer, .Lib, &comp.fuzzer_lib, main_progress_node });
|
||||
}
|
||||
|
||||
if (testAndClear(&comp.queued_jobs.glibc_shared_objects)) {
|
||||
comp.link_task_wait_group.spawnManager(buildGlibcSharedObjects, .{ comp, main_progress_node });
|
||||
}
|
||||
|
||||
if (testAndClear(&comp.queued_jobs.libunwind)) {
|
||||
comp.link_task_wait_group.spawnManager(buildLibUnwind, .{ comp, main_progress_node });
|
||||
}
|
||||
|
||||
if (testAndClear(&comp.queued_jobs.libcxx)) {
|
||||
comp.link_task_wait_group.spawnManager(buildLibCxx, .{ comp, main_progress_node });
|
||||
}
|
||||
|
||||
if (testAndClear(&comp.queued_jobs.libcxxabi)) {
|
||||
comp.link_task_wait_group.spawnManager(buildLibCxxAbi, .{ comp, main_progress_node });
|
||||
}
|
||||
|
||||
if (testAndClear(&comp.queued_jobs.libtsan)) {
|
||||
comp.link_task_wait_group.spawnManager(buildLibTsan, .{ comp, main_progress_node });
|
||||
}
|
||||
|
||||
if (testAndClear(&comp.queued_jobs.zig_libc)) {
|
||||
comp.link_task_wait_group.spawnManager(buildZigLibc, .{ comp, main_progress_node });
|
||||
}
|
||||
|
||||
for (0..@typeInfo(musl.CrtFile).@"enum".fields.len) |i| {
|
||||
if (testAndClear(&comp.queued_jobs.musl_crt_file[i])) {
|
||||
const tag: musl.CrtFile = @enumFromInt(i);
|
||||
@ -3740,8 +3759,18 @@ fn performAllTheWorkInner(
|
||||
}
|
||||
}
|
||||
|
||||
if (testAndClear(&comp.queued_jobs.glibc_shared_objects)) {
|
||||
comp.link_task_wait_group.spawnManager(buildGlibcSharedObjects, .{ comp, main_progress_node });
|
||||
for (0..@typeInfo(wasi_libc.CrtFile).@"enum".fields.len) |i| {
|
||||
if (testAndClear(&comp.queued_jobs.wasi_libc_crt_file[i])) {
|
||||
const tag: wasi_libc.CrtFile = @enumFromInt(i);
|
||||
comp.link_task_wait_group.spawnManager(buildWasiLibcCrtFile, .{ comp, tag, main_progress_node });
|
||||
}
|
||||
}
|
||||
|
||||
for (0..@typeInfo(mingw.CrtFile).@"enum".fields.len) |i| {
|
||||
if (testAndClear(&comp.queued_jobs.mingw_crt_file[i])) {
|
||||
const tag: mingw.CrtFile = @enumFromInt(i);
|
||||
comp.link_task_wait_group.spawnManager(buildMingwCrtFile, .{ comp, tag, main_progress_node });
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@ -3843,7 +3872,7 @@ fn performAllTheWorkInner(
|
||||
|
||||
work: while (true) {
|
||||
for (&comp.work_queues) |*work_queue| if (work_queue.readItem()) |job| {
|
||||
try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, job, main_progress_node);
|
||||
try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, job);
|
||||
continue :work;
|
||||
};
|
||||
if (comp.zcu) |zcu| {
|
||||
@ -3878,7 +3907,7 @@ pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {
|
||||
for (jobs) |job| try comp.queueJob(job);
|
||||
}
|
||||
|
||||
fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) JobError!void {
|
||||
fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {
|
||||
switch (job) {
|
||||
.codegen_nav => |nav_index| {
|
||||
const zcu = comp.zcu.?;
|
||||
@ -3974,19 +4003,6 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
|
||||
error.AnalysisFail => return,
|
||||
};
|
||||
},
|
||||
.mingw_crt_file => |crt_file| {
|
||||
const named_frame = tracy.namedFrame("mingw_crt_file");
|
||||
defer named_frame.end();
|
||||
|
||||
mingw.buildCrtFile(comp, crt_file, prog_node) catch |err| {
|
||||
// TODO Surface more error details.
|
||||
comp.lockAndSetMiscFailure(
|
||||
.mingw_crt_file,
|
||||
"unable to build mingw-w64 CRT file {s}: {s}",
|
||||
.{ @tagName(crt_file), @errorName(err) },
|
||||
);
|
||||
};
|
||||
},
|
||||
.windows_import_lib => |index| {
|
||||
const named_frame = tracy.namedFrame("windows_import_lib");
|
||||
defer named_frame.end();
|
||||
@ -4001,95 +4017,6 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
|
||||
);
|
||||
};
|
||||
},
|
||||
.libunwind => {
|
||||
const named_frame = tracy.namedFrame("libunwind");
|
||||
defer named_frame.end();
|
||||
|
||||
libunwind.buildStaticLib(comp, prog_node) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(
|
||||
.libunwind,
|
||||
"unable to build libunwind: {s}",
|
||||
.{@errorName(err)},
|
||||
),
|
||||
};
|
||||
},
|
||||
.libcxx => {
|
||||
const named_frame = tracy.namedFrame("libcxx");
|
||||
defer named_frame.end();
|
||||
|
||||
libcxx.buildLibCXX(comp, prog_node) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(
|
||||
.libcxx,
|
||||
"unable to build libcxx: {s}",
|
||||
.{@errorName(err)},
|
||||
),
|
||||
};
|
||||
},
|
||||
.libcxxabi => {
|
||||
const named_frame = tracy.namedFrame("libcxxabi");
|
||||
defer named_frame.end();
|
||||
|
||||
libcxx.buildLibCXXABI(comp, prog_node) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(
|
||||
.libcxxabi,
|
||||
"unable to build libcxxabi: {s}",
|
||||
.{@errorName(err)},
|
||||
),
|
||||
};
|
||||
},
|
||||
.libtsan => {
|
||||
const named_frame = tracy.namedFrame("libtsan");
|
||||
defer named_frame.end();
|
||||
|
||||
libtsan.buildTsan(comp, prog_node) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(
|
||||
.libtsan,
|
||||
"unable to build TSAN library: {s}",
|
||||
.{@errorName(err)},
|
||||
),
|
||||
};
|
||||
},
|
||||
.wasi_libc_crt_file => |crt_file| {
|
||||
const named_frame = tracy.namedFrame("wasi_libc_crt_file");
|
||||
defer named_frame.end();
|
||||
|
||||
wasi_libc.buildCrtFile(comp, crt_file, prog_node) catch |err| {
|
||||
// TODO Surface more error details.
|
||||
comp.lockAndSetMiscFailure(
|
||||
.wasi_libc_crt_file,
|
||||
"unable to build WASI libc CRT file: {s}",
|
||||
.{@errorName(err)},
|
||||
);
|
||||
};
|
||||
},
|
||||
.zig_libc => {
|
||||
const named_frame = tracy.namedFrame("zig_libc");
|
||||
defer named_frame.end();
|
||||
|
||||
comp.buildOutputFromZig(
|
||||
"c.zig",
|
||||
.Lib,
|
||||
&comp.libc_static_lib,
|
||||
.zig_libc,
|
||||
prog_node,
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(
|
||||
.zig_libc,
|
||||
"unable to build zig's multitarget libc: {s}",
|
||||
.{@errorName(err)},
|
||||
),
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -4742,11 +4669,7 @@ fn buildRt(
|
||||
};
|
||||
}
|
||||
|
||||
fn buildMuslCrtFile(
|
||||
comp: *Compilation,
|
||||
crt_file: musl.CrtFile,
|
||||
prog_node: std.Progress.Node,
|
||||
) void {
|
||||
fn buildMuslCrtFile(comp: *Compilation, crt_file: musl.CrtFile, prog_node: std.Progress.Node) void {
|
||||
musl.buildCrtFile(comp, crt_file, prog_node) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(.musl_crt_file, "unable to build musl {s}: {s}", .{
|
||||
@ -4755,11 +4678,7 @@ fn buildMuslCrtFile(
|
||||
};
|
||||
}
|
||||
|
||||
fn buildGlibcCrtFile(
|
||||
comp: *Compilation,
|
||||
crt_file: glibc.CrtFile,
|
||||
prog_node: std.Progress.Node,
|
||||
) void {
|
||||
fn buildGlibcCrtFile(comp: *Compilation, crt_file: glibc.CrtFile, prog_node: std.Progress.Node) void {
|
||||
glibc.buildCrtFile(comp, crt_file, prog_node) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(.glibc_crt_file, "unable to build glibc {s}: {s}", .{
|
||||
@ -4777,6 +4696,65 @@ fn buildGlibcSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) voi
|
||||
};
|
||||
}
|
||||
|
||||
fn buildMingwCrtFile(comp: *Compilation, crt_file: mingw.CrtFile, prog_node: std.Progress.Node) void {
|
||||
mingw.buildCrtFile(comp, crt_file, prog_node) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(.mingw_crt_file, "unable to build mingw-w64 {s}: {s}", .{
|
||||
@tagName(crt_file), @errorName(err),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
fn buildWasiLibcCrtFile(comp: *Compilation, crt_file: wasi_libc.CrtFile, prog_node: std.Progress.Node) void {
|
||||
wasi_libc.buildCrtFile(comp, crt_file, prog_node) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(.wasi_libc_crt_file, "unable to build WASI libc {s}: {s}", .{
|
||||
@tagName(crt_file), @errorName(err),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
fn buildLibUnwind(comp: *Compilation, prog_node: std.Progress.Node) void {
|
||||
libunwind.buildStaticLib(comp, prog_node) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(.libunwind, "unable to build libunwind: {s}", .{@errorName(err)}),
|
||||
};
|
||||
}
|
||||
|
||||
fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) void {
|
||||
libcxx.buildLibCxx(comp, prog_node) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(.libcxx, "unable to build libcxx: {s}", .{@errorName(err)}),
|
||||
};
|
||||
}
|
||||
|
||||
fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) void {
|
||||
libcxx.buildLibCxxAbi(comp, prog_node) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(.libcxxabi, "unable to build libcxxabi: {s}", .{@errorName(err)}),
|
||||
};
|
||||
}
|
||||
|
||||
fn buildLibTsan(comp: *Compilation, prog_node: std.Progress.Node) void {
|
||||
libtsan.buildTsan(comp, prog_node) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(.libtsan, "unable to build TSAN library: {s}", .{@errorName(err)}),
|
||||
};
|
||||
}
|
||||
|
||||
fn buildZigLibc(comp: *Compilation, prog_node: std.Progress.Node) void {
|
||||
comp.buildOutputFromZig(
|
||||
"c.zig",
|
||||
.Lib,
|
||||
&comp.libc_static_lib,
|
||||
.zig_libc,
|
||||
prog_node,
|
||||
) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(.zig_libc, "unable to build zig's multitarget libc: {s}", .{@errorName(err)}),
|
||||
};
|
||||
}
|
||||
|
||||
fn reportRetryableCObjectError(
|
||||
comp: *Compilation,
|
||||
c_object: *CObject,
|
||||
|
||||
@ -114,7 +114,7 @@ pub const BuildError = error{
|
||||
ZigCompilerNotBuiltWithLLVMExtensions,
|
||||
};
|
||||
|
||||
pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void {
|
||||
pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void {
|
||||
if (!build_options.have_llvm) {
|
||||
return error.ZigCompilerNotBuiltWithLLVMExtensions;
|
||||
}
|
||||
@ -357,7 +357,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
|
||||
comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
|
||||
}
|
||||
|
||||
pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void {
|
||||
pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void {
|
||||
if (!build_options.have_llvm) {
|
||||
return error.ZigCompilerNotBuiltWithLLVMExtensions;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user