| ... | ... | @@ -4687,19 +4687,19 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 4687 | 4687 | |
| 4688 | 4688 | try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang" }); |
| 4689 | 4689 | // if "ext" is explicit, add "-x <lang>". Otherwise let clang do its thing. |
| 4690 | | if (c_object.src.ext != null) { |
| 4690 | if (c_object.src.ext != null or ext.clangNeedsLanguageOverride()) { |
| 4691 | 4691 | try argv.appendSlice(&[_][]const u8{ "-x", switch (ext) { |
| 4692 | 4692 | .assembly => "assembler", |
| 4693 | 4693 | .assembly_with_cpp => "assembler-with-cpp", |
| 4694 | 4694 | .c => "c", |
| 4695 | | .cpp => "c++", |
| 4696 | 4695 | .h => "c-header", |
| 4696 | .cpp => "c++", |
| 4697 | 4697 | .hpp => "c++-header", |
| 4698 | .m => "objective-c", |
| 4698 | 4699 | .hm => "objective-c-header", |
| 4700 | .mm => "objective-c++", |
| 4699 | 4701 | .hmm => "objective-c++-header", |
| 4700 | 4702 | .cu => "cuda", |
| 4701 | | .m => "objective-c", |
| 4702 | | .mm => "objective-c++", |
| 4703 | 4703 | else => fatal("language '{s}' is unsupported in this context", .{@tagName(ext)}), |
| 4704 | 4704 | } }); |
| 4705 | 4705 | } |
| ... | ... | @@ -5273,10 +5273,6 @@ pub fn addCCArgs( |
| 5273 | 5273 | // can be disabled. |
| 5274 | 5274 | try argv.append("--no-default-config"); |
| 5275 | 5275 | |
| 5276 | | if (ext == .cpp) { |
| 5277 | | try argv.append("-nostdinc++"); |
| 5278 | | } |
| 5279 | | |
| 5280 | 5276 | // We don't ever put `-fcolor-diagnostics` or `-fno-color-diagnostics` because in passthrough mode |
| 5281 | 5277 | // we want Clang to infer it, and in normal mode we always want it off, which will be true since |
| 5282 | 5278 | // clang will detect stderr as a pipe rather than a terminal. |
| ... | ... | @@ -5285,117 +5281,312 @@ pub fn addCCArgs( |
| 5285 | 5281 | try argv.append("-fno-caret-diagnostics"); |
| 5286 | 5282 | } |
| 5287 | 5283 | |
| 5288 | | try argv.append(if (comp.function_sections) "-ffunction-sections" else "-fno-function-sections"); |
| 5289 | | try argv.append(if (comp.data_sections) "-fdata-sections" else "-fno-data-sections"); |
| 5284 | // We never want clang to invoke the system assembler for anything. So we would want |
| 5285 | // this option always enabled. However, it only matters for some targets. To avoid |
| 5286 | // "unused parameter" warnings, and to keep CLI spam to a minimum, we only put this |
| 5287 | // flag on the command line if it is necessary. |
| 5288 | if (target_util.clangMightShellOutForAssembly(target)) { |
| 5289 | try argv.append("-integrated-as"); |
| 5290 | } |
| 5290 | 5291 | |
| 5291 | | try argv.append(if (mod.no_builtin) "-fno-builtin" else "-fbuiltin"); |
| 5292 | const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target); |
| 5293 | try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple }); |
| 5292 | 5294 | |
| 5293 | | if (comp.config.link_libcpp) { |
| 5294 | | const libcxx_include_path = try std.fs.path.join(arena, &[_][]const u8{ |
| 5295 | | comp.zig_lib_directory.path.?, "libcxx", "include", |
| 5296 | | }); |
| 5297 | | const libcxxabi_include_path = try std.fs.path.join(arena, &[_][]const u8{ |
| 5298 | | comp.zig_lib_directory.path.?, "libcxxabi", "include", |
| 5299 | | }); |
| 5295 | if (target.cpu.arch.isArm()) { |
| 5296 | try argv.append(if (target.cpu.arch.isThumb()) "-mthumb" else "-mno-thumb"); |
| 5297 | } |
| 5300 | 5298 | |
| 5301 | | try argv.append("-isystem"); |
| 5302 | | try argv.append(libcxx_include_path); |
| 5299 | if (target_util.llvmMachineAbi(target)) |mabi| { |
| 5300 | try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi})); |
| 5301 | } |
| 5303 | 5302 | |
| 5304 | | try argv.append("-isystem"); |
| 5305 | | try argv.append(libcxxabi_include_path); |
| 5303 | // We might want to support -mfloat-abi=softfp for Arm and CSKY here in the future. |
| 5304 | if (target_util.clangSupportsFloatAbiArg(target)) { |
| 5305 | const fabi = @tagName(target.floatAbi()); |
| 5306 | 5306 | |
| 5307 | | if (target.abi.isMusl()) { |
| 5308 | | try argv.append("-D_LIBCPP_HAS_MUSL_LIBC"); |
| 5309 | | } |
| 5310 | | try argv.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); |
| 5311 | | try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS"); |
| 5312 | | try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); |
| 5307 | try argv.append(switch (target.cpu.arch) { |
| 5308 | // For whatever reason, Clang doesn't support `-mfloat-abi` for s390x. |
| 5309 | .s390x => try std.fmt.allocPrint(arena, "-m{s}-float", .{fabi}), |
| 5310 | else => try std.fmt.allocPrint(arena, "-mfloat-abi={s}", .{fabi}), |
| 5311 | }); |
| 5312 | } |
| 5313 | 5313 | |
| 5314 | | if (!comp.config.any_non_single_threaded) { |
| 5315 | | try argv.append("-D_LIBCPP_HAS_NO_THREADS"); |
| 5316 | | } |
| 5314 | if (target_util.supports_fpic(target)) { |
| 5315 | try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC"); |
| 5316 | } |
| 5317 | 5317 | |
| 5318 | | // See the comment in libcxx.zig for more details about this. |
| 5319 | | try argv.append("-D_LIBCPP_PSTL_BACKEND_SERIAL"); |
| 5318 | if (comp.mingw_unicode_entry_point) { |
| 5319 | try argv.append("-municode"); |
| 5320 | } |
| 5320 | 5321 | |
| 5321 | | try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{ |
| 5322 | | @intFromEnum(comp.libcxx_abi_version), |
| 5323 | | })); |
| 5324 | | try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{ |
| 5325 | | @intFromEnum(comp.libcxx_abi_version), |
| 5326 | | })); |
| 5322 | if (mod.code_model != .default) { |
| 5323 | try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(mod.code_model)})); |
| 5324 | } |
| 5327 | 5325 | |
| 5328 | | try argv.append(libcxx.hardeningModeFlag(mod.optimize_mode)); |
| 5326 | try argv.ensureUnusedCapacity(2); |
| 5327 | switch (comp.config.debug_format) { |
| 5328 | .strip => {}, |
| 5329 | .code_view => { |
| 5330 | // -g is required here because -gcodeview doesn't trigger debug info |
| 5331 | // generation, it only changes the type of information generated. |
| 5332 | argv.appendSliceAssumeCapacity(&.{ "-g", "-gcodeview" }); |
| 5333 | }, |
| 5334 | .dwarf => |f| { |
| 5335 | argv.appendAssumeCapacity("-gdwarf-4"); |
| 5336 | switch (f) { |
| 5337 | .@"32" => argv.appendAssumeCapacity("-gdwarf32"), |
| 5338 | .@"64" => argv.appendAssumeCapacity("-gdwarf64"), |
| 5339 | } |
| 5340 | }, |
| 5329 | 5341 | } |
| 5330 | 5342 | |
| 5331 | | if (comp.config.link_libunwind) { |
| 5332 | | const libunwind_include_path = try std.fs.path.join(arena, &[_][]const u8{ |
| 5333 | | comp.zig_lib_directory.path.?, "libunwind", "include", |
| 5334 | | }); |
| 5343 | if (comp.config.lto) { |
| 5344 | try argv.append("-flto"); |
| 5345 | } |
| 5335 | 5346 | |
| 5336 | | try argv.append("-isystem"); |
| 5337 | | try argv.append(libunwind_include_path); |
| 5347 | // This only works for preprocessed files. Guarded by `FileExt.clangSupportsDepFile`. |
| 5348 | if (out_dep_path) |p| { |
| 5349 | try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p }); |
| 5338 | 5350 | } |
| 5339 | 5351 | |
| 5340 | | if (comp.config.link_libc) { |
| 5341 | | if (target.isGnuLibC()) { |
| 5342 | | const target_version = target.os.versionRange().gnuLibCVersion().?; |
| 5343 | | const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{ |
| 5344 | | target_version.minor, |
| 5352 | // Non-preprocessed assembly files don't support these flags. |
| 5353 | if (ext != .assembly) { |
| 5354 | try argv.append(if (target.os.tag == .freestanding) "-ffreestanding" else "-fhosted"); |
| 5355 | |
| 5356 | if (target_util.clangSupportsNoImplicitFloatArg(target) and target.floatAbi() == .soft) { |
| 5357 | try argv.append("-mno-implicit-float"); |
| 5358 | } |
| 5359 | |
| 5360 | if (target_util.hasRedZone(target)) { |
| 5361 | try argv.append(if (mod.red_zone) "-mred-zone" else "-mno-red-zone"); |
| 5362 | } |
| 5363 | |
| 5364 | try argv.append(if (mod.omit_frame_pointer) "-fomit-frame-pointer" else "-fno-omit-frame-pointer"); |
| 5365 | |
| 5366 | const ssp_buf_size = mod.stack_protector; |
| 5367 | if (ssp_buf_size != 0) { |
| 5368 | try argv.appendSlice(&[_][]const u8{ |
| 5369 | "-fstack-protector-strong", |
| 5370 | "--param", |
| 5371 | try std.fmt.allocPrint(arena, "ssp-buffer-size={d}", .{ssp_buf_size}), |
| 5345 | 5372 | }); |
| 5346 | | try argv.append(glibc_minor_define); |
| 5347 | | } else if (target.isMinGW()) { |
| 5348 | | try argv.append("-D__MSVCRT_VERSION__=0xE00"); // use ucrt |
| 5373 | } else { |
| 5374 | try argv.append("-fno-stack-protector"); |
| 5375 | } |
| 5376 | |
| 5377 | try argv.append(if (mod.no_builtin) "-fno-builtin" else "-fbuiltin"); |
| 5378 | |
| 5379 | try argv.append(if (comp.function_sections) "-ffunction-sections" else "-fno-function-sections"); |
| 5380 | try argv.append(if (comp.data_sections) "-fdata-sections" else "-fno-data-sections"); |
| 5381 | |
| 5382 | switch (mod.unwind_tables) { |
| 5383 | .none => { |
| 5384 | try argv.append("-fno-unwind-tables"); |
| 5385 | try argv.append("-fno-asynchronous-unwind-tables"); |
| 5386 | }, |
| 5387 | .sync => { |
| 5388 | // Need to override Clang's convoluted default logic. |
| 5389 | try argv.append("-fno-asynchronous-unwind-tables"); |
| 5390 | try argv.append("-funwind-tables"); |
| 5391 | }, |
| 5392 | .@"async" => try argv.append("-fasynchronous-unwind-tables"), |
| 5393 | } |
| 5394 | |
| 5395 | try argv.append("-nostdinc"); |
| 5396 | |
| 5397 | if (ext == .cpp or ext == .hpp) { |
| 5398 | try argv.append("-nostdinc++"); |
| 5399 | } |
| 5400 | |
| 5401 | // LLVM IR files don't support these flags. |
| 5402 | if (ext != .ll and ext != .bc) { |
| 5403 | // https://github.com/llvm/llvm-project/issues/105972 |
| 5404 | if (target.cpu.arch.isPowerPC() and target.floatAbi() == .soft) { |
| 5405 | try argv.append("-D__NO_FPRS__"); |
| 5406 | try argv.append("-D_SOFT_FLOAT"); |
| 5407 | try argv.append("-D_SOFT_DOUBLE"); |
| 5408 | } |
| 5409 | |
| 5410 | if (comp.config.link_libc) { |
| 5411 | if (target.isGnuLibC()) { |
| 5412 | const target_version = target.os.versionRange().gnuLibCVersion().?; |
| 5413 | const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{ |
| 5414 | target_version.minor, |
| 5415 | }); |
| 5416 | try argv.append(glibc_minor_define); |
| 5417 | } else if (target.isMinGW()) { |
| 5418 | try argv.append("-D__MSVCRT_VERSION__=0xE00"); // use ucrt |
| 5349 | 5419 | |
| 5350 | | switch (ext) { |
| 5351 | | .c, .cpp, .m, .mm, .h, .hpp, .hm, .hmm, .cu, .rc, .assembly, .assembly_with_cpp => { |
| 5352 | 5420 | const minver: u16 = @truncate(@intFromEnum(target.os.versionRange().windows.min) >> 16); |
| 5353 | 5421 | try argv.append( |
| 5354 | 5422 | try std.fmt.allocPrint(arena, "-D_WIN32_WINNT=0x{x:0>4}", .{minver}), |
| 5355 | 5423 | ); |
| 5356 | | }, |
| 5357 | | else => {}, |
| 5424 | } |
| 5358 | 5425 | } |
| 5359 | | } |
| 5360 | | } |
| 5361 | 5426 | |
| 5362 | | const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target); |
| 5363 | | try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple }); |
| 5427 | if (comp.config.link_libcpp) { |
| 5428 | try argv.append("-isystem"); |
| 5429 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ |
| 5430 | comp.zig_lib_directory.path.?, "libcxx", "include", |
| 5431 | })); |
| 5364 | 5432 | |
| 5365 | | switch (ext) { |
| 5366 | | .c, .cpp, .m, .mm, .h, .hpp, .hm, .hmm, .cu, .rc => { |
| 5367 | | try argv.appendSlice(&[_][]const u8{ |
| 5368 | | "-nostdinc", |
| 5369 | | "-fno-spell-checking", |
| 5370 | | }); |
| 5371 | | if (comp.config.lto) { |
| 5372 | | try argv.append("-flto"); |
| 5433 | try argv.append("-isystem"); |
| 5434 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ |
| 5435 | comp.zig_lib_directory.path.?, "libcxxabi", "include", |
| 5436 | })); |
| 5437 | |
| 5438 | if (target.abi.isMusl()) { |
| 5439 | try argv.append("-D_LIBCPP_HAS_MUSL_LIBC"); |
| 5440 | } |
| 5441 | |
| 5442 | try argv.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); |
| 5443 | try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS"); |
| 5444 | try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); |
| 5445 | |
| 5446 | if (!comp.config.any_non_single_threaded) { |
| 5447 | try argv.append("-D_LIBCPP_HAS_NO_THREADS"); |
| 5448 | } |
| 5449 | |
| 5450 | // See the comment in libcxx.zig for more details about this. |
| 5451 | try argv.append("-D_LIBCPP_PSTL_BACKEND_SERIAL"); |
| 5452 | |
| 5453 | try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{ |
| 5454 | @intFromEnum(comp.libcxx_abi_version), |
| 5455 | })); |
| 5456 | try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{ |
| 5457 | @intFromEnum(comp.libcxx_abi_version), |
| 5458 | })); |
| 5459 | |
| 5460 | try argv.append(libcxx.hardeningModeFlag(mod.optimize_mode)); |
| 5461 | } |
| 5462 | |
| 5463 | // According to Rich Felker libc headers are supposed to go before C language headers. |
| 5464 | // However as noted by @dimenus, appending libc headers before compiler headers breaks |
| 5465 | // intrinsics and other compiler specific items. |
| 5466 | try argv.append("-isystem"); |
| 5467 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" })); |
| 5468 | |
| 5469 | try argv.ensureUnusedCapacity(comp.libc_include_dir_list.len * 2); |
| 5470 | for (comp.libc_include_dir_list) |include_dir| { |
| 5471 | try argv.append("-isystem"); |
| 5472 | try argv.append(include_dir); |
| 5373 | 5473 | } |
| 5374 | 5474 | |
| 5375 | | if (ext == .mm) { |
| 5376 | | try argv.append("-ObjC++"); |
| 5475 | if (mod.resolved_target.is_native_os and mod.resolved_target.is_native_abi) { |
| 5476 | try argv.ensureUnusedCapacity(comp.native_system_include_paths.len * 2); |
| 5477 | for (comp.native_system_include_paths) |include_path| { |
| 5478 | argv.appendAssumeCapacity("-isystem"); |
| 5479 | argv.appendAssumeCapacity(include_path); |
| 5480 | } |
| 5377 | 5481 | } |
| 5378 | 5482 | |
| 5483 | if (comp.config.link_libunwind) { |
| 5484 | try argv.append("-isystem"); |
| 5485 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ |
| 5486 | comp.zig_lib_directory.path.?, "libunwind", "include", |
| 5487 | })); |
| 5488 | } |
| 5489 | |
| 5490 | try argv.ensureUnusedCapacity(comp.libc_framework_dir_list.len * 2); |
| 5379 | 5491 | for (comp.libc_framework_dir_list) |framework_dir| { |
| 5380 | 5492 | try argv.appendSlice(&.{ "-iframework", framework_dir }); |
| 5381 | 5493 | } |
| 5382 | 5494 | |
| 5495 | try argv.ensureUnusedCapacity(comp.framework_dirs.len * 2); |
| 5383 | 5496 | for (comp.framework_dirs) |framework_dir| { |
| 5384 | 5497 | try argv.appendSlice(&.{ "-F", framework_dir }); |
| 5385 | 5498 | } |
| 5499 | } |
| 5500 | } |
| 5386 | 5501 | |
| 5387 | | // According to Rich Felker libc headers are supposed to go before C language headers. |
| 5388 | | // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics |
| 5389 | | // and other compiler specific items. |
| 5390 | | const c_headers_dir = try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" }); |
| 5391 | | try argv.append("-isystem"); |
| 5392 | | try argv.append(c_headers_dir); |
| 5502 | // Only assembly files support these flags. |
| 5503 | switch (ext) { |
| 5504 | .assembly, |
| 5505 | .assembly_with_cpp, |
| 5506 | => { |
| 5507 | // The Clang assembler does not accept the list of CPU features like the |
| 5508 | // compiler frontend does. Therefore we must hard-code the -m flags for |
| 5509 | // all CPU features here. |
| 5510 | switch (target.cpu.arch) { |
| 5511 | .riscv32, .riscv64 => { |
| 5512 | const RvArchFeat = struct { char: u8, feat: std.Target.riscv.Feature }; |
| 5513 | const letters = [_]RvArchFeat{ |
| 5514 | .{ .char = 'm', .feat = .m }, |
| 5515 | .{ .char = 'a', .feat = .a }, |
| 5516 | .{ .char = 'f', .feat = .f }, |
| 5517 | .{ .char = 'd', .feat = .d }, |
| 5518 | .{ .char = 'c', .feat = .c }, |
| 5519 | }; |
| 5520 | const prefix: []const u8 = if (target.cpu.arch == .riscv64) "rv64" else "rv32"; |
| 5521 | const prefix_len = 4; |
| 5522 | assert(prefix.len == prefix_len); |
| 5523 | var march_buf: [prefix_len + letters.len + 1]u8 = undefined; |
| 5524 | var march_index: usize = prefix_len; |
| 5525 | @memcpy(march_buf[0..prefix.len], prefix); |
| 5393 | 5526 | |
| 5394 | | for (comp.libc_include_dir_list) |include_dir| { |
| 5395 | | try argv.append("-isystem"); |
| 5396 | | try argv.append(include_dir); |
| 5527 | if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) { |
| 5528 | march_buf[march_index] = 'e'; |
| 5529 | } else { |
| 5530 | march_buf[march_index] = 'i'; |
| 5531 | } |
| 5532 | march_index += 1; |
| 5533 | |
| 5534 | for (letters) |letter| { |
| 5535 | if (std.Target.riscv.featureSetHas(target.cpu.features, letter.feat)) { |
| 5536 | march_buf[march_index] = letter.char; |
| 5537 | march_index += 1; |
| 5538 | } |
| 5539 | } |
| 5540 | |
| 5541 | const march_arg = try std.fmt.allocPrint(arena, "-march={s}", .{ |
| 5542 | march_buf[0..march_index], |
| 5543 | }); |
| 5544 | try argv.append(march_arg); |
| 5545 | |
| 5546 | if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) { |
| 5547 | try argv.append("-mrelax"); |
| 5548 | } else { |
| 5549 | try argv.append("-mno-relax"); |
| 5550 | } |
| 5551 | if (std.Target.riscv.featureSetHas(target.cpu.features, .save_restore)) { |
| 5552 | try argv.append("-msave-restore"); |
| 5553 | } else { |
| 5554 | try argv.append("-mno-save-restore"); |
| 5555 | } |
| 5556 | }, |
| 5557 | .mips, .mipsel, .mips64, .mips64el => { |
| 5558 | if (target.cpu.model.llvm_name) |llvm_name| { |
| 5559 | try argv.append(try std.fmt.allocPrint(arena, "-march={s}", .{llvm_name})); |
| 5560 | } |
| 5561 | }, |
| 5562 | else => { |
| 5563 | // TODO |
| 5564 | }, |
| 5397 | 5565 | } |
| 5398 | 5566 | |
| 5567 | if (target_util.clangAssemblerSupportsMcpuArg(target)) { |
| 5568 | if (target.cpu.model.llvm_name) |llvm_name| { |
| 5569 | try argv.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{llvm_name})); |
| 5570 | } |
| 5571 | } |
| 5572 | }, |
| 5573 | else => {}, |
| 5574 | } |
| 5575 | |
| 5576 | // Only C-family files support these flags. |
| 5577 | switch (ext) { |
| 5578 | .c, |
| 5579 | .h, |
| 5580 | .cpp, |
| 5581 | .hpp, |
| 5582 | .m, |
| 5583 | .hm, |
| 5584 | .mm, |
| 5585 | .hmm, |
| 5586 | .cu, |
| 5587 | => { |
| 5588 | try argv.append("-fno-spell-checking"); |
| 5589 | |
| 5399 | 5590 | if (target_util.clangSupportsTargetCpuArg(target)) { |
| 5400 | 5591 | if (target.cpu.model.llvm_name) |llvm_name| { |
| 5401 | 5592 | try argv.appendSlice(&[_][]const u8{ |
| ... | ... | @@ -5421,9 +5612,6 @@ pub fn addCCArgs( |
| 5421 | 5612 | argv.appendAssumeCapacity(arg); |
| 5422 | 5613 | } |
| 5423 | 5614 | } |
| 5424 | | if (mod.code_model != .default) { |
| 5425 | | try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(mod.code_model)})); |
| 5426 | | } |
| 5427 | 5615 | |
| 5428 | 5616 | switch (target.os.tag) { |
| 5429 | 5617 | .windows => { |
| ... | ... | @@ -5506,23 +5694,6 @@ pub fn addCCArgs( |
| 5506 | 5694 | } |
| 5507 | 5695 | } |
| 5508 | 5696 | |
| 5509 | | if (target_util.hasRedZone(target)) { |
| 5510 | | try argv.append(if (mod.red_zone) "-mred-zone" else "-mno-red-zone"); |
| 5511 | | } |
| 5512 | | |
| 5513 | | try argv.append(if (mod.omit_frame_pointer) "-fomit-frame-pointer" else "-fno-omit-frame-pointer"); |
| 5514 | | |
| 5515 | | const ssp_buf_size = mod.stack_protector; |
| 5516 | | if (ssp_buf_size != 0) { |
| 5517 | | try argv.appendSlice(&[_][]const u8{ |
| 5518 | | "-fstack-protector-strong", |
| 5519 | | "--param", |
| 5520 | | try std.fmt.allocPrint(arena, "ssp-buffer-size={d}", .{ssp_buf_size}), |
| 5521 | | }); |
| 5522 | | } else { |
| 5523 | | try argv.append("-fno-stack-protector"); |
| 5524 | | } |
| 5525 | | |
| 5526 | 5697 | switch (mod.optimize_mode) { |
| 5527 | 5698 | .Debug => { |
| 5528 | 5699 | // windows c runtime requires -D_DEBUG if using debug libraries |
| ... | ... | @@ -5556,177 +5727,8 @@ pub fn addCCArgs( |
| 5556 | 5727 | if (mod.optimize_mode != .Debug) { |
| 5557 | 5728 | try argv.append("-Werror=date-time"); |
| 5558 | 5729 | } |
| 5559 | | |
| 5560 | | switch (mod.unwind_tables) { |
| 5561 | | .none => { |
| 5562 | | try argv.append("-fno-unwind-tables"); |
| 5563 | | try argv.append("-fno-asynchronous-unwind-tables"); |
| 5564 | | }, |
| 5565 | | .sync => { |
| 5566 | | // Need to override Clang's convoluted default logic. |
| 5567 | | try argv.append("-fno-asynchronous-unwind-tables"); |
| 5568 | | try argv.append("-funwind-tables"); |
| 5569 | | }, |
| 5570 | | .@"async" => try argv.append("-fasynchronous-unwind-tables"), |
| 5571 | | } |
| 5572 | | }, |
| 5573 | | .shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig, .res, .manifest => {}, |
| 5574 | | .assembly, .assembly_with_cpp => { |
| 5575 | | if (ext == .assembly_with_cpp) { |
| 5576 | | const c_headers_dir = try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" }); |
| 5577 | | try argv.append("-isystem"); |
| 5578 | | try argv.append(c_headers_dir); |
| 5579 | | |
| 5580 | | for (comp.libc_include_dir_list) |include_dir| { |
| 5581 | | try argv.append("-isystem"); |
| 5582 | | try argv.append(include_dir); |
| 5583 | | } |
| 5584 | | } |
| 5585 | | |
| 5586 | | // The Clang assembler does not accept the list of CPU features like the |
| 5587 | | // compiler frontend does. Therefore we must hard-code the -m flags for |
| 5588 | | // all CPU features here. |
| 5589 | | switch (target.cpu.arch) { |
| 5590 | | .riscv32, .riscv64 => { |
| 5591 | | const RvArchFeat = struct { char: u8, feat: std.Target.riscv.Feature }; |
| 5592 | | const letters = [_]RvArchFeat{ |
| 5593 | | .{ .char = 'm', .feat = .m }, |
| 5594 | | .{ .char = 'a', .feat = .a }, |
| 5595 | | .{ .char = 'f', .feat = .f }, |
| 5596 | | .{ .char = 'd', .feat = .d }, |
| 5597 | | .{ .char = 'c', .feat = .c }, |
| 5598 | | }; |
| 5599 | | const prefix: []const u8 = if (target.cpu.arch == .riscv64) "rv64" else "rv32"; |
| 5600 | | const prefix_len = 4; |
| 5601 | | assert(prefix.len == prefix_len); |
| 5602 | | var march_buf: [prefix_len + letters.len + 1]u8 = undefined; |
| 5603 | | var march_index: usize = prefix_len; |
| 5604 | | @memcpy(march_buf[0..prefix.len], prefix); |
| 5605 | | |
| 5606 | | if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) { |
| 5607 | | march_buf[march_index] = 'e'; |
| 5608 | | } else { |
| 5609 | | march_buf[march_index] = 'i'; |
| 5610 | | } |
| 5611 | | march_index += 1; |
| 5612 | | |
| 5613 | | for (letters) |letter| { |
| 5614 | | if (std.Target.riscv.featureSetHas(target.cpu.features, letter.feat)) { |
| 5615 | | march_buf[march_index] = letter.char; |
| 5616 | | march_index += 1; |
| 5617 | | } |
| 5618 | | } |
| 5619 | | |
| 5620 | | const march_arg = try std.fmt.allocPrint(arena, "-march={s}", .{ |
| 5621 | | march_buf[0..march_index], |
| 5622 | | }); |
| 5623 | | try argv.append(march_arg); |
| 5624 | | |
| 5625 | | if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) { |
| 5626 | | try argv.append("-mrelax"); |
| 5627 | | } else { |
| 5628 | | try argv.append("-mno-relax"); |
| 5629 | | } |
| 5630 | | if (std.Target.riscv.featureSetHas(target.cpu.features, .save_restore)) { |
| 5631 | | try argv.append("-msave-restore"); |
| 5632 | | } else { |
| 5633 | | try argv.append("-mno-save-restore"); |
| 5634 | | } |
| 5635 | | }, |
| 5636 | | .mips, .mipsel, .mips64, .mips64el => { |
| 5637 | | if (target.cpu.model.llvm_name) |llvm_name| { |
| 5638 | | try argv.append(try std.fmt.allocPrint(arena, "-march={s}", .{llvm_name})); |
| 5639 | | } |
| 5640 | | }, |
| 5641 | | else => { |
| 5642 | | // TODO |
| 5643 | | }, |
| 5644 | | } |
| 5645 | | if (target_util.clangAssemblerSupportsMcpuArg(target)) { |
| 5646 | | if (target.cpu.model.llvm_name) |llvm_name| { |
| 5647 | | try argv.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{llvm_name})); |
| 5648 | | } |
| 5649 | | } |
| 5650 | | }, |
| 5651 | | } |
| 5652 | | |
| 5653 | | if (comp.mingw_unicode_entry_point) { |
| 5654 | | try argv.append("-municode"); |
| 5655 | | } |
| 5656 | | |
| 5657 | | if (target.cpu.arch.isArm()) { |
| 5658 | | try argv.append(if (target.cpu.arch.isThumb()) "-mthumb" else "-mno-thumb"); |
| 5659 | | } |
| 5660 | | |
| 5661 | | if (target_util.supports_fpic(target)) { |
| 5662 | | try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC"); |
| 5663 | | } |
| 5664 | | |
| 5665 | | try argv.ensureUnusedCapacity(2); |
| 5666 | | switch (comp.config.debug_format) { |
| 5667 | | .strip => {}, |
| 5668 | | .code_view => { |
| 5669 | | // -g is required here because -gcodeview doesn't trigger debug info |
| 5670 | | // generation, it only changes the type of information generated. |
| 5671 | | argv.appendSliceAssumeCapacity(&.{ "-g", "-gcodeview" }); |
| 5672 | | }, |
| 5673 | | .dwarf => |f| { |
| 5674 | | argv.appendAssumeCapacity("-gdwarf-4"); |
| 5675 | | switch (f) { |
| 5676 | | .@"32" => argv.appendAssumeCapacity("-gdwarf32"), |
| 5677 | | .@"64" => argv.appendAssumeCapacity("-gdwarf64"), |
| 5678 | | } |
| 5679 | 5730 | }, |
| 5680 | | } |
| 5681 | | |
| 5682 | | if (target_util.llvmMachineAbi(target)) |mabi| { |
| 5683 | | try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi})); |
| 5684 | | } |
| 5685 | | |
| 5686 | | // We might want to support -mfloat-abi=softfp for Arm and CSKY here in the future. |
| 5687 | | if (target_util.clangSupportsFloatAbiArg(target)) { |
| 5688 | | const fabi = @tagName(target.floatAbi()); |
| 5689 | | |
| 5690 | | try argv.append(switch (target.cpu.arch) { |
| 5691 | | // For whatever reason, Clang doesn't support `-mfloat-abi` for s390x. |
| 5692 | | .s390x => try std.fmt.allocPrint(arena, "-m{s}-float", .{fabi}), |
| 5693 | | else => try std.fmt.allocPrint(arena, "-mfloat-abi={s}", .{fabi}), |
| 5694 | | }); |
| 5695 | | } |
| 5696 | | |
| 5697 | | if (target_util.clangSupportsNoImplicitFloatArg(target) and target.floatAbi() == .soft) { |
| 5698 | | try argv.append("-mno-implicit-float"); |
| 5699 | | } |
| 5700 | | |
| 5701 | | // https://github.com/llvm/llvm-project/issues/105972 |
| 5702 | | if (target.cpu.arch.isPowerPC() and target.floatAbi() == .soft) { |
| 5703 | | try argv.append("-D__NO_FPRS__"); |
| 5704 | | try argv.append("-D_SOFT_FLOAT"); |
| 5705 | | try argv.append("-D_SOFT_DOUBLE"); |
| 5706 | | } |
| 5707 | | |
| 5708 | | if (out_dep_path) |p| { |
| 5709 | | try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p }); |
| 5710 | | } |
| 5711 | | |
| 5712 | | // We never want clang to invoke the system assembler for anything. So we would want |
| 5713 | | // this option always enabled. However, it only matters for some targets. To avoid |
| 5714 | | // "unused parameter" warnings, and to keep CLI spam to a minimum, we only put this |
| 5715 | | // flag on the command line if it is necessary. |
| 5716 | | if (target_util.clangMightShellOutForAssembly(target)) { |
| 5717 | | try argv.append("-integrated-as"); |
| 5718 | | } |
| 5719 | | |
| 5720 | | if (target.os.tag == .freestanding) { |
| 5721 | | try argv.append("-ffreestanding"); |
| 5722 | | } |
| 5723 | | |
| 5724 | | if (mod.resolved_target.is_native_os and mod.resolved_target.is_native_abi) { |
| 5725 | | try argv.ensureUnusedCapacity(comp.native_system_include_paths.len * 2); |
| 5726 | | for (comp.native_system_include_paths) |include_path| { |
| 5727 | | argv.appendAssumeCapacity("-isystem"); |
| 5728 | | argv.appendAssumeCapacity(include_path); |
| 5729 | | } |
| 5731 | else => {}, |
| 5730 | 5732 | } |
| 5731 | 5733 | |
| 5732 | 5734 | try argv.appendSlice(comp.global_cc_argv); |
| ... | ... | @@ -5840,6 +5842,36 @@ pub const FileExt = enum { |
| 5840 | 5842 | manifest, |
| 5841 | 5843 | unknown, |
| 5842 | 5844 | |
| 5845 | pub fn clangNeedsLanguageOverride(ext: FileExt) bool { |
| 5846 | return switch (ext) { |
| 5847 | .h, |
| 5848 | .hpp, |
| 5849 | .hm, |
| 5850 | .hmm, |
| 5851 | => true, |
| 5852 | |
| 5853 | .c, |
| 5854 | .cpp, |
| 5855 | .cu, |
| 5856 | .m, |
| 5857 | .mm, |
| 5858 | .ll, |
| 5859 | .bc, |
| 5860 | .assembly, |
| 5861 | .assembly_with_cpp, |
| 5862 | .shared_library, |
| 5863 | .object, |
| 5864 | .static_library, |
| 5865 | .zig, |
| 5866 | .def, |
| 5867 | .rc, |
| 5868 | .res, |
| 5869 | .manifest, |
| 5870 | .unknown, |
| 5871 | => false, |
| 5872 | }; |
| 5873 | } |
| 5874 | |
| 5843 | 5875 | pub fn clangSupportsDiagnostics(ext: FileExt) bool { |
| 5844 | 5876 | return switch (ext) { |
| 5845 | 5877 | .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu, .ll, .bc => true, |
| ... | ... | @@ -5861,12 +5893,11 @@ pub const FileExt = enum { |
| 5861 | 5893 | |
| 5862 | 5894 | pub fn clangSupportsDepFile(ext: FileExt) bool { |
| 5863 | 5895 | return switch (ext) { |
| 5864 | | .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu => true, |
| 5896 | .assembly_with_cpp, .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu => true, |
| 5865 | 5897 | |
| 5866 | 5898 | .ll, |
| 5867 | 5899 | .bc, |
| 5868 | 5900 | .assembly, |
| 5869 | | .assembly_with_cpp, |
| 5870 | 5901 | .shared_library, |
| 5871 | 5902 | .object, |
| 5872 | 5903 | .static_library, |
| ... | ... | @@ -5886,9 +5917,9 @@ pub const FileExt = enum { |
| 5886 | 5917 | .cpp => ".cpp", |
| 5887 | 5918 | .cu => ".cu", |
| 5888 | 5919 | .h => ".h", |
| 5889 | | .hpp => ".h", |
| 5890 | | .hm => ".h", |
| 5891 | | .hmm => ".h", |
| 5920 | .hpp => ".hpp", |
| 5921 | .hm => ".hm", |
| 5922 | .hmm => ".hmm", |
| 5892 | 5923 | .m => ".m", |
| 5893 | 5924 | .mm => ".mm", |
| 5894 | 5925 | .ll => ".ll", |
| ... | ... | @@ -5925,21 +5956,42 @@ pub fn hasCExt(filename: []const u8) bool { |
| 5925 | 5956 | return mem.endsWith(u8, filename, ".c"); |
| 5926 | 5957 | } |
| 5927 | 5958 | |
| 5959 | pub fn hasCHExt(filename: []const u8) bool { |
| 5960 | return mem.endsWith(u8, filename, ".h"); |
| 5961 | } |
| 5962 | |
| 5928 | 5963 | pub fn hasCppExt(filename: []const u8) bool { |
| 5929 | 5964 | return mem.endsWith(u8, filename, ".C") or |
| 5930 | 5965 | mem.endsWith(u8, filename, ".cc") or |
| 5966 | mem.endsWith(u8, filename, ".cp") or |
| 5967 | mem.endsWith(u8, filename, ".CPP") or |
| 5931 | 5968 | mem.endsWith(u8, filename, ".cpp") or |
| 5932 | 5969 | mem.endsWith(u8, filename, ".cxx") or |
| 5933 | 5970 | mem.endsWith(u8, filename, ".c++") or |
| 5934 | 5971 | mem.endsWith(u8, filename, ".stub"); |
| 5935 | 5972 | } |
| 5936 | 5973 | |
| 5974 | pub fn hasCppHExt(filename: []const u8) bool { |
| 5975 | return mem.endsWith(u8, filename, ".hh") or |
| 5976 | mem.endsWith(u8, filename, ".hpp") or |
| 5977 | mem.endsWith(u8, filename, ".hxx"); |
| 5978 | } |
| 5979 | |
| 5937 | 5980 | pub fn hasObjCExt(filename: []const u8) bool { |
| 5938 | 5981 | return mem.endsWith(u8, filename, ".m"); |
| 5939 | 5982 | } |
| 5940 | 5983 | |
| 5984 | pub fn hasObjCHExt(filename: []const u8) bool { |
| 5985 | return mem.endsWith(u8, filename, ".hm"); |
| 5986 | } |
| 5987 | |
| 5941 | 5988 | pub fn hasObjCppExt(filename: []const u8) bool { |
| 5942 | | return mem.endsWith(u8, filename, ".mm"); |
| 5989 | return mem.endsWith(u8, filename, ".M") or |
| 5990 | mem.endsWith(u8, filename, ".mm"); |
| 5991 | } |
| 5992 | |
| 5993 | pub fn hasObjCppHExt(filename: []const u8) bool { |
| 5994 | return mem.endsWith(u8, filename, ".hmm"); |
| 5943 | 5995 | } |
| 5944 | 5996 | |
| 5945 | 5997 | pub fn hasSharedLibraryExt(filename: []const u8) bool { |
| ... | ... | @@ -5972,12 +6024,20 @@ pub fn hasSharedLibraryExt(filename: []const u8) bool { |
| 5972 | 6024 | pub fn classifyFileExt(filename: []const u8) FileExt { |
| 5973 | 6025 | if (hasCExt(filename)) { |
| 5974 | 6026 | return .c; |
| 6027 | } else if (hasCHExt(filename)) { |
| 6028 | return .h; |
| 5975 | 6029 | } else if (hasCppExt(filename)) { |
| 5976 | 6030 | return .cpp; |
| 6031 | } else if (hasCppHExt(filename)) { |
| 6032 | return .hpp; |
| 5977 | 6033 | } else if (hasObjCExt(filename)) { |
| 5978 | 6034 | return .m; |
| 6035 | } else if (hasObjCHExt(filename)) { |
| 6036 | return .hm; |
| 5979 | 6037 | } else if (hasObjCppExt(filename)) { |
| 5980 | 6038 | return .mm; |
| 6039 | } else if (hasObjCppHExt(filename)) { |
| 6040 | return .hmm; |
| 5981 | 6041 | } else if (mem.endsWith(u8, filename, ".ll")) { |
| 5982 | 6042 | return .ll; |
| 5983 | 6043 | } else if (mem.endsWith(u8, filename, ".bc")) { |
| ... | ... | @@ -5986,8 +6046,6 @@ pub fn classifyFileExt(filename: []const u8) FileExt { |
| 5986 | 6046 | return .assembly; |
| 5987 | 6047 | } else if (mem.endsWith(u8, filename, ".S")) { |
| 5988 | 6048 | return .assembly_with_cpp; |
| 5989 | | } else if (mem.endsWith(u8, filename, ".h")) { |
| 5990 | | return .h; |
| 5991 | 6049 | } else if (mem.endsWith(u8, filename, ".zig")) { |
| 5992 | 6050 | return .zig; |
| 5993 | 6051 | } else if (hasSharedLibraryExt(filename)) { |