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/main.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/main.zig')
| -rw-r--r-- | src/main.zig | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/src/main.zig b/src/main.zig index f203bad968..2e97cc0214 100644 --- a/src/main.zig +++ b/src/main.zig @@ -391,6 +391,7 @@ const usage_build_generic = \\ -mcmodel=[default|tiny| Limit range of code and data virtual addresses \\ small|kernel| \\ medium|large] + \\ -x language Treat subsequent input files as having type <language> \\ -mred-zone Force-enable the "red-zone" \\ -mno-red-zone Force-disable the "red-zone" \\ -fomit-frame-pointer Omit the stack frame pointer @@ -913,6 +914,7 @@ fn buildOutputType( var cssan = ClangSearchSanitizer.init(gpa, &clang_argv); defer cssan.map.deinit(); + var file_ext: ?Compilation.FileExt = null; args_loop: while (args_iter.next()) |arg| { if (mem.startsWith(u8, arg, "@")) { // This is a "compiler response file". We must parse the file and treat its @@ -1401,6 +1403,15 @@ fn buildOutputType( try clang_argv.append(arg); } else if (mem.startsWith(u8, arg, "-I")) { try cssan.addIncludePath(.I, arg, arg[2..], true); + } else if (mem.eql(u8, arg, "-x")) { + const lang = args_iter.nextOrFatal(); + if (mem.eql(u8, lang, "none")) { + file_ext = null; + } else if (Compilation.LangToExt.get(lang)) |got_ext| { + file_ext = got_ext; + } else { + fatal("language not recognized: '{s}'", .{lang}); + } } else if (mem.startsWith(u8, arg, "-mexec-model=")) { wasi_exec_model = std.meta.stringToEnum(std.builtin.WasiExecModel, arg["-mexec-model=".len..]) orelse { fatal("expected [command|reactor] for -mexec-mode=[value], found '{s}'", .{arg["-mexec-model=".len..]}); @@ -1408,22 +1419,21 @@ fn buildOutputType( } else { fatal("unrecognized parameter: '{s}'", .{arg}); } - } else switch (Compilation.classifyFileExt(arg)) { - .object, .static_library, .shared_library => { - try link_objects.append(.{ .path = arg }); - }, - .assembly, .c, .cpp, .h, .ll, .bc, .m, .mm, .cu => { + } else switch (file_ext orelse + Compilation.classifyFileExt(arg)) { + .object, .static_library, .shared_library => try link_objects.append(.{ .path = arg }), + .assembly, .assembly_with_cpp, .c, .cpp, .h, .ll, .bc, .m, .mm, .cu => { try c_source_files.append(.{ .src_path = arg, .extra_flags = try arena.dupe([]const u8, extra_cflags.items), + // duped when parsing the args. + .ext = file_ext, }); }, .zig => { if (root_src_file) |other| { fatal("found another zig file '{s}' after root source file '{s}'", .{ arg, other }); - } else { - root_src_file = arg; - } + } else root_src_file = arg; }, .def, .unknown => { fatal("unrecognized file extension of parameter '{s}'", .{arg}); @@ -1464,6 +1474,7 @@ fn buildOutputType( var needed = false; var must_link = false; var force_static_libs = false; + var file_ext: ?Compilation.FileExt = null; while (it.has_next) { it.next() catch |err| { fatal("unable to parse command line parameters: {s}", .{@errorName(err)}); @@ -1484,32 +1495,39 @@ fn buildOutputType( .asm_only => c_out_mode = .assembly, // -S .preprocess_only => c_out_mode = .preprocessor, // -E .emit_llvm => emit_llvm = true, + .x => { + const lang = mem.sliceTo(it.only_arg, 0); + if (mem.eql(u8, lang, "none")) { + file_ext = null; + } else if (Compilation.LangToExt.get(lang)) |got_ext| { + file_ext = got_ext; + } else { + fatal("language not recognized: '{s}'", .{lang}); + } + }, .other => { try clang_argv.appendSlice(it.other_args); }, - .positional => { - const file_ext = Compilation.classifyFileExt(mem.sliceTo(it.only_arg, 0)); - switch (file_ext) { - .assembly, .c, .cpp, .ll, .bc, .h, .m, .mm, .cu => { - try c_source_files.append(.{ .src_path = it.only_arg }); - }, - .unknown, .shared_library, .object, .static_library => { - try link_objects.append(.{ - .path = it.only_arg, - .must_link = must_link, - }); - }, - .def => { - linker_module_definition_file = it.only_arg; - }, - .zig => { - if (root_src_file) |other| { - fatal("found another zig file '{s}' after root source file '{s}'", .{ it.only_arg, other }); - } else { - root_src_file = it.only_arg; - } - }, - } + .positional => switch (file_ext orelse + Compilation.classifyFileExt(mem.sliceTo(it.only_arg, 0))) { + .assembly, .assembly_with_cpp, .c, .cpp, .ll, .bc, .h, .m, .mm, .cu => { + try c_source_files.append(.{ + .src_path = it.only_arg, + .ext = file_ext, // duped while parsing the args. + }); + }, + .unknown, .shared_library, .object, .static_library => try link_objects.append(.{ + .path = it.only_arg, + .must_link = must_link, + }), + .def => { + linker_module_definition_file = it.only_arg; + }, + .zig => { + if (root_src_file) |other| { + fatal("found another zig file '{s}' after root source file '{s}'", .{ it.only_arg, other }); + } else root_src_file = it.only_arg; + }, }, .l => { // -l @@ -4860,6 +4878,7 @@ pub const ClangArgIterator = struct { o, c, m, + x, other, positional, l, |
