| ... | @@ -25,10 +25,20 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -25,10 +25,20 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 25 | defer arena_allocator.deinit(); | 25 | defer arena_allocator.deinit(); |
| 26 | const arena = arena_allocator.allocator(); | 26 | const arena = arena_allocator.allocator(); |
| 27 | | 27 | |
| 28 | const root_name = "tsan"; | | |
| 29 | const output_mode = .Lib; | | |
| 30 | const link_mode = .static; | | |
| 31 | const target = comp.getTarget(); | 28 | const target = comp.getTarget(); |
| | 29 | const root_name = switch (target.os.tag) { |
| | 30 | // On Apple platforms, we use the same name as LLVM and Apple so that we correctly |
| | 31 | // mark the images as instrumented when traversing them when TSAN dylib is |
| | 32 | // initialized. |
| | 33 | .macos => "clang_rt.tsan_osx_dynamic", |
| | 34 | .ios => switch (target.abi) { |
| | 35 | .simulator => "clang_rt.tsan_iossim_dynamic", |
| | 36 | else => "clang_rt.tsan_ios_dynamic", |
| | 37 | }, |
| | 38 | else => "tsan", |
| | 39 | }; |
| | 40 | const link_mode: std.builtin.LinkMode = if (target.isDarwin()) .dynamic else .static; |
| | 41 | const output_mode = .Lib; |
| 32 | const basename = try std.zig.binNameAlloc(arena, .{ | 42 | const basename = try std.zig.binNameAlloc(arena, .{ |
| 33 | .root_name = root_name, | 43 | .root_name = root_name, |
| 34 | .target = target, | 44 | .target = target, |
| ... | @@ -43,6 +53,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -43,6 +53,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 43 | | 53 | |
| 44 | const optimize_mode = comp.compilerRtOptMode(); | 54 | const optimize_mode = comp.compilerRtOptMode(); |
| 45 | const strip = comp.compilerRtStrip(); | 55 | const strip = comp.compilerRtStrip(); |
| | 56 | const link_libcpp = target.isDarwin(); |
| 46 | | 57 | |
| 47 | const config = Compilation.Config.resolve(.{ | 58 | const config = Compilation.Config.resolve(.{ |
| 48 | .output_mode = output_mode, | 59 | .output_mode = output_mode, |
| ... | @@ -54,6 +65,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -54,6 +65,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 54 | .root_optimize_mode = optimize_mode, | 65 | .root_optimize_mode = optimize_mode, |
| 55 | .root_strip = strip, | 66 | .root_strip = strip, |
| 56 | .link_libc = true, | 67 | .link_libc = true, |
| | 68 | .link_libcpp = link_libcpp, |
| 57 | }) catch |err| { | 69 | }) catch |err| { |
| 58 | comp.setMiscFailure( | 70 | comp.setMiscFailure( |
| 59 | .libtsan, | 71 | .libtsan, |
| ... | @@ -272,6 +284,12 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -272,6 +284,12 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 272 | }); | 284 | }); |
| 273 | } | 285 | } |
| 274 | | 286 | |
| | 287 | const skip_linker_dependencies = !target.isDarwin(); |
| | 288 | const linker_allow_shlib_undefined = target.isDarwin(); |
| | 289 | const install_name = if (target.isDarwin()) |
| | 290 | try std.fmt.allocPrintZ(arena, "@rpath/{s}", .{basename}) |
| | 291 | else |
| | 292 | null; |
| 275 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ | 293 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 276 | .local_cache_directory = comp.global_cache_directory, | 294 | .local_cache_directory = comp.global_cache_directory, |
| 277 | .global_cache_directory = comp.global_cache_directory, | 295 | .global_cache_directory = comp.global_cache_directory, |
| ... | @@ -294,7 +312,9 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -294,7 +312,9 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 294 | .verbose_cimport = comp.verbose_cimport, | 312 | .verbose_cimport = comp.verbose_cimport, |
| 295 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, | 313 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 296 | .clang_passthrough_mode = comp.clang_passthrough_mode, | 314 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 297 | .skip_linker_dependencies = true, | 315 | .skip_linker_dependencies = skip_linker_dependencies, |
| | 316 | .linker_allow_shlib_undefined = linker_allow_shlib_undefined, |
| | 317 | .install_name = install_name, |
| 298 | }) catch |err| { | 318 | }) catch |err| { |
| 299 | comp.setMiscFailure( | 319 | comp.setMiscFailure( |
| 300 | .libtsan, | 320 | .libtsan, |
| ... | @@ -317,8 +337,13 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -317,8 +337,13 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 317 | }, | 337 | }, |
| 318 | }; | 338 | }; |
| 319 | | 339 | |
| 320 | assert(comp.tsan_static_lib == null); | 340 | assert(comp.tsan_static_lib == null and comp.tsan_dynamic_lib == null); |
| 321 | comp.tsan_static_lib = try sub_compilation.toCrtFile(); | 341 | |
| | 342 | if (target.isDarwin()) { |
| | 343 | comp.tsan_dynamic_lib = try sub_compilation.toCrtFile(); |
| | 344 | } else { |
| | 345 | comp.tsan_static_lib = try sub_compilation.toCrtFile(); |
| | 346 | } |
| 322 | } | 347 | } |
| 323 | | 348 | |
| 324 | const tsan_sources = [_][]const u8{ | 349 | const tsan_sources = [_][]const u8{ |