aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-06-20 00:26:39 +0200
committerGitHub <noreply@github.com>2022-06-20 00:26:39 +0200
commit74442f35030a9c4f4ff65db01a18e8fb2f2a1ecf (patch)
tree0a3417d662326ce757cc8d89ca7e19498ead9207 /src
parent33cf6ef621114daad63d14067b6ff374e664d410 (diff)
parent1d4dbf8d3c891346e6dc978764e8bce9c85ad044 (diff)
downloadzig-74442f35030a9c4f4ff65db01a18e8fb2f2a1ecf.tar.gz
zig-74442f35030a9c4f4ff65db01a18e8fb2f2a1ecf.zip
Merge pull request #11847 from ziglang/better-libcompiler_rt
Diffstat (limited to 'src')
-rw-r--r--src/Compilation.zig158
-rw-r--r--src/ThreadPool.zig81
-rw-r--r--src/WaitGroup.zig7
-rw-r--r--src/link.zig7
-rw-r--r--src/link/Coff.zig2
-rw-r--r--src/link/Elf.zig2
-rw-r--r--src/link/MachO.zig50
-rw-r--r--src/link/Wasm.zig2
-rw-r--r--src/musl.zig1
9 files changed, 170 insertions, 140 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 54d87faa7b..2646da2f6f 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -92,6 +92,9 @@ unwind_tables: bool,
test_evented_io: bool,
debug_compiler_runtime_libs: bool,
debug_compile_errors: bool,
+job_queued_compiler_rt_lib: bool = false,
+job_queued_compiler_rt_obj: bool = false,
+alloc_failure_occurred: bool = false,
c_source_files: []const CSourceFile,
clang_argv: []const []const u8,
@@ -129,11 +132,11 @@ libssp_static_lib: ?CRTFile = null,
/// Populated when we build the libc static library. A Job to build this is placed in the queue
/// and resolved before calling linker.flush().
libc_static_lib: ?CRTFile = null,
-/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue
-/// and resolved before calling linker.flush().
-compiler_rt_static_lib: ?CRTFile = null,
-/// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue
-/// and resolved before calling linker.flush().
+/// Populated when we build the libcompiler_rt static library. A Job to build this is indicated
+/// by setting `job_queued_compiler_rt_lib` and resolved before calling linker.flush().
+compiler_rt_lib: ?CRTFile = null,
+/// Populated when we build the compiler_rt_obj object. A Job to build this is indicated
+/// by setting `job_queued_compiler_rt_obj` and resolved before calling linker.flush().
compiler_rt_obj: ?CRTFile = null,
glibc_so_files: ?glibc.BuiltSharedObjects = null,
@@ -175,7 +178,7 @@ pub const CRTFile = struct {
lock: Cache.Lock,
full_object_path: []const u8,
- fn deinit(self: *CRTFile, gpa: Allocator) void {
+ pub fn deinit(self: *CRTFile, gpa: Allocator) void {
self.lock.release();
gpa.free(self.full_object_path);
self.* = undefined;
@@ -223,8 +226,6 @@ const Job = union(enum) {
libcxxabi: void,
libtsan: void,
libssp: void,
- compiler_rt_lib: void,
- compiler_rt_obj: 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,
@@ -1924,13 +1925,13 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {
if (is_exe_or_dyn_lib) {
log.debug("queuing a job to build compiler_rt_lib", .{});
- try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });
+ comp.job_queued_compiler_rt_lib = true;
} else if (options.output_mode != .Obj) {
log.debug("queuing a job to build compiler_rt_obj", .{});
// If build-obj with -fcompiler-rt is requested, that is handled specially
// elsewhere. In this case we are making a static library, so we ask
// for a compiler-rt object to put in it.
- try comp.work_queue.writeItem(.{ .compiler_rt_obj = {} });
+ comp.job_queued_compiler_rt_obj = true;
}
}
if (needs_c_symbols) {
@@ -1978,7 +1979,7 @@ pub fn destroy(self: *Compilation) void {
if (self.libcxxabi_static_lib) |*crt_file| {
crt_file.deinit(gpa);
}
- if (self.compiler_rt_static_lib) |*crt_file| {
+ if (self.compiler_rt_lib) |*crt_file| {
crt_file.deinit(gpa);
}
if (self.compiler_rt_obj) |*crt_file| {
@@ -2020,6 +2021,7 @@ pub fn destroy(self: *Compilation) void {
}
pub fn clearMiscFailures(comp: *Compilation) void {
+ comp.alloc_failure_occurred = false;
for (comp.misc_failures.values()) |*value| {
value.deinit(comp.gpa);
}
@@ -2532,8 +2534,10 @@ pub fn makeBinFileWritable(self: *Compilation) !void {
return self.bin_file.makeWritable();
}
+/// This function is temporally single-threaded.
pub fn totalErrorCount(self: *Compilation) usize {
- var total: usize = self.failed_c_objects.count() + self.misc_failures.count();
+ var total: usize = self.failed_c_objects.count() + self.misc_failures.count() +
+ @boolToInt(self.alloc_failure_occurred);
if (self.bin_file.options.module) |module| {
total += module.failed_exports.count();
@@ -2590,6 +2594,7 @@ pub fn totalErrorCount(self: *Compilation) usize {
return total;
}
+/// This function is temporally single-threaded.
pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
var arena = std.heap.ArenaAllocator.init(self.gpa);
errdefer arena.deinit();
@@ -2622,6 +2627,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
for (self.misc_failures.values()) |*value| {
try AllErrors.addPlainWithChildren(&arena, &errors, value.msg, value.children);
}
+ if (self.alloc_failure_occurred) {
+ try AllErrors.addPlain(&arena, &errors, "memory allocation failure");
+ }
if (self.bin_file.options.module) |module| {
{
var it = module.failed_files.iterator();
@@ -2739,6 +2747,8 @@ pub fn performAllTheWork(
comp.work_queue_wait_group.reset();
defer comp.work_queue_wait_group.wait();
+ const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
+
{
const astgen_frame = tracy.namedFrame("astgen");
defer astgen_frame.end();
@@ -2783,7 +2793,6 @@ pub fn performAllTheWork(
}
}
- const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
if (!use_stage1) {
const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls");
defer outdated_and_deleted_decls_frame.end();
@@ -2826,6 +2835,16 @@ pub fn performAllTheWork(
}
break;
}
+
+ if (comp.job_queued_compiler_rt_lib) {
+ comp.job_queued_compiler_rt_lib = false;
+ buildCompilerRtOneShot(comp, .Lib, &comp.compiler_rt_lib);
+ }
+
+ if (comp.job_queued_compiler_rt_obj) {
+ comp.job_queued_compiler_rt_obj = false;
+ buildCompilerRtOneShot(comp, .Obj, &comp.compiler_rt_obj);
+ }
}
fn processOneJob(comp: *Compilation, job: Job) !void {
@@ -2996,7 +3015,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
module.semaPkg(pkg) catch |err| switch (err) {
error.CurrentWorkingDirectoryUnlinked,
error.Unexpected,
- => try comp.setMiscFailure(
+ => comp.lockAndSetMiscFailure(
.analyze_pkg,
"unexpected problem analyzing package '{s}'",
.{pkg.root_src_path},
@@ -3011,7 +3030,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
glibc.buildCRTFile(comp, crt_file) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(.glibc_crt_file, "unable to build glibc CRT file: {s}", .{
+ comp.lockAndSetMiscFailure(.glibc_crt_file, "unable to build glibc CRT file: {s}", .{
@errorName(err),
});
};
@@ -3022,7 +3041,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
glibc.buildSharedObjects(comp) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(
+ comp.lockAndSetMiscFailure(
.glibc_shared_objects,
"unable to build glibc shared objects: {s}",
.{@errorName(err)},
@@ -3035,7 +3054,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
musl.buildCRTFile(comp, crt_file) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(
+ comp.lockAndSetMiscFailure(
.musl_crt_file,
"unable to build musl CRT file: {s}",
.{@errorName(err)},
@@ -3048,7 +3067,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
mingw.buildCRTFile(comp, crt_file) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(
+ comp.lockAndSetMiscFailure(
.mingw_crt_file,
"unable to build mingw-w64 CRT file: {s}",
.{@errorName(err)},
@@ -3062,7 +3081,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
const link_lib = comp.bin_file.options.system_libs.keys()[index];
mingw.buildImportLib(comp, link_lib) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(
+ comp.lockAndSetMiscFailure(
.windows_import_lib,
"unable to generate DLL import .lib file: {s}",
.{@errorName(err)},
@@ -3075,7 +3094,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
libunwind.buildStaticLib(comp) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(
+ comp.lockAndSetMiscFailure(
.libunwind,
"unable to build libunwind: {s}",
.{@errorName(err)},
@@ -3088,7 +3107,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
libcxx.buildLibCXX(comp) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(
+ comp.lockAndSetMiscFailure(
.libcxx,
"unable to build libcxx: {s}",
.{@errorName(err)},
@@ -3101,7 +3120,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
libcxx.buildLibCXXABI(comp) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(
+ comp.lockAndSetMiscFailure(
.libcxxabi,
"unable to build libcxxabi: {s}",
.{@errorName(err)},
@@ -3114,7 +3133,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
libtsan.buildTsan(comp) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(
+ comp.lockAndSetMiscFailure(
.libtsan,
"unable to build TSAN library: {s}",
.{@errorName(err)},
@@ -3127,51 +3146,13 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
wasi_libc.buildCRTFile(comp, crt_file) catch |err| {
// TODO Surface more error details.
- try comp.setMiscFailure(
+ comp.lockAndSetMiscFailure(
.wasi_libc_crt_file,
"unable to build WASI libc CRT file: {s}",
.{@errorName(err)},
);
};
},
- .compiler_rt_lib => {
- const named_frame = tracy.namedFrame("compiler_rt_lib");
- defer named_frame.end();
-
- comp.buildOutputFromZig(
- "compiler_rt.zig",
- .Lib,
- &comp.compiler_rt_static_lib,
- .compiler_rt,
- ) catch |err| switch (err) {
- error.OutOfMemory => return error.OutOfMemory,
- error.SubCompilationFailed => return, // error reported already
- else => try comp.setMiscFailure(
- .compiler_rt,
- "unable to build compiler_rt: {s}",
- .{@errorName(err)},
- ),
- };
- },
- .compiler_rt_obj => {
- const named_frame = tracy.namedFrame("compiler_rt_obj");
- defer named_frame.end();
-
- comp.buildOutputFromZig(
- "compiler_rt.zig",
- .Obj,
- &comp.compiler_rt_obj,
- .compiler_rt,
- ) catch |err| switch (err) {
- error.OutOfMemory => return error.OutOfMemory,
- error.SubCompilationFailed => return, // error reported already
- else => try comp.setMiscFailure(
- .compiler_rt,
- "unable to build compiler_rt: {s}",
- .{@errorName(err)},
- ),
- };
- },
.libssp => {
const named_frame = tracy.namedFrame("libssp");
defer named_frame.end();
@@ -3184,7 +3165,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
error.SubCompilationFailed => return, // error reported already
- else => try comp.setMiscFailure(
+ else => comp.lockAndSetMiscFailure(
.libssp,
"unable to build libssp: {s}",
.{@errorName(err)},
@@ -3203,7 +3184,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
error.SubCompilationFailed => return, // error reported already
- else => try comp.setMiscFailure(
+ else => comp.lockAndSetMiscFailure(
.zig_libc,
"unable to build zig's multitarget libc: {s}",
.{@errorName(err)},
@@ -3307,11 +3288,7 @@ fn workerUpdateBuiltinZigFile(
comp.setMiscFailure(.write_builtin_zig, "unable to write builtin.zig to {s}: {s}", .{
dir_path, @errorName(err),
- }) catch |oom| switch (oom) {
- error.OutOfMemory => log.err("unable to write builtin.zig to {s}: {s}", .{
- dir_path, @errorName(err),
- }),
- };
+ });
};
}
@@ -3525,6 +3502,21 @@ fn workerUpdateCObject(
};
}
+fn buildCompilerRtOneShot(
+ comp: *Compilation,
+ output_mode: std.builtin.OutputMode,
+ out: *?CRTFile,
+) void {
+ comp.buildOutputFromZig("compiler_rt.zig", output_mode, out, .compiler_rt) catch |err| switch (err) {
+ error.SubCompilationFailed => return, // error reported already
+ else => comp.lockAndSetMiscFailure(
+ .compiler_rt,
+ "unable to build compiler_rt: {s}",
+ .{@errorName(err)},
+ ),
+ };
+}
+
fn reportRetryableCObjectError(
comp: *Compilation,
c_object: *CObject,
@@ -4623,14 +4615,21 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
comp.bin_file.options.object_format != .c;
}
-fn setMiscFailure(
+fn setAllocFailure(comp: *Compilation) void {
+ log.debug("memory allocation failure", .{});
+ comp.alloc_failure_occurred = true;
+}
+
+/// Assumes that Compilation mutex is locked.
+/// See also `lockAndSetMiscFailure`.
+pub fn setMiscFailure(
comp: *Compilation,
tag: MiscTask,
comptime format: []const u8,
args: anytype,
-) Allocator.Error!void {
- try comp.misc_failures.ensureUnusedCapacity(comp.gpa, 1);
- const msg = try std.fmt.allocPrint(comp.gpa, format, args);
+) void {
+ comp.misc_failures.ensureUnusedCapacity(comp.gpa, 1) catch return comp.setAllocFailure();
+ const msg = std.fmt.allocPrint(comp.gpa, format, args) catch return comp.setAllocFailure();
const gop = comp.misc_failures.getOrPutAssumeCapacity(tag);
if (gop.found_existing) {
gop.value_ptr.deinit(comp.gpa);
@@ -4638,6 +4637,19 @@ fn setMiscFailure(
gop.value_ptr.* = .{ .msg = msg };
}
+/// See also `setMiscFailure`.
+pub fn lockAndSetMiscFailure(
+ comp: *Compilation,
+ tag: MiscTask,
+ comptime format: []const u8,
+ args: anytype,
+) void {
+ comp.mutex.lock();
+ defer comp.mutex.unlock();
+
+ return setMiscFailure(comp, tag, format, args);
+}
+
pub fn dump_argv(argv: []const []const u8) void {
for (argv[0 .. argv.len - 1]) |arg| {
std.debug.print("{s} ", .{arg});
diff --git a/src/ThreadPool.zig b/src/ThreadPool.zig
index 55e40ea287..7115adbddd 100644
--- a/src/ThreadPool.zig
+++ b/src/ThreadPool.zig
@@ -1,6 +1,7 @@
const std = @import("std");
const builtin = @import("builtin");
const ThreadPool = @This();
+const WaitGroup = @import("WaitGroup.zig");
mutex: std.Thread.Mutex = .{},
cond: std.Thread.Condition = .{},
@@ -19,8 +20,8 @@ const RunProto = switch (builtin.zig_backend) {
else => *const fn (*Runnable) void,
};
-pub fn init(self: *ThreadPool, allocator: std.mem.Allocator) !void {
- self.* = .{
+pub fn init(pool: *ThreadPool, allocator: std.mem.Allocator) !void {
+ pool.* = .{
.allocator = allocator,
.threads = &[_]std.Thread{},
};
@@ -30,48 +31,48 @@ pub fn init(self: *ThreadPool, allocator: std.mem.Allocator) !void {
}
const thread_count = std.math.max(1, std.Thread.getCpuCount() catch 1);
- self.threads = try allocator.alloc(std.Thread, thread_count);
- errdefer allocator.free(self.threads);
+ pool.threads = try allocator.alloc(std.Thread, thread_count);
+ errdefer allocator.free(pool.threads);
// kill and join any threads we spawned previously on error.
var spawned: usize = 0;
- errdefer self.join(spawned);
+ errdefer pool.join(spawned);
- for (self.threads) |*thread| {
- thread.* = try std.Thread.spawn(.{}, worker, .{self});
+ for (pool.threads) |*thread| {
+ thread.* = try std.Thread.spawn(.{}, worker, .{pool});
spawned += 1;
}
}
-pub fn deinit(self: *ThreadPool) void {
- self.join(self.threads.len); // kill and join all threads.
- self.* = undefined;
+pub fn deinit(pool: *ThreadPool) void {
+ pool.join(pool.threads.len); // kill and join all threads.
+ pool.* = undefined;
}
-fn join(self: *ThreadPool, spawned: usize) void {
+fn join(pool: *ThreadPool, spawned: usize) void {
if (builtin.single_threaded) {
return;
}
{
- self.mutex.lock();
- defer self.mutex.unlock();
+ pool.mutex.lock();
+ defer pool.mutex.unlock();
// ensure future worker threads exit the dequeue loop
- self.is_running = false;
+ pool.is_running = false;
}
// wake up any sleeping threads (this can be done outside the mutex)
// then wait for all the threads we know are spawned to complete.
- self.cond.broadcast();
- for (self.threads[0..spawned]) |thread| {
+ pool.cond.broadcast();
+ for (pool.threads[0..spawned]) |thread| {
thread.join();
}
- self.allocator.free(self.threads);
+ pool.allocator.free(pool.threads);
}
-pub fn spawn(self: *ThreadPool, comptime func: anytype, args: anytype) !void {
+pub fn spawn(pool: *ThreadPool, comptime func: anytype, args: anytype) !void {
if (builtin.single_threaded) {
@call(.{}, func, args);
return;
@@ -98,41 +99,57 @@ pub fn spawn(self: *ThreadPool, comptime func: anytype, args: anytype) !void {
};
{
- self.mutex.lock();
- defer self.mutex.unlock();
+ pool.mutex.lock();
+ defer pool.mutex.unlock();
- const closure = try self.allocator.create(Closure);
+ const closure = try pool.allocator.create(Closure);
closure.* = .{
.arguments = args,
- .pool = self,
+ .pool = pool,
};
- self.run_queue.prepend(&closure.run_node);
+ pool.run_queue.prepend(&closure.run_node);
}
// Notify waiting threads outside the lock to try and keep the critical section small.
- self.cond.signal();
+ pool.cond.signal();
}
-fn worker(self: *ThreadPool) void {
- self.mutex.lock();
- defer self.mutex.unlock();
+fn worker(pool: *ThreadPool) void {
+ pool.mutex.lock();
+ defer pool.mutex.unlock();
while (true) {
- while (self.run_queue.popFirst()) |run_node| {
+ while (pool.run_queue.popFirst()) |run_node| {
// Temporarily unlock the mutex in order to execute the run_node
- self.mutex.unlock();
- defer self.mutex.lock();
+ pool.mutex.unlock();
+ defer pool.mutex.lock();
const runFn = run_node.data.runFn;
runFn(&run_node.data);
}
// Stop executing instead of waiting if the thread pool is no longer running.
- if (self.is_running) {
- self.cond.wait(&self.mutex);
+ if (pool.is_running) {
+ pool.cond.wait(&pool.mutex);
} else {
break;
}
}
}
+
+pub fn waitAndWork(pool: *ThreadPool, wait_group: *WaitGroup) void {
+ while (!wait_group.isDone()) {
+ if (blk: {
+ pool.mutex.lock();
+ defer pool.mutex.unlock();
+ break :blk pool.run_queue.popFirst();
+ }) |run_node| {
+ run_node.data.runFn(&run_node.data);
+ continue;
+ }
+
+ wait_group.wait();
+ return;
+ }
+}
diff --git a/src/WaitGroup.zig b/src/WaitGroup.zig
index 860d0a8b4c..c8be6658db 100644
--- a/src/WaitGroup.zig
+++ b/src/WaitGroup.zig
@@ -37,3 +37,10 @@ pub fn reset(self: *WaitGroup) void {
self.state.store(0, .Monotonic);
self.event.reset();
}
+
+pub fn isDone(wg: *WaitGroup) bool {
+ const state = wg.state.load(.Acquire);
+ assert(state & is_waiting == 0);
+
+ return (state / one_pending) == 0;
+}
diff --git a/src/link.zig b/src/link.zig
index 51712db40e..65e9de8ca3 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -792,11 +792,8 @@ pub const File = struct {
}),
}
}
- if (base.options.object_format == .macho) {
- try base.cast(MachO).?.flushObject(comp, prog_node);
- } else {
- try base.flushModule(comp, prog_node);
- }
+ try base.flushModule(comp, prog_node);
+
const dirname = fs.path.dirname(full_out_path_z) orelse ".";
break :blk try fs.path.join(arena, &.{ dirname, base.intermediary_basename.? });
} else null;
diff --git a/src/link/Coff.zig b/src/link/Coff.zig
index 37ec8d0758..2943cae36a 100644
--- a/src/link/Coff.zig
+++ b/src/link/Coff.zig
@@ -1354,7 +1354,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
}
// MSVC compiler_rt is missing some stuff, so we build it unconditionally but
// and rely on weak linkage to allow MSVC compiler_rt functions to override ours.
- if (comp.compiler_rt_static_lib) |lib| {
+ if (comp.compiler_rt_lib) |lib| {
try argv.append(lib.full_object_path);
}
}
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index e0f114acd4..a0e40e5682 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -1272,7 +1272,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
const stack_size = self.base.options.stack_size_override orelse 16777216;
const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
const compiler_rt_path: ?[]const u8 = blk: {
- if (comp.compiler_rt_static_lib) |x| break :blk x.full_object_path;
+ if (comp.compiler_rt_lib) |x| break :blk x.full_object_path;
if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
break :blk null;
};
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index a4d14b985f..c71007157a 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -436,7 +436,7 @@ pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !v
return error.TODOImplementWritingStaticLibFiles;
}
}
- try self.flushModule(comp, prog_node);
+ return self.flushModule(comp, prog_node);
}
pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void {
@@ -444,8 +444,23 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
defer tracy.end();
const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
- if (!use_stage1 and self.base.options.output_mode == .Obj)
- return self.flushObject(comp, prog_node);
+
+ if (build_options.have_llvm and !use_stage1) {
+ if (self.llvm_object) |llvm_object| {
+ try llvm_object.flushModule(comp, prog_node);
+
+ llvm_object.destroy(self.base.allocator);
+ self.llvm_object = null;
+
+ if (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Static) {
+ return;
+ }
+ }
+ }
+
+ var sub_prog_node = prog_node.start("MachO Flush", 0);
+ sub_prog_node.activate();
+ defer sub_prog_node.end();
var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
defer arena_allocator.deinit();
@@ -454,12 +469,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
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 (self.d_sym) |*d_sym| {
- if (self.base.options.module) |module| {
- try d_sym.dwarf.flushModule(&self.base, module);
- }
- }
-
// 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.
const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {
@@ -482,8 +491,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
const obj_basename = self.base.intermediary_basename orelse break :blk null;
- try self.flushObject(comp, prog_node);
-
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, obj_basename });
} else {
@@ -491,9 +498,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
}
} else null;
- var sub_prog_node = prog_node.start("MachO Flush", 0);
- sub_prog_node.activate();
- defer sub_prog_node.end();
+ if (self.d_sym) |*d_sym| {
+ if (self.base.options.module) |module| {
+ try d_sym.dwarf.flushModule(&self.base, module);
+ }
+ }
const is_lib = self.base.options.output_mode == .Lib;
const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
@@ -738,7 +747,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
try positionals.append(p);
}
- if (comp.compiler_rt_static_lib) |lib| {
+ if (comp.compiler_rt_lib) |lib| {
try positionals.append(lib.full_object_path);
}
@@ -1119,17 +1128,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
self.cold_start = false;
}
-pub fn flushObject(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void {
- const tracy = trace(@src());
- defer tracy.end();
-
- if (build_options.have_llvm)
- if (self.llvm_object) |llvm_object|
- return llvm_object.flushModule(comp, prog_node);
-
- return error.TODOImplementWritingObjFiles;
-}
-
fn resolveSearchDir(
arena: Allocator,
dir: []const u8,
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index ee2ed19ed5..5a910e188b 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -2255,7 +2255,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
const is_obj = self.base.options.output_mode == .Obj;
const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj)
- comp.compiler_rt_static_lib.?.full_object_path
+ comp.compiler_rt_lib.?.full_object_path
else
null;
diff --git a/src/musl.zig b/src/musl.zig
index d061addc9a..68b524b415 100644
--- a/src/musl.zig
+++ b/src/musl.zig
@@ -4,7 +4,6 @@ const mem = std.mem;
const path = std.fs.path;
const assert = std.debug.assert;
-const target_util = @import("target.zig");
const Compilation = @import("Compilation.zig");
const build_options = @import("build_options");