| author | |
| committer | |
| log | a337046832b936d912b6902e331cb58bdc513a2d |
| tree | 2475300223038682fad3477d5e59473b78992a5b |
| parent | aded86e6909e01dfb45b35204e9dedf6aabb3d58 |
This cleans up how the CLI parses and handles -E, -S, and -c.
Compilation explicitly acknowledges when it is being used to do C
preprocessing.
-S is properly translated to -fno-emit-bin -femit-asm but Compilation
does not yet handle -femit-asm.
There is not yet a mechanism for skipping the linking step when there is
only a single object file, and so to make this work we have to do a file
copy in link.flush() to copy the file from zig-cache into the output
directory.7 files changed, 130 insertions(+), 87 deletions(-)
BRANCH_TODO+1-3| ... | ... | @@ -1,5 +1,3 @@ |
| 1 | * make sure that `zig cc -o hello hello.c -target native-native-musl` and `zig build-exe hello.zig -lc -target native-native-musl` will share the same libc build. | |
| 2 | * zig cc as a preprocessor (-E) | |
| 3 | 1 | * tests passing with -Dskip-non-native |
| 4 | 2 | * `-ftime-report` |
| 5 | 3 | * -fstack-report print stack size diagnostics\n" |
| ... | ... | @@ -20,6 +18,7 @@ |
| 20 | 18 | * restore error messages for stage2_add_link_lib |
| 21 | 19 | * windows CUSTOMBUILD : error : unable to build compiler_rt: FileNotFound [D:\a\1\s\build\zig_install_lib_files.vcxproj] |
| 22 | 20 | * try building some software with zig cc |
| 21 | * implement support for -femit-asm | |
| 23 | 22 | |
| 24 | 23 | * implement proper parsing of clang stderr/stdout and exposing compile errors with the Compilation API |
| 25 | 24 | * implement proper parsing of LLD stderr/stdout and exposing compile errors with the Compilation API |
| ... | ... | @@ -57,4 +56,3 @@ |
| 57 | 56 | * make std.Progress support multithreaded |
| 58 | 57 | * update musl.zig static data to use native path separator in static data rather than replacing '/' at runtime |
| 59 | 58 | * linking hello world with LLD, lld is silently calling exit(1) instead of reporting ok=false. when run standalone the error message is: ld.lld: error: section [index 3] has a sh_offset (0x57000) + sh_size (0x68) that is greater than the file size (0x57060) |
| 60 |
src/Compilation.zig+28-10| ... | ... | @@ -49,6 +49,7 @@ sanitize_c: bool, |
| 49 | 49 | /// Otherwise we attempt to parse the error messages and expose them via the Compilation API. |
| 50 | 50 | /// This is `true` for `zig cc`, `zig c++`, and `zig translate-c`. |
| 51 | 51 | clang_passthrough_mode: bool, |
| 52 | clang_preprocessor_mode: ClangPreprocessorMode, | |
| 52 | 53 | /// Whether to print clang argvs to stdout. |
| 53 | 54 | verbose_cc: bool, |
| 54 | 55 | verbose_tokenize: bool, |
| ... | ... | @@ -271,6 +272,14 @@ pub const EmitLoc = struct { |
| 271 | 272 | basename: []const u8, |
| 272 | 273 | }; |
| 273 | 274 | |
| 275 | pub const ClangPreprocessorMode = enum { | |
| 276 | no, | |
| 277 | /// This means we are doing `zig cc -E -o <path>`. | |
| 278 | yes, | |
| 279 | /// This means we are doing `zig cc -E`. | |
| 280 | stdout, | |
| 281 | }; | |
| 282 | ||
| 274 | 283 | pub const InitOptions = struct { |
| 275 | 284 | zig_lib_directory: Directory, |
| 276 | 285 | local_cache_directory: Directory, |
| ... | ... | @@ -285,6 +294,8 @@ pub const InitOptions = struct { |
| 285 | 294 | emit_bin: ?EmitLoc, |
| 286 | 295 | /// `null` means to not emit a C header file. |
| 287 | 296 | emit_h: ?EmitLoc = null, |
| 297 | /// `null` means to not emit assembly. | |
| 298 | emit_asm: ?EmitLoc = null, | |
| 288 | 299 | link_mode: ?std.builtin.LinkMode = null, |
| 289 | 300 | dll_export_fns: ?bool = false, |
| 290 | 301 | /// Normally when using LLD to link, Zig uses a file named "lld.id" in the |
| ... | ... | @@ -349,6 +360,7 @@ pub const InitOptions = struct { |
| 349 | 360 | version: ?std.builtin.Version = null, |
| 350 | 361 | libc_installation: ?*const LibCInstallation = null, |
| 351 | 362 | machine_code_model: std.builtin.CodeModel = .default, |
| 363 | clang_preprocessor_mode: ClangPreprocessorMode = .no, | |
| 352 | 364 | /// This is for stage1 and should be deleted upon completion of self-hosting. |
| 353 | 365 | color: @import("main.zig").Color = .Auto, |
| 354 | 366 | test_filter: ?[]const u8 = null, |
| ... | ... | @@ -478,6 +490,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 478 | 490 | } else must_pic; |
| 479 | 491 | |
| 480 | 492 | if (options.emit_h != null) fatal("-femit-h not supported yet", .{}); // TODO |
| 493 | if (options.emit_asm != null) fatal("-femit-asm not supported yet", .{}); // TODO | |
| 481 | 494 | |
| 482 | 495 | const emit_bin = options.emit_bin orelse fatal("-fno-emit-bin not supported yet", .{}); // TODO |
| 483 | 496 | |
| ... | ... | @@ -750,6 +763,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 750 | 763 | .sanitize_c = sanitize_c, |
| 751 | 764 | .rand = options.rand, |
| 752 | 765 | .clang_passthrough_mode = options.clang_passthrough_mode, |
| 766 | .clang_preprocessor_mode = options.clang_preprocessor_mode, | |
| 753 | 767 | .verbose_cc = options.verbose_cc, |
| 754 | 768 | .verbose_tokenize = options.verbose_tokenize, |
| 755 | 769 | .verbose_ast = options.verbose_ast, |
| ... | ... | @@ -1215,7 +1229,6 @@ fn obtainCObjectCacheManifest(comp: *Compilation) Cache.Manifest { |
| 1215 | 1229 | // Only things that need to be added on top of the base hash, and only things |
| 1216 | 1230 | // that apply both to @cImport and compiling C objects. No linking stuff here! |
| 1217 | 1231 | // Also nothing that applies only to compiling .zig code. |
| 1218 | ||
| 1219 | 1232 | man.hash.add(comp.sanitize_c); |
| 1220 | 1233 | man.hash.addListOfBytes(comp.clang_argv); |
| 1221 | 1234 | man.hash.add(comp.bin_file.options.link_libcpp); |
| ... | ... | @@ -1381,6 +1394,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 1381 | 1394 | var man = comp.obtainCObjectCacheManifest(); |
| 1382 | 1395 | defer man.deinit(); |
| 1383 | 1396 | |
| 1397 | man.hash.add(comp.clang_preprocessor_mode); | |
| 1398 | ||
| 1384 | 1399 | _ = try man.addFile(c_object.src.src_path, null); |
| 1385 | 1400 | { |
| 1386 | 1401 | // Hash the extra flags, with special care to call addFile for file parameters. |
| ... | ... | @@ -1424,7 +1439,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 1424 | 1439 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); |
| 1425 | 1440 | defer zig_cache_tmp_dir.close(); |
| 1426 | 1441 | |
| 1427 | try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang", "-c" }); | |
| 1442 | try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang" }); | |
| 1428 | 1443 | |
| 1429 | 1444 | const ext = classifyFileExt(c_object.src.src_path); |
| 1430 | 1445 | const out_dep_path: ?[]const u8 = if (comp.disable_c_depfile or !ext.clangSupportsDepFile()) |
| ... | ... | @@ -1433,8 +1448,12 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 1433 | 1448 | try std.fmt.allocPrint(arena, "{}.d", .{out_obj_path}); |
| 1434 | 1449 | try comp.addCCArgs(arena, &argv, ext, out_dep_path); |
| 1435 | 1450 | |
| 1436 | try argv.append("-o"); | |
| 1437 | try argv.append(out_obj_path); | |
| 1451 | try argv.ensureCapacity(argv.items.len + 3); | |
| 1452 | switch (comp.clang_preprocessor_mode) { | |
| 1453 | .no => argv.appendSliceAssumeCapacity(&[_][]const u8{"-c", "-o", out_obj_path}), | |
| 1454 | .yes => argv.appendSliceAssumeCapacity(&[_][]const u8{"-E", "-o", out_obj_path}), | |
| 1455 | .stdout => argv.appendAssumeCapacity("-E"), | |
| 1456 | } | |
| 1438 | 1457 | |
| 1439 | 1458 | try argv.append(c_object.src.src_path); |
| 1440 | 1459 | try argv.appendSlice(c_object.src.extra_flags); |
| ... | ... | @@ -1460,6 +1479,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 1460 | 1479 | // TODO https://github.com/ziglang/zig/issues/6342 |
| 1461 | 1480 | std.process.exit(1); |
| 1462 | 1481 | } |
| 1482 | if (comp.clang_preprocessor_mode == .stdout) | |
| 1483 | std.process.exit(0); | |
| 1463 | 1484 | }, |
| 1464 | 1485 | else => std.process.exit(1), |
| 1465 | 1486 | } |
| ... | ... | @@ -1522,14 +1543,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 1522 | 1543 | break :blk digest; |
| 1523 | 1544 | }; |
| 1524 | 1545 | |
| 1525 | const components = if (comp.local_cache_directory.path) |p| | |
| 1526 | &[_][]const u8{ p, "o", &digest, o_basename } | |
| 1527 | else | |
| 1528 | &[_][]const u8{ "o", &digest, o_basename }; | |
| 1529 | ||
| 1530 | 1546 | c_object.status = .{ |
| 1531 | 1547 | .success = .{ |
| 1532 | .object_path = try std.fs.path.join(comp.gpa, components), | |
| 1548 | .object_path = try comp.local_cache_directory.join(comp.gpa, &[_][]const u8{ | |
| 1549 | "o", &digest, o_basename, | |
| 1550 | }), | |
| 1533 | 1551 | .lock = man.toOwnedLock(), |
| 1534 | 1552 | }, |
| 1535 | 1553 | }; |
src/clang_options_data.zig+9-5| ... | ... | @@ -7,7 +7,7 @@ flagpd1("CC"), |
| 7 | 7 | .{ |
| 8 | 8 | .name = "E", |
| 9 | 9 | .syntax = .flag, |
| 10 | .zig_equivalent = .pp_or_asm, | |
| 10 | .zig_equivalent = .preprocess_only, | |
| 11 | 11 | .pd1 = true, |
| 12 | 12 | .pd2 = false, |
| 13 | 13 | .psl = false, |
| ... | ... | @@ -95,7 +95,7 @@ flagpd1("Qy"), |
| 95 | 95 | .{ |
| 96 | 96 | .name = "S", |
| 97 | 97 | .syntax = .flag, |
| 98 | .zig_equivalent = .pp_or_asm, | |
| 98 | .zig_equivalent = .asm_only, | |
| 99 | 99 | .pd1 = true, |
| 100 | 100 | .pd2 = false, |
| 101 | 101 | .psl = false, |
| ... | ... | @@ -196,7 +196,7 @@ sepd1("Zlinker-input"), |
| 196 | 196 | .{ |
| 197 | 197 | .name = "E", |
| 198 | 198 | .syntax = .flag, |
| 199 | .zig_equivalent = .pp_or_asm, | |
| 199 | .zig_equivalent = .preprocess_only, | |
| 200 | 200 | .pd1 = true, |
| 201 | 201 | .pd2 = false, |
| 202 | 202 | .psl = true, |
| ... | ... | @@ -1477,7 +1477,7 @@ flagpsl("MT"), |
| 1477 | 1477 | .{ |
| 1478 | 1478 | .name = "assemble", |
| 1479 | 1479 | .syntax = .flag, |
| 1480 | .zig_equivalent = .pp_or_asm, | |
| 1480 | .zig_equivalent = .asm_only, | |
| 1481 | 1481 | .pd1 = false, |
| 1482 | 1482 | .pd2 = true, |
| 1483 | 1483 | .psl = false, |
| ... | ... | @@ -1805,7 +1805,7 @@ flagpsl("MT"), |
| 1805 | 1805 | .{ |
| 1806 | 1806 | .name = "preprocess", |
| 1807 | 1807 | .syntax = .flag, |
| 1808 | .zig_equivalent = .pp_or_asm, | |
| 1808 | .zig_equivalent = .preprocess_only, | |
| 1809 | 1809 | .pd1 = false, |
| 1810 | 1810 | .pd2 = true, |
| 1811 | 1811 | .psl = false, |
| ... | ... | @@ -3406,6 +3406,8 @@ flagpd1("mlong-double-128"), |
| 3406 | 3406 | flagpd1("mlong-double-64"), |
| 3407 | 3407 | flagpd1("mlong-double-80"), |
| 3408 | 3408 | flagpd1("mlongcall"), |
| 3409 | flagpd1("mlvi-cfi"), | |
| 3410 | flagpd1("mlvi-hardening"), | |
| 3409 | 3411 | flagpd1("mlwp"), |
| 3410 | 3412 | flagpd1("mlzcnt"), |
| 3411 | 3413 | flagpd1("mmadd4"), |
| ... | ... | @@ -3499,6 +3501,8 @@ flagpd1("mno-ldc1-sdc1"), |
| 3499 | 3501 | flagpd1("mno-local-sdata"), |
| 3500 | 3502 | flagpd1("mno-long-calls"), |
| 3501 | 3503 | flagpd1("mno-longcall"), |
| 3504 | flagpd1("mno-lvi-cfi"), | |
| 3505 | flagpd1("mno-lvi-hardening"), | |
| 3502 | 3506 | flagpd1("mno-lwp"), |
| 3503 | 3507 | flagpd1("mno-lzcnt"), |
| 3504 | 3508 | flagpd1("mno-madd4"), |
src/link.zig+19-2| ... | ... | @@ -1,16 +1,18 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const mem = std.mem; |
| 3 | 3 | const Allocator = std.mem.Allocator; |
| 4 | const fs = std.fs; | |
| 5 | const log = std.log.scoped(.link); | |
| 6 | const assert = std.debug.assert; | |
| 7 | ||
| 4 | 8 | const Compilation = @import("Compilation.zig"); |
| 5 | 9 | const Module = @import("Module.zig"); |
| 6 | const fs = std.fs; | |
| 7 | 10 | const trace = @import("tracy.zig").trace; |
| 8 | 11 | const Package = @import("Package.zig"); |
| 9 | 12 | const Type = @import("type.zig").Type; |
| 10 | 13 | const Cache = @import("Cache.zig"); |
| 11 | 14 | const build_options = @import("build_options"); |
| 12 | 15 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; |
| 13 | const log = std.log.scoped(.link); | |
| 14 | 16 | |
| 15 | 17 | pub const producer_string = if (std.builtin.is_test) "zig test" else "zig " ++ build_options.version; |
| 16 | 18 | |
| ... | ... | @@ -303,6 +305,21 @@ pub const File = struct { |
| 303 | 305 | /// Commit pending changes and write headers. Takes into account final output mode |
| 304 | 306 | /// and `use_lld`, not only `effectiveOutputMode`. |
| 305 | 307 | pub fn flush(base: *File, comp: *Compilation) !void { |
| 308 | if (comp.clang_preprocessor_mode == .yes) { | |
| 309 | // TODO: avoid extra link step when it's just 1 object file (the `zig cc -c` case) | |
| 310 | // Until then, we do `lld -r -o output.o input.o` even though the output is the same | |
| 311 | // as the input. For the preprocessing case (`zig cc -E -o foo`) we copy the file | |
| 312 | // to the final location. | |
| 313 | const full_out_path = try base.options.directory.join(comp.gpa, &[_][]const u8{ | |
| 314 | base.options.sub_path, | |
| 315 | }); | |
| 316 | defer comp.gpa.free(full_out_path); | |
| 317 | assert(comp.c_object_table.count() == 1); | |
| 318 | const the_entry = comp.c_object_table.items()[0]; | |
| 319 | const cached_pp_file_path = the_entry.key.status.success.object_path; | |
| 320 | try fs.cwd().copyFile(cached_pp_file_path, fs.cwd(), full_out_path, .{}); | |
| 321 | return; | |
| 322 | } | |
| 306 | 323 | const use_lld = build_options.have_llvm and base.options.use_lld; |
| 307 | 324 | if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static and |
| 308 | 325 | !base.options.target.isWasm()) |
src/link/Elf.zig+1-4| ... | ... | @@ -1401,10 +1401,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1401 | 1401 | try argv.append("-pie"); |
| 1402 | 1402 | } |
| 1403 | 1403 | |
| 1404 | const full_out_path = if (directory.path) |dir_path| | |
| 1405 | try fs.path.join(arena, &[_][]const u8{dir_path, self.base.options.sub_path}) | |
| 1406 | else | |
| 1407 | self.base.options.sub_path; | |
| 1404 | const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.sub_path}); | |
| 1408 | 1405 | try argv.append("-o"); |
| 1409 | 1406 | try argv.append(full_out_path); |
| 1410 | 1407 |
src/main.zig+54-45| ... | ... | @@ -327,6 +327,7 @@ pub fn buildOutputType( |
| 327 | 327 | var time_report = false; |
| 328 | 328 | var show_builtin = false; |
| 329 | 329 | var emit_bin: Emit = .yes_default_path; |
| 330 | var emit_asm: Emit = .no; | |
| 330 | 331 | var emit_zir: Emit = .no; |
| 331 | 332 | var target_arch_os_abi: []const u8 = "native"; |
| 332 | 333 | var target_mcpu: ?[]const u8 = null; |
| ... | ... | @@ -345,7 +346,6 @@ pub fn buildOutputType( |
| 345 | 346 | var want_stack_check: ?bool = null; |
| 346 | 347 | var want_valgrind: ?bool = null; |
| 347 | 348 | var rdynamic: bool = false; |
| 348 | var only_pp_or_asm = false; | |
| 349 | 349 | var linker_script: ?[]const u8 = null; |
| 350 | 350 | var version_script: ?[]const u8 = null; |
| 351 | 351 | var disable_c_depfile = false; |
| ... | ... | @@ -371,6 +371,7 @@ pub fn buildOutputType( |
| 371 | 371 | var override_global_cache_dir: ?[]const u8 = null; |
| 372 | 372 | var override_lib_dir: ?[]const u8 = null; |
| 373 | 373 | var main_pkg_path: ?[]const u8 = null; |
| 374 | var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no; | |
| 374 | 375 | |
| 375 | 376 | var system_libs = std.ArrayList([]const u8).init(gpa); |
| 376 | 377 | defer system_libs.deinit(); |
| ... | ... | @@ -752,7 +753,14 @@ pub fn buildOutputType( |
| 752 | 753 | ensure_libcpp_on_non_freestanding = arg_mode == .cpp; |
| 753 | 754 | want_native_include_dirs = true; |
| 754 | 755 | |
| 755 | var c_arg = false; | |
| 756 | const COutMode = enum { | |
| 757 | link, | |
| 758 | object, | |
| 759 | assembly, | |
| 760 | preprocessor, | |
| 761 | }; | |
| 762 | var c_out_mode: COutMode = .link; | |
| 763 | var out_path: ?[]const u8 = null; | |
| 756 | 764 | var is_shared_lib = false; |
| 757 | 765 | var linker_args = std.ArrayList([]const u8).init(arena); |
| 758 | 766 | var it = ClangArgIterator.init(arena, all_args); |
| ... | ... | @@ -762,12 +770,10 @@ pub fn buildOutputType( |
| 762 | 770 | }; |
| 763 | 771 | switch (it.zig_equivalent) { |
| 764 | 772 | .target => target_arch_os_abi = it.only_arg, // example: -target riscv64-linux-unknown |
| 765 | .o => { | |
| 766 | // -o | |
| 767 | emit_bin = .{ .yes = it.only_arg }; | |
| 768 | enable_cache = true; | |
| 769 | }, | |
| 770 | .c => c_arg = true, // -c | |
| 773 | .o => out_path = it.only_arg, // -o | |
| 774 | .c => c_out_mode = .object, // -c | |
| 775 | .asm_only => c_out_mode = .assembly, // -S | |
| 776 | .preprocess_only => c_out_mode = .preprocessor, // -E | |
| 771 | 777 | .other => { |
| 772 | 778 | try clang_argv.appendSlice(it.other_args); |
| 773 | 779 | }, |
| ... | ... | @@ -813,11 +819,6 @@ pub fn buildOutputType( |
| 813 | 819 | try linker_args.append(linker_arg); |
| 814 | 820 | } |
| 815 | 821 | }, |
| 816 | .pp_or_asm => { | |
| 817 | // This handles both -E and -S. | |
| 818 | only_pp_or_asm = true; | |
| 819 | try clang_argv.appendSlice(it.other_args); | |
| 820 | }, | |
| 821 | 822 | .optimize => { |
| 822 | 823 | // Alright, what release mode do they want? |
| 823 | 824 | if (mem.eql(u8, it.only_arg, "Os")) { |
| ... | ... | @@ -999,32 +1000,43 @@ pub fn buildOutputType( |
| 999 | 1000 | } |
| 1000 | 1001 | } |
| 1001 | 1002 | |
| 1002 | if (only_pp_or_asm) { | |
| 1003 | output_mode = .Obj; | |
| 1004 | fatal("TODO implement using zig cc as a preprocessor", .{}); | |
| 1005 | //// Transfer "link_objects" into c_source_files so that all those | |
| 1006 | //// args make it onto the command line. | |
| 1007 | //try c_source_files.appendSlice(link_objects.items); | |
| 1008 | //for (c_source_files.items) |c_source_file| { | |
| 1009 | // const src_path = switch (emit_bin) { | |
| 1010 | // .yes => |p| p, | |
| 1011 | // else => c_source_file.source_path, | |
| 1012 | // }; | |
| 1013 | // const basename = fs.path.basename(src_path); | |
| 1014 | // c_source_file.preprocessor_only_basename = basename; | |
| 1015 | //} | |
| 1016 | //emit_bin = .no; | |
| 1017 | } else if (!c_arg) { | |
| 1018 | output_mode = if (is_shared_lib) .Lib else .Exe; | |
| 1019 | switch (emit_bin) { | |
| 1020 | .no, .yes_default_path => { | |
| 1021 | emit_bin = .{ .yes = "a.out" }; | |
| 1022 | enable_cache = true; | |
| 1023 | }, | |
| 1024 | .yes => {}, | |
| 1025 | } | |
| 1026 | } else { | |
| 1027 | output_mode = .Obj; | |
| 1003 | switch (c_out_mode) { | |
| 1004 | .link => { | |
| 1005 | output_mode = if (is_shared_lib) .Lib else .Exe; | |
| 1006 | emit_bin = .{ .yes = out_path orelse "a.out" }; | |
| 1007 | enable_cache = true; | |
| 1008 | }, | |
| 1009 | .object => { | |
| 1010 | output_mode = .Obj; | |
| 1011 | if (out_path) |p| { | |
| 1012 | emit_bin = .{ .yes = p }; | |
| 1013 | } else { | |
| 1014 | emit_bin = .yes_default_path; | |
| 1015 | } | |
| 1016 | }, | |
| 1017 | .assembly => { | |
| 1018 | output_mode = .Obj; | |
| 1019 | emit_bin = .no; | |
| 1020 | if (out_path) |p| { | |
| 1021 | emit_asm = .{ .yes = p }; | |
| 1022 | } else { | |
| 1023 | emit_asm = .yes_default_path; | |
| 1024 | } | |
| 1025 | }, | |
| 1026 | .preprocessor => { | |
| 1027 | output_mode = .Obj; | |
| 1028 | // An error message is generated when there is more than 1 C source file. | |
| 1029 | if (c_source_files.items.len != 1) { | |
| 1030 | // For example `zig cc` and no args should print the "no input files" message. | |
| 1031 | return punt_to_clang(arena, all_args); | |
| 1032 | } | |
| 1033 | if (out_path) |p| { | |
| 1034 | emit_bin = .{ .yes = p }; | |
| 1035 | clang_preprocessor_mode = .yes; | |
| 1036 | } else { | |
| 1037 | clang_preprocessor_mode = .stdout; | |
| 1038 | } | |
| 1039 | }, | |
| 1028 | 1040 | } |
| 1029 | 1041 | if (c_source_files.items.len == 0 and link_objects.items.len == 0) { |
| 1030 | 1042 | // For example `zig cc` and no args should print the "no input files" message. |
| ... | ... | @@ -1407,6 +1419,7 @@ pub fn buildOutputType( |
| 1407 | 1419 | .self_exe_path = self_exe_path, |
| 1408 | 1420 | .rand = &default_prng.random, |
| 1409 | 1421 | .clang_passthrough_mode = arg_mode != .build, |
| 1422 | .clang_preprocessor_mode = clang_preprocessor_mode, | |
| 1410 | 1423 | .version = optional_version, |
| 1411 | 1424 | .libc_installation = if (libc_installation) |*lci| lci else null, |
| 1412 | 1425 | .verbose_cc = verbose_cc, |
| ... | ... | @@ -1453,11 +1466,6 @@ pub fn buildOutputType( |
| 1453 | 1466 | |
| 1454 | 1467 | try updateModule(gpa, comp, zir_out_path, hook); |
| 1455 | 1468 | |
| 1456 | if (build_options.have_llvm and only_pp_or_asm) { | |
| 1457 | // this may include dumping the output to stdout | |
| 1458 | fatal("TODO: implement `zig cc` when using it as a preprocessor", .{}); | |
| 1459 | } | |
| 1460 | ||
| 1461 | 1469 | if (build_options.is_stage1 and comp.stage1_lock != null and watch) { |
| 1462 | 1470 | std.log.warn("--watch is not recommended with the stage1 backend; it leaks memory and is not capable of incremental compilation", .{}); |
| 1463 | 1471 | } |
| ... | ... | @@ -2436,7 +2444,8 @@ pub const ClangArgIterator = struct { |
| 2436 | 2444 | shared, |
| 2437 | 2445 | rdynamic, |
| 2438 | 2446 | wl, |
| 2439 | pp_or_asm, | |
| 2447 | preprocess_only, | |
| 2448 | asm_only, | |
| 2440 | 2449 | optimize, |
| 2441 | 2450 | debug, |
| 2442 | 2451 | sanitize, |
tools/update_clang_options.zig+18-18| ... | ... | @@ -116,19 +116,19 @@ const known_options = [_]KnownOpt{ |
| 116 | 116 | }, |
| 117 | 117 | .{ |
| 118 | 118 | .name = "E", |
| 119 | .ident = "pp_or_asm", | |
| 119 | .ident = "preprocess_only", | |
| 120 | 120 | }, |
| 121 | 121 | .{ |
| 122 | 122 | .name = "preprocess", |
| 123 | .ident = "pp_or_asm", | |
| 123 | .ident = "preprocess_only", | |
| 124 | 124 | }, |
| 125 | 125 | .{ |
| 126 | 126 | .name = "S", |
| 127 | .ident = "pp_or_asm", | |
| 127 | .ident = "asm_only", | |
| 128 | 128 | }, |
| 129 | 129 | .{ |
| 130 | 130 | .name = "assemble", |
| 131 | .ident = "pp_or_asm", | |
| 131 | .ident = "asm_only", | |
| 132 | 132 | }, |
| 133 | 133 | .{ |
| 134 | 134 | .name = "O1", |
| ... | ... | @@ -346,7 +346,7 @@ pub fn main() anyerror!void { |
| 346 | 346 | for (blacklisted_options) |blacklisted_key| { |
| 347 | 347 | if (std.mem.eql(u8, blacklisted_key, kv.key)) continue :it_map; |
| 348 | 348 | } |
| 349 | if (kv.value.Object.get("Name").?.value.String.len == 0) continue; | |
| 349 | if (kv.value.Object.get("Name").?.String.len == 0) continue; | |
| 350 | 350 | try all_objects.append(&kv.value.Object); |
| 351 | 351 | } |
| 352 | 352 | } |
| ... | ... | @@ -365,11 +365,11 @@ pub fn main() anyerror!void { |
| 365 | 365 | ); |
| 366 | 366 | |
| 367 | 367 | for (all_objects.span()) |obj| { |
| 368 | const name = obj.get("Name").?.value.String; | |
| 368 | const name = obj.get("Name").?.String; | |
| 369 | 369 | var pd1 = false; |
| 370 | 370 | var pd2 = false; |
| 371 | 371 | var pslash = false; |
| 372 | for (obj.get("Prefixes").?.value.Array.span()) |prefix_json| { | |
| 372 | for (obj.get("Prefixes").?.Array.span()) |prefix_json| { | |
| 373 | 373 | const prefix = prefix_json.String; |
| 374 | 374 | if (std.mem.eql(u8, prefix, "-")) { |
| 375 | 375 | pd1 = true; |
| ... | ... | @@ -465,7 +465,7 @@ const Syntax = union(enum) { |
| 465 | 465 | self: Syntax, |
| 466 | 466 | comptime fmt: []const u8, |
| 467 | 467 | options: std.fmt.FormatOptions, |
| 468 | out_stream: var, | |
| 468 | out_stream: anytype, | |
| 469 | 469 | ) !void { |
| 470 | 470 | switch (self) { |
| 471 | 471 | .multi_arg => |n| return out_stream.print(".{{.{}={}}}", .{ @tagName(self), n }), |
| ... | ... | @@ -475,8 +475,8 @@ const Syntax = union(enum) { |
| 475 | 475 | }; |
| 476 | 476 | |
| 477 | 477 | fn objSyntax(obj: *json.ObjectMap) Syntax { |
| 478 | const num_args = @intCast(u8, obj.get("NumArgs").?.value.Integer); | |
| 479 | for (obj.get("!superclasses").?.value.Array.span()) |superclass_json| { | |
| 478 | const num_args = @intCast(u8, obj.get("NumArgs").?.Integer); | |
| 479 | for (obj.get("!superclasses").?.Array.span()) |superclass_json| { | |
| 480 | 480 | const superclass = superclass_json.String; |
| 481 | 481 | if (std.mem.eql(u8, superclass, "Joined")) { |
| 482 | 482 | return .joined; |
| ... | ... | @@ -510,19 +510,19 @@ fn objSyntax(obj: *json.ObjectMap) Syntax { |
| 510 | 510 | return .{ .multi_arg = num_args }; |
| 511 | 511 | } |
| 512 | 512 | } |
| 513 | const name = obj.get("Name").?.value.String; | |
| 513 | const name = obj.get("Name").?.String; | |
| 514 | 514 | if (std.mem.eql(u8, name, "<input>")) { |
| 515 | 515 | return .flag; |
| 516 | 516 | } else if (std.mem.eql(u8, name, "<unknown>")) { |
| 517 | 517 | return .flag; |
| 518 | 518 | } |
| 519 | const kind_def = obj.get("Kind").?.value.Object.get("def").?.value.String; | |
| 519 | const kind_def = obj.get("Kind").?.Object.get("def").?.String; | |
| 520 | 520 | if (std.mem.eql(u8, kind_def, "KIND_FLAG")) { |
| 521 | 521 | return .flag; |
| 522 | 522 | } |
| 523 | const key = obj.get("!name").?.value.String; | |
| 523 | const key = obj.get("!name").?.String; | |
| 524 | 524 | std.debug.warn("{} (key {}) has unrecognized superclasses:\n", .{ name, key }); |
| 525 | for (obj.get("!superclasses").?.value.Array.span()) |superclass_json| { | |
| 525 | for (obj.get("!superclasses").?.Array.span()) |superclass_json| { | |
| 526 | 526 | std.debug.warn(" {}\n", .{superclass_json.String}); |
| 527 | 527 | } |
| 528 | 528 | std.process.exit(1); |
| ... | ... | @@ -560,15 +560,15 @@ fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool { |
| 560 | 560 | } |
| 561 | 561 | |
| 562 | 562 | if (!a_match_with_eql and !b_match_with_eql) { |
| 563 | const a_name = a.get("Name").?.value.String; | |
| 564 | const b_name = b.get("Name").?.value.String; | |
| 563 | const a_name = a.get("Name").?.String; | |
| 564 | const b_name = b.get("Name").?.String; | |
| 565 | 565 | if (a_name.len != b_name.len) { |
| 566 | 566 | return a_name.len > b_name.len; |
| 567 | 567 | } |
| 568 | 568 | } |
| 569 | 569 | |
| 570 | const a_key = a.get("!name").?.value.String; | |
| 571 | const b_key = b.get("!name").?.value.String; | |
| 570 | const a_key = a.get("!name").?.String; | |
| 571 | const b_key = b.get("!name").?.String; | |
| 572 | 572 | return std.mem.lessThan(u8, a_key, b_key); |
| 573 | 573 | } |
| 574 | 574 |