diff --git a/src/Compilation.zig b/src/Compilation.zig index 1b6d805bb3ca..0818eaafddd6 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -4597,6 +4597,27 @@ pub const FileExt = enum { => false, }; } + + pub fn canonicalName(ext: FileExt, target: Target) [:0]const u8 { + return switch (ext) { + .c => ".c", + .cpp => ".cpp", + .cu => ".cu", + .h => ".h", + .m => ".m", + .mm => ".mm", + .ll => ".ll", + .bc => ".bc", + .assembly => ".s", + .assembly_with_cpp => ".S", + .shared_library => target.dynamicLibSuffix(), + .object => target.ofmt.fileExt(target.cpu.arch), + .static_library => target.staticLibSuffix(), + .zig => ".zig", + .def => ".def", + .unknown => "", + }; + } }; pub fn hasObjectExt(filename: []const u8) bool { diff --git a/src/main.zig b/src/main.zig index a680a5d89eba..2fd314def8d8 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3020,6 +3020,32 @@ fn buildOutputType( break :l global_cache_directory; }; + for (c_source_files.items) |*src| { + if (!mem.eql(u8, src.src_path, "-")) continue; + + const ext = src.ext orelse + fatal("-E or -x is required when reading from a non-regular file", .{}); + + // "-" is stdin. Dump it to a real file. + const sep = fs.path.sep_str; + const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-stdin{s}", .{ + std.crypto.random.int(u64), ext.canonicalName(target_info.target), + }); + try local_cache_directory.handle.makePath("tmp"); + // Note that in one of the happy paths, execve() is used to switch + // to clang in which case any cleanup logic that exists for this + // temporary file will not run and this temp file will be leaked. + // Oh well. It's a minor punishment for using `-x c` which nobody + // should be doing. Therefore, we make no effort to clean up. Using + // `-` for stdin as a source file always leaks a temp file. + var f = try local_cache_directory.handle.createFile(sub_path, .{}); + defer f.close(); + try f.writeFileAll(io.getStdIn(), .{}); + + // Convert `sub_path` to be relative to current working directory. + src.src_path = try local_cache_directory.join(arena, &.{sub_path}); + } + if (build_options.have_llvm and emit_asm != .no) { // LLVM has no way to set this non-globally. const argv = [_][*:0]const u8{ "zig (LLVM option parsing)", "--x86-asm-syntax=intel" };