╭ libcxx.zig ───────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
1 const std = @import("std"); 2 const path = std.fs.path; 3 const assert = std.debug.assert; 4 5 const target_util = @import("../target.zig"); 6 const Compilation = @import("../Compilation.zig"); 7 const build_options = @import("build_options"); 8 const trace = @import("../tracy.zig").trace; 9 const Module = @import("../Module.zig"); 10 11 const libcxxabi_files = [_][]const u8{ 12 "src/cxa_aux_runtime.cpp", 13 "src/cxa_default_handlers.cpp", 14 "src/cxa_demangle.cpp", 15 "src/cxa_exception_storage.cpp", 16 "src/cxa_guard.cpp", 17 "src/cxa_handlers.cpp", 18 "src/cxa_vector.cpp", 19 "src/cxa_virtual.cpp", 20 21 "src/stdlib_exception.cpp", 22 "src/stdlib_stdexcept.cpp", 23 "src/stdlib_typeinfo.cpp", 24 "src/stdlib_new_delete.cpp", 25 26 "src/abort_message.cpp", 27 "src/fallback_malloc.cpp", 28 "src/private_typeinfo.cpp", 29 30 "src/cxa_exception.cpp", 31 "src/cxa_personality.cpp", 32 33 "src/cxa_noexception.cpp", 34 35 "src/cxa_thread_atexit.cpp", 36 }; 37 38 const libcxx_base_files = [_][]const u8{ 39 "src/algorithm.cpp", 40 "src/any.cpp", 41 "src/bind.cpp", 42 "src/call_once.cpp", 43 "src/charconv.cpp", 44 "src/chrono.cpp", 45 "src/error_category.cpp", 46 "src/exception.cpp", 47 "src/expected.cpp", 48 "src/filesystem/directory_entry.cpp", 49 "src/filesystem/directory_iterator.cpp", 50 "src/filesystem/filesystem_clock.cpp", 51 "src/filesystem/filesystem_error.cpp", 52 // omit int128_builtins.cpp because it provides __muloti4 which is already provided 53 // by compiler_rt and crashes on Windows x86_64: https://github.com/ziglang/zig/issues/10719 54 //"src/filesystem/int128_builtins.cpp", 55 "src/filesystem/operations.cpp", 56 "src/filesystem/path.cpp", 57 "src/fstream.cpp", 58 "src/functional.cpp", 59 "src/hash.cpp", 60 "src/ios.cpp", 61 "src/ios.instantiations.cpp", 62 "src/iostream.cpp", 63 "src/locale.cpp", 64 "src/memory.cpp", 65 "src/memory_resource.cpp", 66 "src/new.cpp", 67 "src/new_handler.cpp", 68 "src/new_helpers.cpp", 69 "src/optional.cpp", 70 "src/ostream.cpp", 71 "src/print.cpp", 72 //"src/pstl/libdispatch.cpp", 73 "src/random.cpp", 74 "src/random_shuffle.cpp", 75 "src/regex.cpp", 76 "src/ryu/d2fixed.cpp", 77 "src/ryu/d2s.cpp", 78 "src/ryu/f2s.cpp", 79 "src/stdexcept.cpp", 80 "src/string.cpp", 81 "src/strstream.cpp", 82 "src/support/win32/locale_win32.cpp", 83 "src/support/win32/support.cpp", 84 "src/system_error.cpp", 85 "src/typeinfo.cpp", 86 "src/valarray.cpp", 87 "src/variant.cpp", 88 "src/vector.cpp", 89 "src/verbose_abort.cpp", 90 }; 91 92 const libcxx_thread_files = [_][]const u8{ 93 "src/atomic.cpp", 94 "src/barrier.cpp", 95 "src/condition_variable.cpp", 96 "src/condition_variable_destructor.cpp", 97 "src/future.cpp", 98 "src/mutex.cpp", 99 "src/mutex_destructor.cpp", 100 "src/shared_mutex.cpp", 101 "src/support/win32/thread_win32.cpp", 102 "src/thread.cpp", 103 }; 104 105 pub const BuildError = error{ 106 OutOfMemory, 107 AlreadyReported, 108 ZigCompilerNotBuiltWithLLVMExtensions, 109 } || std.Io.Cancelable; 110 111 pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void { 112 if (!build_options.have_llvm) { 113 return error.ZigCompilerNotBuiltWithLLVMExtensions; 114 } 115 116 const tracy = trace(@src()); 117 defer tracy.end(); 118 119 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); 120 defer arena_allocator.deinit(); 121 const arena = arena_allocator.allocator(); 122 123 const io = comp.io; 124 const root_name = "c++"; 125 const output_mode = .Lib; 126 const link_mode = .static; 127 const target = &comp.root_mod.resolved_target.result; 128 129 const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" }); 130 const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" }); 131 const cxx_src_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "src" }); 132 const cxx_libc_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "libc" }); 133 134 const optimize_mode = comp.compilerRtOptMode(); 135 const strip = comp.compilerRtStrip(); 136 137 const config = Compilation.Config.resolve(.{ 138 .output_mode = output_mode, 139 .link_mode = link_mode, 140 .resolved_target = comp.root_mod.resolved_target, 141 .is_test = false, 142 .have_zcu = false, 143 .emit_bin = true, 144 .root_optimize_mode = optimize_mode, 145 .root_strip = strip, 146 .link_libc = true, 147 .lto = comp.config.lto, 148 .any_sanitize_thread = comp.config.any_sanitize_thread, 149 }) catch |err| { 150 comp.lockAndSetMiscFailure( 151 .libcxx, 152 "unable to build libc++: resolving configuration failed: {s}", 153 .{@errorName(err)}, 154 ); 155 return error.AlreadyReported; 156 }; 157 158 const root_mod = Module.create(arena, .{ 159 .paths = .{ 160 .root = .zig_lib_root, 161 .root_src_path = "", 162 }, 163 .fully_qualified_name = "root", 164 .inherited = .{ 165 .resolved_target = comp.root_mod.resolved_target, 166 .strip = strip, 167 .stack_check = false, 168 .stack_protector = 0, 169 .sanitize_c = .off, 170 .sanitize_thread = comp.config.any_sanitize_thread, 171 .red_zone = comp.root_mod.red_zone, 172 .omit_frame_pointer = comp.root_mod.omit_frame_pointer, 173 .valgrind = false, 174 .optimize_mode = optimize_mode, 175 .pic = if (target_util.supports_fpic(target)) true else null, 176 .code_model = comp.root_mod.code_model, 177 }, 178 .global = config, 179 .cc_argv = &.{}, 180 .parent = null, 181 }) catch |err| { 182 comp.lockAndSetMiscFailure( 183 .libcxx, 184 "unable to build libc++: creating module failed: {s}", 185 .{@errorName(err)}, 186 ); 187 return error.AlreadyReported; 188 }; 189 190 const libcxx_files = if (comp.config.any_non_single_threaded) 191 &(libcxx_base_files ++ libcxx_thread_files) 192 else 193 &libcxx_base_files; 194 195 var c_source_files = try std.array_list.Managed(Compilation.CSourceFile).initCapacity(arena, libcxx_files.len); 196 197 for (libcxx_files) |cxx_src| { 198 // These don't compile on WASI due to e.g. `fchmod` usage. 199 if (std.mem.startsWith(u8, cxx_src, "src/filesystem/") and target.os.tag == .wasi) 200 continue; 201 if (std.mem.startsWith(u8, cxx_src, "src/support/win32/") and target.os.tag != .windows) 202 continue; 203 204 var cflags = std.array_list.Managed([]const u8).init(arena); 205 206 try addCxxArgs(comp, arena, &cflags); 207 208 try cflags.append("-w"); // Disable all warnings. 209 try cflags.append("-DNDEBUG"); 210 try cflags.append("-DLIBC_NAMESPACE=__llvm_libc_common_utils"); 211 try cflags.append("-D_LIBCPP_BUILDING_LIBRARY"); 212 try cflags.append("-DLIBCXX_BUILDING_LIBCXXABI"); 213 try cflags.append("-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER"); 214 215 if (target.os.tag == .wasi) { 216 try cflags.append("-fno-exceptions"); 217 } 218 219 try cflags.append("-fvisibility=hidden"); 220 try cflags.append("-fvisibility-inlines-hidden"); 221 222 try cflags.append("-faligned-allocation"); 223 224 try cflags.append("-nostdinc++"); 225 try cflags.append("-std=c++23"); 226 227 // These depend on only the zig lib directory file path, which is 228 // purposefully either in the cache or not in the cache. The decision 229 // should not be overridden here. 230 var cache_exempt_flags = std.array_list.Managed([]const u8).init(arena); 231 232 try cache_exempt_flags.append("-I"); 233 try cache_exempt_flags.append(cxx_include_path); 234 235 try cache_exempt_flags.append("-I"); 236 try cache_exempt_flags.append(cxxabi_include_path); 237 238 try cache_exempt_flags.append("-I"); 239 try cache_exempt_flags.append(cxx_src_include_path); 240 241 try cache_exempt_flags.append("-I"); 242 try cache_exempt_flags.append(cxx_libc_include_path); 243 244 c_source_files.appendAssumeCapacity(.{ 245 .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", cxx_src }), 246 .extra_flags = cflags.items, 247 .cache_exempt_flags = cache_exempt_flags.items, 248 .owner = root_mod, 249 }); 250 } 251 252 const misc_task: Compilation.MiscTask = .libcxx; 253 254 var sub_create_diag: Compilation.CreateDiagnostic = undefined; 255 const sub_compilation = Compilation.create(comp.gpa, arena, io, &sub_create_diag, .{ 256 .thread_limit = comp.thread_limit, 257 .dirs = comp.dirs.withoutLocalCache(), 258 .self_exe_path = comp.self_exe_path, 259 .cache_mode = .whole, 260 .config = config, 261 .root_mod = root_mod, 262 .root_name = root_name, 263 .libc_installation = comp.libc_installation, 264 .emit_bin = .yes_cache, 265 .function_sections = true, 266 .data_sections = true, 267 .c_source_files = c_source_files.items, 268 .verbose_cc = comp.verbose_cc, 269 .verbose_link = comp.verbose_link, 270 .verbose_air = comp.verbose_air, 271 .verbose_llvm_ir = comp.verbose_llvm_ir, 272 .verbose_llvm_bc = comp.verbose_llvm_bc, 273 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, 274 .clang_passthrough_mode = comp.clang_passthrough_mode, 275 .skip_linker_dependencies = true, 276 .environ_map = comp.environ_map, 277 }) catch |err| { 278 switch (err) { 279 else => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++: create compilation failed: {t}", .{err}), 280 error.CreateFail => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++: create compilation failed: {f}", .{sub_create_diag}), 281 } 282 return error.AlreadyReported; 283 }; 284 defer sub_compilation.destroy(); 285 286 comp.updateSubCompilation(sub_compilation, misc_task, prog_node) catch |err| switch (err) { 287 error.AlreadyReported => |e| return e, 288 else => |e| { 289 comp.lockAndSetMiscFailure(misc_task, "unable to build libc++: compilation failed: {t}", .{e}); 290 return error.AlreadyReported; 291 }, 292 }; 293 294 assert(comp.libcxx_static_lib == null); 295 const crt_file = try sub_compilation.toCrtFile(); 296 comp.libcxx_static_lib = crt_file; 297 try comp.queuePrelinkTaskMode(crt_file.full_object_path, false, &config); 298 } 299 300 pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void { 301 if (!build_options.have_llvm) { 302 return error.ZigCompilerNotBuiltWithLLVMExtensions; 303 } 304 305 const tracy = trace(@src()); 306 defer tracy.end(); 307 308 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); 309 defer arena_allocator.deinit(); 310 const arena = arena_allocator.allocator(); 311 312 const io = comp.io; 313 const root_name = "c++abi"; 314 const output_mode = .Lib; 315 const link_mode = .static; 316 const target = &comp.root_mod.resolved_target.result; 317 318 const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" }); 319 const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" }); 320 const cxx_src_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "src" }); 321 322 const optimize_mode = comp.compilerRtOptMode(); 323 const strip = comp.compilerRtStrip(); 324 // See the `-fno-exceptions` logic for WASI. 325 // The old 32-bit x86 variant of SEH doesn't use tables. 326 const unwind_tables: std.lang.UnwindTables = 327 if (target.cpu.arch == .x86 and target.os.tag == .windows) .none else .async; 328 329 const config = Compilation.Config.resolve(.{ 330 .output_mode = output_mode, 331 .link_mode = link_mode, 332 .resolved_target = comp.root_mod.resolved_target, 333 .is_test = false, 334 .have_zcu = false, 335 .emit_bin = true, 336 .root_optimize_mode = optimize_mode, 337 .root_strip = strip, 338 .link_libc = true, 339 .any_unwind_tables = unwind_tables != .none, 340 .lto = comp.config.lto, 341 .any_sanitize_thread = comp.config.any_sanitize_thread, 342 }) catch |err| { 343 comp.lockAndSetMiscFailure( 344 .libcxxabi, 345 "unable to build libc++abi: resolving configuration failed: {s}", 346 .{@errorName(err)}, 347 ); 348 return error.AlreadyReported; 349 }; 350 351 const root_mod = Module.create(arena, .{ 352 .paths = .{ 353 .root = .zig_lib_root, 354 .root_src_path = "", 355 }, 356 .fully_qualified_name = "root", 357 .inherited = .{ 358 .resolved_target = comp.root_mod.resolved_target, 359 .strip = strip, 360 .stack_check = false, 361 .stack_protector = 0, 362 .sanitize_c = .off, 363 .sanitize_thread = comp.config.any_sanitize_thread, 364 .red_zone = comp.root_mod.red_zone, 365 .omit_frame_pointer = comp.root_mod.omit_frame_pointer, 366 .valgrind = false, 367 .optimize_mode = optimize_mode, 368 .unwind_tables = unwind_tables, 369 .pic = if (target_util.supports_fpic(target)) true else null, 370 .code_model = comp.root_mod.code_model, 371 }, 372 .global = config, 373 .cc_argv = &.{}, 374 .parent = null, 375 }) catch |err| { 376 comp.lockAndSetMiscFailure( 377 .libcxxabi, 378 "unable to build libc++abi: creating module failed: {s}", 379 .{@errorName(err)}, 380 ); 381 return error.AlreadyReported; 382 }; 383 384 var c_source_files = try std.array_list.Managed(Compilation.CSourceFile).initCapacity(arena, libcxxabi_files.len); 385 386 for (libcxxabi_files) |cxxabi_src| { 387 if (!comp.config.any_non_single_threaded and std.mem.eql(u8, cxxabi_src, "src/cxa_thread_atexit.cpp")) 388 continue; 389 if (target.os.tag == .wasi and 390 (std.mem.eql(u8, cxxabi_src, "src/cxa_exception.cpp") or std.mem.eql(u8, cxxabi_src, "src/cxa_personality.cpp"))) 391 continue; 392 if (target.os.tag != .wasi and std.mem.eql(u8, cxxabi_src, "src/cxa_noexception.cpp")) 393 continue; 394 395 var cflags = std.array_list.Managed([]const u8).init(arena); 396 397 try addCxxArgs(comp, arena, &cflags); 398 399 try cflags.append("-w"); // Disable all warnings. 400 try cflags.append("-DNDEBUG"); 401 try cflags.append("-D_LIBCPP_BUILDING_LIBRARY"); 402 try cflags.append("-D_LIBCXXABI_BUILDING_LIBRARY"); 403 if (!comp.config.any_non_single_threaded) { 404 try cflags.append("-D_LIBCXXABI_HAS_NO_THREADS"); 405 } 406 if (target.abi.isGnu()) { 407 if (target.os.tag != .linux or !(target.os.versionRange().gnuLibCVersion().?.order(.{ .major = 2, .minor = 18, .patch = 0 }) == .lt)) 408 try cflags.append("-DHAVE___CXA_THREAD_ATEXIT_IMPL"); 409 } 410 411 if (target.os.tag == .wasi) { 412 try cflags.append("-fno-exceptions"); 413 } 414 415 try cflags.append("-fvisibility=hidden"); 416 try cflags.append("-fvisibility-inlines-hidden"); 417 418 try cflags.append("-nostdinc++"); 419 try cflags.append("-fstrict-aliasing"); 420 try cflags.append("-std=c++23"); 421 422 // These depend on only the zig lib directory file path, which is 423 // purposefully either in the cache or not in the cache. The decision 424 // should not be overridden here. 425 var cache_exempt_flags = std.array_list.Managed([]const u8).init(arena); 426 427 try cache_exempt_flags.append("-I"); 428 try cache_exempt_flags.append(cxxabi_include_path); 429 430 try cache_exempt_flags.append("-I"); 431 try cache_exempt_flags.append(cxx_include_path); 432 433 try cache_exempt_flags.append("-I"); 434 try cache_exempt_flags.append(cxx_src_include_path); 435 436 c_source_files.appendAssumeCapacity(.{ 437 .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", cxxabi_src }), 438 .extra_flags = cflags.items, 439 .cache_exempt_flags = cache_exempt_flags.items, 440 .owner = root_mod, 441 }); 442 } 443 444 const misc_task: Compilation.MiscTask = .libcxxabi; 445 446 var sub_create_diag: Compilation.CreateDiagnostic = undefined; 447 const sub_compilation = Compilation.create(comp.gpa, arena, io, &sub_create_diag, .{ 448 .thread_limit = comp.thread_limit, 449 .dirs = comp.dirs.withoutLocalCache(), 450 .self_exe_path = comp.self_exe_path, 451 .cache_mode = .whole, 452 .config = config, 453 .root_mod = root_mod, 454 .root_name = root_name, 455 .libc_installation = comp.libc_installation, 456 .emit_bin = .yes_cache, 457 .function_sections = true, 458 .data_sections = true, 459 .c_source_files = c_source_files.items, 460 .verbose_cc = comp.verbose_cc, 461 .verbose_link = comp.verbose_link, 462 .verbose_air = comp.verbose_air, 463 .verbose_llvm_ir = comp.verbose_llvm_ir, 464 .verbose_llvm_bc = comp.verbose_llvm_bc, 465 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, 466 .clang_passthrough_mode = comp.clang_passthrough_mode, 467 .skip_linker_dependencies = true, 468 .environ_map = comp.environ_map, 469 }) catch |err| { 470 switch (err) { 471 else => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++abi: create compilation failed: {t}", .{err}), 472 error.CreateFail => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++abi: create compilation failed: {f}", .{sub_create_diag}), 473 } 474 return error.AlreadyReported; 475 }; 476 defer sub_compilation.destroy(); 477 478 comp.updateSubCompilation(sub_compilation, misc_task, prog_node) catch |err| switch (err) { 479 error.AlreadyReported => |e| return e, 480 else => |e| { 481 comp.lockAndSetMiscFailure( 482 .libcxxabi, 483 "unable to build libc++abi: compilation failed: {s}", 484 .{@errorName(e)}, 485 ); 486 return error.AlreadyReported; 487 }, 488 }; 489 490 assert(comp.libcxxabi_static_lib == null); 491 const crt_file = try sub_compilation.toCrtFile(); 492 comp.libcxxabi_static_lib = crt_file; 493 try comp.queuePrelinkTaskMode(crt_file.full_object_path, false, &config); 494 } 495 496 pub fn addCxxArgs( 497 comp: *const Compilation, 498 arena: std.mem.Allocator, 499 cflags: *std.array_list.Managed([]const u8), 500 ) error{OutOfMemory}!void { 501 const target = comp.getTarget(); 502 const optimize_mode = comp.compilerRtOptMode(); 503 504 const abi_version: u2 = if (target.os.tag == .emscripten) 2 else 1; 505 try cflags.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{ 506 abi_version, 507 })); 508 try cflags.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{ 509 abi_version, 510 })); 511 try cflags.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_HAS_THREADS={d}", .{ 512 @as(u1, if (comp.config.any_non_single_threaded) 1 else 0), 513 })); 514 try cflags.append("-D_LIBCPP_HAS_MONOTONIC_CLOCK"); 515 try cflags.append("-D_LIBCPP_HAS_TERMINAL"); 516 try cflags.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_HAS_MUSL_LIBC={d}", .{ 517 @as(u1, if (target.abi.isMusl()) 1 else 0), 518 })); 519 try cflags.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); 520 try cflags.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); 521 try cflags.append("-D_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS=0"); 522 try cflags.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_HAS_FILESYSTEM={d}", .{ 523 @as(u1, if (target.os.tag == .wasi) 0 else 1), 524 })); 525 try cflags.append("-D_LIBCPP_HAS_RANDOM_DEVICE"); 526 try cflags.append("-D_LIBCPP_HAS_LOCALIZATION"); 527 try cflags.append("-D_LIBCPP_HAS_UNICODE"); 528 try cflags.append("-D_LIBCPP_HAS_WIDE_CHARACTERS"); 529 try cflags.append("-D_LIBCPP_HAS_NO_STD_MODULES"); 530 if (target.os.tag == .linux) { 531 try cflags.append("-D_LIBCPP_HAS_TIME_ZONE_DATABASE"); 532 } 533 // See libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h 534 // for potentially enabling some fancy features here, which would 535 // require corresponding changes in libcxx.zig, as well as 536 // Compilation.addCCArgs. This option makes it use serial backend which 537 // is simple and works everywhere. 538 try cflags.append("-D_LIBCPP_PSTL_BACKEND_SERIAL"); 539 switch (optimize_mode) { 540 .debug => { 541 try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG"); 542 try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE"); 543 }, 544 .fast, .small => { 545 try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE"); 546 try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_IGNORE"); 547 }, 548 .safe => { 549 try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST"); 550 try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE"); 551 }, 552 } 553 if (target.isGnuLibC()) { 554 // glibc 2.16 introduced aligned_alloc 555 if (target.os.versionRange().gnuLibCVersion().?.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) { 556 try cflags.append("-D_LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION=0"); 557 } 558 } 559 } 560