tsan: build dynamic library on Apple platforms

This commit is contained in:
Jakub Konka 2024-07-04 07:19:08 +02:00
parent 768b17755e
commit 1cfc364785
2 changed files with 34 additions and 6 deletions

View File

@ -188,6 +188,9 @@ libunwind_static_lib: ?CRTFile = null,
/// Populated when we build the TSAN static library. A Job to build this is placed in the queue
/// and resolved before calling linker.flush().
tsan_static_lib: ?CRTFile = null,
/// Populated when we build the TSAN dynamic library. A Job to build this is placed in the queue
/// and resolved before calling linker.flush().
tsan_dynamic_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,

View File

@ -25,10 +25,20 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
const root_name = "tsan";
const output_mode = .Lib;
const link_mode = .static;
const target = comp.getTarget();
const root_name = switch (target.os.tag) {
// On Apple platforms, we use the same name as LLVM and Apple so that we correctly
// mark the images as instrumented when traversing them when TSAN dylib is
// initialized.
.macos => "clang_rt.tsan_osx_dynamic",
.ios => switch (target.abi) {
.simulator => "clang_rt.tsan_iossim_dynamic",
else => "clang_rt.tsan_ios_dynamic",
},
else => "tsan",
};
const link_mode: std.builtin.LinkMode = if (target.isDarwin()) .dynamic else .static;
const output_mode = .Lib;
const basename = try std.zig.binNameAlloc(arena, .{
.root_name = root_name,
.target = target,
@ -43,6 +53,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
const optimize_mode = comp.compilerRtOptMode();
const strip = comp.compilerRtStrip();
const link_libcpp = target.isDarwin();
const config = Compilation.Config.resolve(.{
.output_mode = output_mode,
@ -54,6 +65,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
.root_optimize_mode = optimize_mode,
.root_strip = strip,
.link_libc = true,
.link_libcpp = link_libcpp,
}) catch |err| {
comp.setMiscFailure(
.libtsan,
@ -272,6 +284,12 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
});
}
const skip_linker_dependencies = !target.isDarwin();
const linker_allow_shlib_undefined = target.isDarwin();
const install_name = if (target.isDarwin())
try std.fmt.allocPrintZ(arena, "@rpath/{s}", .{basename})
else
null;
const sub_compilation = Compilation.create(comp.gpa, arena, .{
.local_cache_directory = comp.global_cache_directory,
.global_cache_directory = comp.global_cache_directory,
@ -294,7 +312,9 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
.verbose_cimport = comp.verbose_cimport,
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
.skip_linker_dependencies = true,
.skip_linker_dependencies = skip_linker_dependencies,
.linker_allow_shlib_undefined = linker_allow_shlib_undefined,
.install_name = install_name,
}) catch |err| {
comp.setMiscFailure(
.libtsan,
@ -317,8 +337,13 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
},
};
assert(comp.tsan_static_lib == null);
comp.tsan_static_lib = try sub_compilation.toCrtFile();
assert(comp.tsan_static_lib == null and comp.tsan_dynamic_lib == null);
if (target.isDarwin()) {
comp.tsan_dynamic_lib = try sub_compilation.toCrtFile();
} else {
comp.tsan_static_lib = try sub_compilation.toCrtFile();
}
}
const tsan_sources = [_][]const u8{