Commit 1cfc364785
Changed files (2)
src/Compilation.zig
@@ -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,
src/libtsan.zig
@@ -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{