mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
Merge pull request #22224 from alexrp/cc-args
`Compilation`: Clean up `addCCArgs()` + some minor improvements
This commit is contained in:
commit
af89bb05d3
@ -4687,19 +4687,19 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
|
||||
|
||||
try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang" });
|
||||
// if "ext" is explicit, add "-x <lang>". Otherwise let clang do its thing.
|
||||
if (c_object.src.ext != null) {
|
||||
if (c_object.src.ext != null or ext.clangNeedsLanguageOverride()) {
|
||||
try argv.appendSlice(&[_][]const u8{ "-x", switch (ext) {
|
||||
.assembly => "assembler",
|
||||
.assembly_with_cpp => "assembler-with-cpp",
|
||||
.c => "c",
|
||||
.cpp => "c++",
|
||||
.h => "c-header",
|
||||
.cpp => "c++",
|
||||
.hpp => "c++-header",
|
||||
.m => "objective-c",
|
||||
.hm => "objective-c-header",
|
||||
.mm => "objective-c++",
|
||||
.hmm => "objective-c++-header",
|
||||
.cu => "cuda",
|
||||
.m => "objective-c",
|
||||
.mm => "objective-c++",
|
||||
else => fatal("language '{s}' is unsupported in this context", .{@tagName(ext)}),
|
||||
} });
|
||||
}
|
||||
@ -5273,10 +5273,6 @@ pub fn addCCArgs(
|
||||
// can be disabled.
|
||||
try argv.append("--no-default-config");
|
||||
|
||||
if (ext == .cpp) {
|
||||
try argv.append("-nostdinc++");
|
||||
}
|
||||
|
||||
// We don't ever put `-fcolor-diagnostics` or `-fno-color-diagnostics` because in passthrough mode
|
||||
// we want Clang to infer it, and in normal mode we always want it off, which will be true since
|
||||
// clang will detect stderr as a pipe rather than a terminal.
|
||||
@ -5285,117 +5281,312 @@ pub fn addCCArgs(
|
||||
try argv.append("-fno-caret-diagnostics");
|
||||
}
|
||||
|
||||
try argv.append(if (comp.function_sections) "-ffunction-sections" else "-fno-function-sections");
|
||||
try argv.append(if (comp.data_sections) "-fdata-sections" else "-fno-data-sections");
|
||||
|
||||
try argv.append(if (mod.no_builtin) "-fno-builtin" else "-fbuiltin");
|
||||
|
||||
if (comp.config.link_libcpp) {
|
||||
const libcxx_include_path = try std.fs.path.join(arena, &[_][]const u8{
|
||||
comp.zig_lib_directory.path.?, "libcxx", "include",
|
||||
});
|
||||
const libcxxabi_include_path = try std.fs.path.join(arena, &[_][]const u8{
|
||||
comp.zig_lib_directory.path.?, "libcxxabi", "include",
|
||||
});
|
||||
|
||||
try argv.append("-isystem");
|
||||
try argv.append(libcxx_include_path);
|
||||
|
||||
try argv.append("-isystem");
|
||||
try argv.append(libcxxabi_include_path);
|
||||
|
||||
if (target.abi.isMusl()) {
|
||||
try argv.append("-D_LIBCPP_HAS_MUSL_LIBC");
|
||||
}
|
||||
try argv.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
|
||||
try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS");
|
||||
try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
|
||||
|
||||
if (!comp.config.any_non_single_threaded) {
|
||||
try argv.append("-D_LIBCPP_HAS_NO_THREADS");
|
||||
}
|
||||
|
||||
// See the comment in libcxx.zig for more details about this.
|
||||
try argv.append("-D_LIBCPP_PSTL_BACKEND_SERIAL");
|
||||
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{
|
||||
@intFromEnum(comp.libcxx_abi_version),
|
||||
}));
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{
|
||||
@intFromEnum(comp.libcxx_abi_version),
|
||||
}));
|
||||
|
||||
try argv.append(libcxx.hardeningModeFlag(mod.optimize_mode));
|
||||
}
|
||||
|
||||
if (comp.config.link_libunwind) {
|
||||
const libunwind_include_path = try std.fs.path.join(arena, &[_][]const u8{
|
||||
comp.zig_lib_directory.path.?, "libunwind", "include",
|
||||
});
|
||||
|
||||
try argv.append("-isystem");
|
||||
try argv.append(libunwind_include_path);
|
||||
}
|
||||
|
||||
if (comp.config.link_libc) {
|
||||
if (target.isGnuLibC()) {
|
||||
const target_version = target.os.versionRange().gnuLibCVersion().?;
|
||||
const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{
|
||||
target_version.minor,
|
||||
});
|
||||
try argv.append(glibc_minor_define);
|
||||
} else if (target.isMinGW()) {
|
||||
try argv.append("-D__MSVCRT_VERSION__=0xE00"); // use ucrt
|
||||
|
||||
switch (ext) {
|
||||
.c, .cpp, .m, .mm, .h, .hpp, .hm, .hmm, .cu, .rc, .assembly, .assembly_with_cpp => {
|
||||
const minver: u16 = @truncate(@intFromEnum(target.os.versionRange().windows.min) >> 16);
|
||||
try argv.append(
|
||||
try std.fmt.allocPrint(arena, "-D_WIN32_WINNT=0x{x:0>4}", .{minver}),
|
||||
);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
// We never want clang to invoke the system assembler for anything. So we would want
|
||||
// this option always enabled. However, it only matters for some targets. To avoid
|
||||
// "unused parameter" warnings, and to keep CLI spam to a minimum, we only put this
|
||||
// flag on the command line if it is necessary.
|
||||
if (target_util.clangMightShellOutForAssembly(target)) {
|
||||
try argv.append("-integrated-as");
|
||||
}
|
||||
|
||||
const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target);
|
||||
try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple });
|
||||
|
||||
switch (ext) {
|
||||
.c, .cpp, .m, .mm, .h, .hpp, .hm, .hmm, .cu, .rc => {
|
||||
if (target.cpu.arch.isArm()) {
|
||||
try argv.append(if (target.cpu.arch.isThumb()) "-mthumb" else "-mno-thumb");
|
||||
}
|
||||
|
||||
if (target_util.llvmMachineAbi(target)) |mabi| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi}));
|
||||
}
|
||||
|
||||
// We might want to support -mfloat-abi=softfp for Arm and CSKY here in the future.
|
||||
if (target_util.clangSupportsFloatAbiArg(target)) {
|
||||
const fabi = @tagName(target.floatAbi());
|
||||
|
||||
try argv.append(switch (target.cpu.arch) {
|
||||
// For whatever reason, Clang doesn't support `-mfloat-abi` for s390x.
|
||||
.s390x => try std.fmt.allocPrint(arena, "-m{s}-float", .{fabi}),
|
||||
else => try std.fmt.allocPrint(arena, "-mfloat-abi={s}", .{fabi}),
|
||||
});
|
||||
}
|
||||
|
||||
if (target_util.supports_fpic(target)) {
|
||||
try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC");
|
||||
}
|
||||
|
||||
if (comp.mingw_unicode_entry_point) {
|
||||
try argv.append("-municode");
|
||||
}
|
||||
|
||||
if (mod.code_model != .default) {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(mod.code_model)}));
|
||||
}
|
||||
|
||||
try argv.ensureUnusedCapacity(2);
|
||||
switch (comp.config.debug_format) {
|
||||
.strip => {},
|
||||
.code_view => {
|
||||
// -g is required here because -gcodeview doesn't trigger debug info
|
||||
// generation, it only changes the type of information generated.
|
||||
argv.appendSliceAssumeCapacity(&.{ "-g", "-gcodeview" });
|
||||
},
|
||||
.dwarf => |f| {
|
||||
argv.appendAssumeCapacity("-gdwarf-4");
|
||||
switch (f) {
|
||||
.@"32" => argv.appendAssumeCapacity("-gdwarf32"),
|
||||
.@"64" => argv.appendAssumeCapacity("-gdwarf64"),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if (comp.config.lto) {
|
||||
try argv.append("-flto");
|
||||
}
|
||||
|
||||
// This only works for preprocessed files. Guarded by `FileExt.clangSupportsDepFile`.
|
||||
if (out_dep_path) |p| {
|
||||
try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p });
|
||||
}
|
||||
|
||||
// Non-preprocessed assembly files don't support these flags.
|
||||
if (ext != .assembly) {
|
||||
try argv.append(if (target.os.tag == .freestanding) "-ffreestanding" else "-fhosted");
|
||||
|
||||
if (target_util.clangSupportsNoImplicitFloatArg(target) and target.floatAbi() == .soft) {
|
||||
try argv.append("-mno-implicit-float");
|
||||
}
|
||||
|
||||
if (target_util.hasRedZone(target)) {
|
||||
try argv.append(if (mod.red_zone) "-mred-zone" else "-mno-red-zone");
|
||||
}
|
||||
|
||||
try argv.append(if (mod.omit_frame_pointer) "-fomit-frame-pointer" else "-fno-omit-frame-pointer");
|
||||
|
||||
const ssp_buf_size = mod.stack_protector;
|
||||
if (ssp_buf_size != 0) {
|
||||
try argv.appendSlice(&[_][]const u8{
|
||||
"-nostdinc",
|
||||
"-fno-spell-checking",
|
||||
"-fstack-protector-strong",
|
||||
"--param",
|
||||
try std.fmt.allocPrint(arena, "ssp-buffer-size={d}", .{ssp_buf_size}),
|
||||
});
|
||||
if (comp.config.lto) {
|
||||
try argv.append("-flto");
|
||||
} else {
|
||||
try argv.append("-fno-stack-protector");
|
||||
}
|
||||
|
||||
try argv.append(if (mod.no_builtin) "-fno-builtin" else "-fbuiltin");
|
||||
|
||||
try argv.append(if (comp.function_sections) "-ffunction-sections" else "-fno-function-sections");
|
||||
try argv.append(if (comp.data_sections) "-fdata-sections" else "-fno-data-sections");
|
||||
|
||||
switch (mod.unwind_tables) {
|
||||
.none => {
|
||||
try argv.append("-fno-unwind-tables");
|
||||
try argv.append("-fno-asynchronous-unwind-tables");
|
||||
},
|
||||
.sync => {
|
||||
// Need to override Clang's convoluted default logic.
|
||||
try argv.append("-fno-asynchronous-unwind-tables");
|
||||
try argv.append("-funwind-tables");
|
||||
},
|
||||
.@"async" => try argv.append("-fasynchronous-unwind-tables"),
|
||||
}
|
||||
|
||||
try argv.append("-nostdinc");
|
||||
|
||||
if (ext == .cpp or ext == .hpp) {
|
||||
try argv.append("-nostdinc++");
|
||||
}
|
||||
|
||||
// LLVM IR files don't support these flags.
|
||||
if (ext != .ll and ext != .bc) {
|
||||
// https://github.com/llvm/llvm-project/issues/105972
|
||||
if (target.cpu.arch.isPowerPC() and target.floatAbi() == .soft) {
|
||||
try argv.append("-D__NO_FPRS__");
|
||||
try argv.append("-D_SOFT_FLOAT");
|
||||
try argv.append("-D_SOFT_DOUBLE");
|
||||
}
|
||||
|
||||
if (ext == .mm) {
|
||||
try argv.append("-ObjC++");
|
||||
if (comp.config.link_libc) {
|
||||
if (target.isGnuLibC()) {
|
||||
const target_version = target.os.versionRange().gnuLibCVersion().?;
|
||||
const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{
|
||||
target_version.minor,
|
||||
});
|
||||
try argv.append(glibc_minor_define);
|
||||
} else if (target.isMinGW()) {
|
||||
try argv.append("-D__MSVCRT_VERSION__=0xE00"); // use ucrt
|
||||
|
||||
const minver: u16 = @truncate(@intFromEnum(target.os.versionRange().windows.min) >> 16);
|
||||
try argv.append(
|
||||
try std.fmt.allocPrint(arena, "-D_WIN32_WINNT=0x{x:0>4}", .{minver}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (comp.libc_framework_dir_list) |framework_dir| {
|
||||
try argv.appendSlice(&.{ "-iframework", framework_dir });
|
||||
}
|
||||
if (comp.config.link_libcpp) {
|
||||
try argv.append("-isystem");
|
||||
try argv.append(try std.fs.path.join(arena, &[_][]const u8{
|
||||
comp.zig_lib_directory.path.?, "libcxx", "include",
|
||||
}));
|
||||
|
||||
for (comp.framework_dirs) |framework_dir| {
|
||||
try argv.appendSlice(&.{ "-F", framework_dir });
|
||||
try argv.append("-isystem");
|
||||
try argv.append(try std.fs.path.join(arena, &[_][]const u8{
|
||||
comp.zig_lib_directory.path.?, "libcxxabi", "include",
|
||||
}));
|
||||
|
||||
if (target.abi.isMusl()) {
|
||||
try argv.append("-D_LIBCPP_HAS_MUSL_LIBC");
|
||||
}
|
||||
|
||||
try argv.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
|
||||
try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS");
|
||||
try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
|
||||
|
||||
if (!comp.config.any_non_single_threaded) {
|
||||
try argv.append("-D_LIBCPP_HAS_NO_THREADS");
|
||||
}
|
||||
|
||||
// See the comment in libcxx.zig for more details about this.
|
||||
try argv.append("-D_LIBCPP_PSTL_BACKEND_SERIAL");
|
||||
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{
|
||||
@intFromEnum(comp.libcxx_abi_version),
|
||||
}));
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{
|
||||
@intFromEnum(comp.libcxx_abi_version),
|
||||
}));
|
||||
|
||||
try argv.append(libcxx.hardeningModeFlag(mod.optimize_mode));
|
||||
}
|
||||
|
||||
// According to Rich Felker libc headers are supposed to go before C language headers.
|
||||
// However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics
|
||||
// and other compiler specific items.
|
||||
const c_headers_dir = try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" });
|
||||
// However as noted by @dimenus, appending libc headers before compiler headers breaks
|
||||
// intrinsics and other compiler specific items.
|
||||
try argv.append("-isystem");
|
||||
try argv.append(c_headers_dir);
|
||||
try argv.append(try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" }));
|
||||
|
||||
try argv.ensureUnusedCapacity(comp.libc_include_dir_list.len * 2);
|
||||
for (comp.libc_include_dir_list) |include_dir| {
|
||||
try argv.append("-isystem");
|
||||
try argv.append(include_dir);
|
||||
}
|
||||
|
||||
if (mod.resolved_target.is_native_os and mod.resolved_target.is_native_abi) {
|
||||
try argv.ensureUnusedCapacity(comp.native_system_include_paths.len * 2);
|
||||
for (comp.native_system_include_paths) |include_path| {
|
||||
argv.appendAssumeCapacity("-isystem");
|
||||
argv.appendAssumeCapacity(include_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (comp.config.link_libunwind) {
|
||||
try argv.append("-isystem");
|
||||
try argv.append(try std.fs.path.join(arena, &[_][]const u8{
|
||||
comp.zig_lib_directory.path.?, "libunwind", "include",
|
||||
}));
|
||||
}
|
||||
|
||||
try argv.ensureUnusedCapacity(comp.libc_framework_dir_list.len * 2);
|
||||
for (comp.libc_framework_dir_list) |framework_dir| {
|
||||
try argv.appendSlice(&.{ "-iframework", framework_dir });
|
||||
}
|
||||
|
||||
try argv.ensureUnusedCapacity(comp.framework_dirs.len * 2);
|
||||
for (comp.framework_dirs) |framework_dir| {
|
||||
try argv.appendSlice(&.{ "-F", framework_dir });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only assembly files support these flags.
|
||||
switch (ext) {
|
||||
.assembly,
|
||||
.assembly_with_cpp,
|
||||
=> {
|
||||
// The Clang assembler does not accept the list of CPU features like the
|
||||
// compiler frontend does. Therefore we must hard-code the -m flags for
|
||||
// all CPU features here.
|
||||
switch (target.cpu.arch) {
|
||||
.riscv32, .riscv64 => {
|
||||
const RvArchFeat = struct { char: u8, feat: std.Target.riscv.Feature };
|
||||
const letters = [_]RvArchFeat{
|
||||
.{ .char = 'm', .feat = .m },
|
||||
.{ .char = 'a', .feat = .a },
|
||||
.{ .char = 'f', .feat = .f },
|
||||
.{ .char = 'd', .feat = .d },
|
||||
.{ .char = 'c', .feat = .c },
|
||||
};
|
||||
const prefix: []const u8 = if (target.cpu.arch == .riscv64) "rv64" else "rv32";
|
||||
const prefix_len = 4;
|
||||
assert(prefix.len == prefix_len);
|
||||
var march_buf: [prefix_len + letters.len + 1]u8 = undefined;
|
||||
var march_index: usize = prefix_len;
|
||||
@memcpy(march_buf[0..prefix.len], prefix);
|
||||
|
||||
if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) {
|
||||
march_buf[march_index] = 'e';
|
||||
} else {
|
||||
march_buf[march_index] = 'i';
|
||||
}
|
||||
march_index += 1;
|
||||
|
||||
for (letters) |letter| {
|
||||
if (std.Target.riscv.featureSetHas(target.cpu.features, letter.feat)) {
|
||||
march_buf[march_index] = letter.char;
|
||||
march_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const march_arg = try std.fmt.allocPrint(arena, "-march={s}", .{
|
||||
march_buf[0..march_index],
|
||||
});
|
||||
try argv.append(march_arg);
|
||||
|
||||
if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) {
|
||||
try argv.append("-mrelax");
|
||||
} else {
|
||||
try argv.append("-mno-relax");
|
||||
}
|
||||
if (std.Target.riscv.featureSetHas(target.cpu.features, .save_restore)) {
|
||||
try argv.append("-msave-restore");
|
||||
} else {
|
||||
try argv.append("-mno-save-restore");
|
||||
}
|
||||
},
|
||||
.mips, .mipsel, .mips64, .mips64el => {
|
||||
if (target.cpu.model.llvm_name) |llvm_name| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-march={s}", .{llvm_name}));
|
||||
}
|
||||
},
|
||||
else => {
|
||||
// TODO
|
||||
},
|
||||
}
|
||||
|
||||
if (target_util.clangAssemblerSupportsMcpuArg(target)) {
|
||||
if (target.cpu.model.llvm_name) |llvm_name| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{llvm_name}));
|
||||
}
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
// Only C-family files support these flags.
|
||||
switch (ext) {
|
||||
.c,
|
||||
.h,
|
||||
.cpp,
|
||||
.hpp,
|
||||
.m,
|
||||
.hm,
|
||||
.mm,
|
||||
.hmm,
|
||||
.cu,
|
||||
=> {
|
||||
try argv.append("-fno-spell-checking");
|
||||
|
||||
if (target_util.clangSupportsTargetCpuArg(target)) {
|
||||
if (target.cpu.model.llvm_name) |llvm_name| {
|
||||
try argv.appendSlice(&[_][]const u8{
|
||||
@ -5421,9 +5612,6 @@ pub fn addCCArgs(
|
||||
argv.appendAssumeCapacity(arg);
|
||||
}
|
||||
}
|
||||
if (mod.code_model != .default) {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(mod.code_model)}));
|
||||
}
|
||||
|
||||
switch (target.os.tag) {
|
||||
.windows => {
|
||||
@ -5506,23 +5694,6 @@ pub fn addCCArgs(
|
||||
}
|
||||
}
|
||||
|
||||
if (target_util.hasRedZone(target)) {
|
||||
try argv.append(if (mod.red_zone) "-mred-zone" else "-mno-red-zone");
|
||||
}
|
||||
|
||||
try argv.append(if (mod.omit_frame_pointer) "-fomit-frame-pointer" else "-fno-omit-frame-pointer");
|
||||
|
||||
const ssp_buf_size = mod.stack_protector;
|
||||
if (ssp_buf_size != 0) {
|
||||
try argv.appendSlice(&[_][]const u8{
|
||||
"-fstack-protector-strong",
|
||||
"--param",
|
||||
try std.fmt.allocPrint(arena, "ssp-buffer-size={d}", .{ssp_buf_size}),
|
||||
});
|
||||
} else {
|
||||
try argv.append("-fno-stack-protector");
|
||||
}
|
||||
|
||||
switch (mod.optimize_mode) {
|
||||
.Debug => {
|
||||
// windows c runtime requires -D_DEBUG if using debug libraries
|
||||
@ -5556,177 +5727,8 @@ pub fn addCCArgs(
|
||||
if (mod.optimize_mode != .Debug) {
|
||||
try argv.append("-Werror=date-time");
|
||||
}
|
||||
|
||||
switch (mod.unwind_tables) {
|
||||
.none => {
|
||||
try argv.append("-fno-unwind-tables");
|
||||
try argv.append("-fno-asynchronous-unwind-tables");
|
||||
},
|
||||
.sync => {
|
||||
// Need to override Clang's convoluted default logic.
|
||||
try argv.append("-fno-asynchronous-unwind-tables");
|
||||
try argv.append("-funwind-tables");
|
||||
},
|
||||
.@"async" => try argv.append("-fasynchronous-unwind-tables"),
|
||||
}
|
||||
},
|
||||
.shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig, .res, .manifest => {},
|
||||
.assembly, .assembly_with_cpp => {
|
||||
if (ext == .assembly_with_cpp) {
|
||||
const c_headers_dir = try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" });
|
||||
try argv.append("-isystem");
|
||||
try argv.append(c_headers_dir);
|
||||
|
||||
for (comp.libc_include_dir_list) |include_dir| {
|
||||
try argv.append("-isystem");
|
||||
try argv.append(include_dir);
|
||||
}
|
||||
}
|
||||
|
||||
// The Clang assembler does not accept the list of CPU features like the
|
||||
// compiler frontend does. Therefore we must hard-code the -m flags for
|
||||
// all CPU features here.
|
||||
switch (target.cpu.arch) {
|
||||
.riscv32, .riscv64 => {
|
||||
const RvArchFeat = struct { char: u8, feat: std.Target.riscv.Feature };
|
||||
const letters = [_]RvArchFeat{
|
||||
.{ .char = 'm', .feat = .m },
|
||||
.{ .char = 'a', .feat = .a },
|
||||
.{ .char = 'f', .feat = .f },
|
||||
.{ .char = 'd', .feat = .d },
|
||||
.{ .char = 'c', .feat = .c },
|
||||
};
|
||||
const prefix: []const u8 = if (target.cpu.arch == .riscv64) "rv64" else "rv32";
|
||||
const prefix_len = 4;
|
||||
assert(prefix.len == prefix_len);
|
||||
var march_buf: [prefix_len + letters.len + 1]u8 = undefined;
|
||||
var march_index: usize = prefix_len;
|
||||
@memcpy(march_buf[0..prefix.len], prefix);
|
||||
|
||||
if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) {
|
||||
march_buf[march_index] = 'e';
|
||||
} else {
|
||||
march_buf[march_index] = 'i';
|
||||
}
|
||||
march_index += 1;
|
||||
|
||||
for (letters) |letter| {
|
||||
if (std.Target.riscv.featureSetHas(target.cpu.features, letter.feat)) {
|
||||
march_buf[march_index] = letter.char;
|
||||
march_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const march_arg = try std.fmt.allocPrint(arena, "-march={s}", .{
|
||||
march_buf[0..march_index],
|
||||
});
|
||||
try argv.append(march_arg);
|
||||
|
||||
if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) {
|
||||
try argv.append("-mrelax");
|
||||
} else {
|
||||
try argv.append("-mno-relax");
|
||||
}
|
||||
if (std.Target.riscv.featureSetHas(target.cpu.features, .save_restore)) {
|
||||
try argv.append("-msave-restore");
|
||||
} else {
|
||||
try argv.append("-mno-save-restore");
|
||||
}
|
||||
},
|
||||
.mips, .mipsel, .mips64, .mips64el => {
|
||||
if (target.cpu.model.llvm_name) |llvm_name| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-march={s}", .{llvm_name}));
|
||||
}
|
||||
},
|
||||
else => {
|
||||
// TODO
|
||||
},
|
||||
}
|
||||
if (target_util.clangAssemblerSupportsMcpuArg(target)) {
|
||||
if (target.cpu.model.llvm_name) |llvm_name| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{llvm_name}));
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if (comp.mingw_unicode_entry_point) {
|
||||
try argv.append("-municode");
|
||||
}
|
||||
|
||||
if (target.cpu.arch.isArm()) {
|
||||
try argv.append(if (target.cpu.arch.isThumb()) "-mthumb" else "-mno-thumb");
|
||||
}
|
||||
|
||||
if (target_util.supports_fpic(target)) {
|
||||
try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC");
|
||||
}
|
||||
|
||||
try argv.ensureUnusedCapacity(2);
|
||||
switch (comp.config.debug_format) {
|
||||
.strip => {},
|
||||
.code_view => {
|
||||
// -g is required here because -gcodeview doesn't trigger debug info
|
||||
// generation, it only changes the type of information generated.
|
||||
argv.appendSliceAssumeCapacity(&.{ "-g", "-gcodeview" });
|
||||
},
|
||||
.dwarf => |f| {
|
||||
argv.appendAssumeCapacity("-gdwarf-4");
|
||||
switch (f) {
|
||||
.@"32" => argv.appendAssumeCapacity("-gdwarf32"),
|
||||
.@"64" => argv.appendAssumeCapacity("-gdwarf64"),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if (target_util.llvmMachineAbi(target)) |mabi| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi}));
|
||||
}
|
||||
|
||||
// We might want to support -mfloat-abi=softfp for Arm and CSKY here in the future.
|
||||
if (target_util.clangSupportsFloatAbiArg(target)) {
|
||||
const fabi = @tagName(target.floatAbi());
|
||||
|
||||
try argv.append(switch (target.cpu.arch) {
|
||||
// For whatever reason, Clang doesn't support `-mfloat-abi` for s390x.
|
||||
.s390x => try std.fmt.allocPrint(arena, "-m{s}-float", .{fabi}),
|
||||
else => try std.fmt.allocPrint(arena, "-mfloat-abi={s}", .{fabi}),
|
||||
});
|
||||
}
|
||||
|
||||
if (target_util.clangSupportsNoImplicitFloatArg(target) and target.floatAbi() == .soft) {
|
||||
try argv.append("-mno-implicit-float");
|
||||
}
|
||||
|
||||
// https://github.com/llvm/llvm-project/issues/105972
|
||||
if (target.cpu.arch.isPowerPC() and target.floatAbi() == .soft) {
|
||||
try argv.append("-D__NO_FPRS__");
|
||||
try argv.append("-D_SOFT_FLOAT");
|
||||
try argv.append("-D_SOFT_DOUBLE");
|
||||
}
|
||||
|
||||
if (out_dep_path) |p| {
|
||||
try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p });
|
||||
}
|
||||
|
||||
// We never want clang to invoke the system assembler for anything. So we would want
|
||||
// this option always enabled. However, it only matters for some targets. To avoid
|
||||
// "unused parameter" warnings, and to keep CLI spam to a minimum, we only put this
|
||||
// flag on the command line if it is necessary.
|
||||
if (target_util.clangMightShellOutForAssembly(target)) {
|
||||
try argv.append("-integrated-as");
|
||||
}
|
||||
|
||||
if (target.os.tag == .freestanding) {
|
||||
try argv.append("-ffreestanding");
|
||||
}
|
||||
|
||||
if (mod.resolved_target.is_native_os and mod.resolved_target.is_native_abi) {
|
||||
try argv.ensureUnusedCapacity(comp.native_system_include_paths.len * 2);
|
||||
for (comp.native_system_include_paths) |include_path| {
|
||||
argv.appendAssumeCapacity("-isystem");
|
||||
argv.appendAssumeCapacity(include_path);
|
||||
}
|
||||
else => {},
|
||||
}
|
||||
|
||||
try argv.appendSlice(comp.global_cc_argv);
|
||||
@ -5840,6 +5842,36 @@ pub const FileExt = enum {
|
||||
manifest,
|
||||
unknown,
|
||||
|
||||
pub fn clangNeedsLanguageOverride(ext: FileExt) bool {
|
||||
return switch (ext) {
|
||||
.h,
|
||||
.hpp,
|
||||
.hm,
|
||||
.hmm,
|
||||
=> true,
|
||||
|
||||
.c,
|
||||
.cpp,
|
||||
.cu,
|
||||
.m,
|
||||
.mm,
|
||||
.ll,
|
||||
.bc,
|
||||
.assembly,
|
||||
.assembly_with_cpp,
|
||||
.shared_library,
|
||||
.object,
|
||||
.static_library,
|
||||
.zig,
|
||||
.def,
|
||||
.rc,
|
||||
.res,
|
||||
.manifest,
|
||||
.unknown,
|
||||
=> false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn clangSupportsDiagnostics(ext: FileExt) bool {
|
||||
return switch (ext) {
|
||||
.c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu, .ll, .bc => true,
|
||||
@ -5861,12 +5893,11 @@ pub const FileExt = enum {
|
||||
|
||||
pub fn clangSupportsDepFile(ext: FileExt) bool {
|
||||
return switch (ext) {
|
||||
.c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu => true,
|
||||
.assembly_with_cpp, .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu => true,
|
||||
|
||||
.ll,
|
||||
.bc,
|
||||
.assembly,
|
||||
.assembly_with_cpp,
|
||||
.shared_library,
|
||||
.object,
|
||||
.static_library,
|
||||
@ -5886,9 +5917,9 @@ pub const FileExt = enum {
|
||||
.cpp => ".cpp",
|
||||
.cu => ".cu",
|
||||
.h => ".h",
|
||||
.hpp => ".h",
|
||||
.hm => ".h",
|
||||
.hmm => ".h",
|
||||
.hpp => ".hpp",
|
||||
.hm => ".hm",
|
||||
.hmm => ".hmm",
|
||||
.m => ".m",
|
||||
.mm => ".mm",
|
||||
.ll => ".ll",
|
||||
@ -5925,21 +5956,42 @@ pub fn hasCExt(filename: []const u8) bool {
|
||||
return mem.endsWith(u8, filename, ".c");
|
||||
}
|
||||
|
||||
pub fn hasCHExt(filename: []const u8) bool {
|
||||
return mem.endsWith(u8, filename, ".h");
|
||||
}
|
||||
|
||||
pub fn hasCppExt(filename: []const u8) bool {
|
||||
return mem.endsWith(u8, filename, ".C") or
|
||||
mem.endsWith(u8, filename, ".cc") or
|
||||
mem.endsWith(u8, filename, ".cp") or
|
||||
mem.endsWith(u8, filename, ".CPP") or
|
||||
mem.endsWith(u8, filename, ".cpp") or
|
||||
mem.endsWith(u8, filename, ".cxx") or
|
||||
mem.endsWith(u8, filename, ".c++") or
|
||||
mem.endsWith(u8, filename, ".stub");
|
||||
}
|
||||
|
||||
pub fn hasCppHExt(filename: []const u8) bool {
|
||||
return mem.endsWith(u8, filename, ".hh") or
|
||||
mem.endsWith(u8, filename, ".hpp") or
|
||||
mem.endsWith(u8, filename, ".hxx");
|
||||
}
|
||||
|
||||
pub fn hasObjCExt(filename: []const u8) bool {
|
||||
return mem.endsWith(u8, filename, ".m");
|
||||
}
|
||||
|
||||
pub fn hasObjCHExt(filename: []const u8) bool {
|
||||
return mem.endsWith(u8, filename, ".hm");
|
||||
}
|
||||
|
||||
pub fn hasObjCppExt(filename: []const u8) bool {
|
||||
return mem.endsWith(u8, filename, ".mm");
|
||||
return mem.endsWith(u8, filename, ".M") or
|
||||
mem.endsWith(u8, filename, ".mm");
|
||||
}
|
||||
|
||||
pub fn hasObjCppHExt(filename: []const u8) bool {
|
||||
return mem.endsWith(u8, filename, ".hmm");
|
||||
}
|
||||
|
||||
pub fn hasSharedLibraryExt(filename: []const u8) bool {
|
||||
@ -5972,12 +6024,20 @@ pub fn hasSharedLibraryExt(filename: []const u8) bool {
|
||||
pub fn classifyFileExt(filename: []const u8) FileExt {
|
||||
if (hasCExt(filename)) {
|
||||
return .c;
|
||||
} else if (hasCHExt(filename)) {
|
||||
return .h;
|
||||
} else if (hasCppExt(filename)) {
|
||||
return .cpp;
|
||||
} else if (hasCppHExt(filename)) {
|
||||
return .hpp;
|
||||
} else if (hasObjCExt(filename)) {
|
||||
return .m;
|
||||
} else if (hasObjCHExt(filename)) {
|
||||
return .hm;
|
||||
} else if (hasObjCppExt(filename)) {
|
||||
return .mm;
|
||||
} else if (hasObjCppHExt(filename)) {
|
||||
return .hmm;
|
||||
} else if (mem.endsWith(u8, filename, ".ll")) {
|
||||
return .ll;
|
||||
} else if (mem.endsWith(u8, filename, ".bc")) {
|
||||
@ -5986,8 +6046,6 @@ pub fn classifyFileExt(filename: []const u8) FileExt {
|
||||
return .assembly;
|
||||
} else if (mem.endsWith(u8, filename, ".S")) {
|
||||
return .assembly_with_cpp;
|
||||
} else if (mem.endsWith(u8, filename, ".h")) {
|
||||
return .h;
|
||||
} else if (mem.endsWith(u8, filename, ".zig")) {
|
||||
return .zig;
|
||||
} else if (hasSharedLibraryExt(filename)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user