| ... | ... | @@ -25,10 +25,20 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 25 | 25 | defer arena_allocator.deinit(); |
| 26 | 26 | const arena = arena_allocator.allocator(); |
| 27 | 27 | |
| 28 | | const root_name = "tsan"; |
| 29 | | const output_mode = .Lib; |
| 30 | | const link_mode = .static; |
| 31 | 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 | 42 | const basename = try std.zig.binNameAlloc(arena, .{ |
| 33 | 43 | .root_name = root_name, |
| 34 | 44 | .target = target, |
| ... | ... | @@ -43,6 +53,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 43 | 53 | |
| 44 | 54 | const optimize_mode = comp.compilerRtOptMode(); |
| 45 | 55 | const strip = comp.compilerRtStrip(); |
| 56 | const link_libcpp = target.isDarwin(); |
| 46 | 57 | |
| 47 | 58 | const config = Compilation.Config.resolve(.{ |
| 48 | 59 | .output_mode = output_mode, |
| ... | ... | @@ -54,6 +65,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 54 | 65 | .root_optimize_mode = optimize_mode, |
| 55 | 66 | .root_strip = strip, |
| 56 | 67 | .link_libc = true, |
| 68 | .link_libcpp = link_libcpp, |
| 57 | 69 | }) catch |err| { |
| 58 | 70 | comp.setMiscFailure( |
| 59 | 71 | .libtsan, |
| ... | ... | @@ -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 | 293 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 276 | 294 | .local_cache_directory = comp.global_cache_directory, |
| 277 | 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 | 312 | .verbose_cimport = comp.verbose_cimport, |
| 295 | 313 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 296 | 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 | 318 | }) catch |err| { |
| 299 | 319 | comp.setMiscFailure( |
| 300 | 320 | .libtsan, |
| ... | ... | @@ -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); |
| 321 | | comp.tsan_static_lib = try sub_compilation.toCrtFile(); |
| 340 | assert(comp.tsan_static_lib == null and comp.tsan_dynamic_lib == null); |
| 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 | 349 | const tsan_sources = [_][]const u8{ |