diff options
| author | Motiejus Jakštys <motiejus@jakstys.lt> | 2022-11-14 04:15:04 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-01-13 21:38:11 -0500 |
| commit | 6b3f59c3a735ddbda3b3a62a0dfb5d55fa045f57 (patch) | |
| tree | 457c3ef57718e31cd6297bb3154dcb6177793027 /src/Compilation.zig | |
| parent | d813cef42af43b499fc5dc465e34f873008aaad0 (diff) | |
| download | zig-6b3f59c3a735ddbda3b3a62a0dfb5d55fa045f57.tar.gz zig-6b3f59c3a735ddbda3b3a62a0dfb5d55fa045f57.zip | |
zig run/cc: recognize "-x language"
This commit adds support for "-x language" for a couple of hand-picked
supported languages. There is no reason the list of supported languages
to not grow (e.g. add "c-header"), but I'd like to keep it small at the
start.
Alternative 1
-------------
I first tried to add a new type "Language", and then add that to the
`CSourceFile`. But oh boy what a change it turns out to be. So I am
keeping myself tied to FileExt and see what you folks think.
Alternative 2
-------------
I tried adding `Language: ?[]const u8` to `CSourceFile`. However, the
language/ext, whatever we want to call it, still needs to be interpreted
in the main loop: one kind of handling for source files, other kind of
handling for everything else.
Test case
---------
*standalone.c*
#include <iostream>
int main() {
std::cout << "elho\n";
}
Compile and run:
$ ./zig run -x c++ -lc++ standalone.c
elho
$ ./zig c++ -x c++ standalone.c -o standalone && ./standalone
elho
Fixes #10915
Diffstat (limited to 'src/Compilation.zig')
| -rw-r--r-- | src/Compilation.zig | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index cd0761315a..b0af925e29 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -192,12 +192,30 @@ pub const CRTFile = struct { } }; +// supported languages for "zig clang -x <lang>". +// Loosely based on llvm-project/clang/include/clang/Driver/Types.def +pub const LangToExt = std.ComptimeStringMap(FileExt, .{ + .{ "c", .c }, + .{ "c-header", .h }, + .{ "c++", .cpp }, + .{ "c++-header", .h }, + .{ "objective-c", .m }, + .{ "objective-c-header", .h }, + .{ "objective-c++", .mm }, + .{ "objective-c++-header", .h }, + .{ "assembler", .assembly }, + .{ "assembler-with-cpp", .assembly_with_cpp }, + .{ "cuda", .cu }, +}); + /// For passing to a C compiler. pub const CSourceFile = struct { src_path: []const u8, extra_flags: []const []const u8 = &.{}, /// Same as extra_flags except they are not added to the Cache hash. cache_exempt_flags: []const []const u8 = &.{}, + // this field is non-null iff language was explicitly set with "-x lang". + ext: ?FileExt = null, }; const Job = union(enum) { @@ -2612,6 +2630,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes for (comp.c_object_table.keys()) |key| { _ = try man.addFile(key.src.src_path, null); + man.hash.addOptional(key.src.ext); man.hash.addListOfBytes(key.src.extra_flags); } @@ -3926,14 +3945,23 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P break :e o_ext; }; const o_basename = try std.fmt.allocPrint(arena, "{s}{s}", .{ o_basename_noext, out_ext }); - - try argv.appendSlice(&[_][]const u8{ - self_exe_path, - "clang", - c_object.src.src_path, - }); - - const ext = classifyFileExt(c_object.src.src_path); + const ext = c_object.src.ext orelse classifyFileExt(c_object.src.src_path); + + 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) { + try argv.appendSlice(&[_][]const u8{ "-x", switch (ext) { + .assembly => "assembler", + .assembly_with_cpp => "assembler-with-cpp", + .c => "c", + .cpp => "c++", + .cu => "cuda", + .m => "objective-c", + .mm => "objective-c++", + else => fatal("language '{s}' is unsupported in this context", .{@tagName(ext)}), + } }); + } + try argv.append(c_object.src.src_path); // When all these flags are true, it means that the entire purpose of // this compilation is to perform a single zig cc operation. This means @@ -4395,7 +4423,7 @@ pub fn addCCArgs( } }, .shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig => {}, - .assembly => { + .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. @@ -4535,6 +4563,7 @@ pub const FileExt = enum { ll, bc, assembly, + assembly_with_cpp, shared_library, object, static_library, @@ -4549,6 +4578,7 @@ pub const FileExt = enum { .ll, .bc, .assembly, + .assembly_with_cpp, .shared_library, .object, .static_library, @@ -4588,10 +4618,6 @@ pub fn hasObjCppExt(filename: []const u8) bool { return mem.endsWith(u8, filename, ".mm"); } -pub fn hasAsmExt(filename: []const u8) bool { - return mem.endsWith(u8, filename, ".s") or mem.endsWith(u8, filename, ".S"); -} - pub fn hasSharedLibraryExt(filename: []const u8) bool { if (mem.endsWith(u8, filename, ".so") or mem.endsWith(u8, filename, ".dll") or @@ -4632,8 +4658,10 @@ pub fn classifyFileExt(filename: []const u8) FileExt { return .ll; } else if (mem.endsWith(u8, filename, ".bc")) { return .bc; - } else if (hasAsmExt(filename)) { + } else if (mem.endsWith(u8, filename, ".s")) { 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")) { |
