| author | |
| committer | |
| log | 7e61bdbaa48dcf3a280c5c9a6b10c26ef4f687d5 |
| tree | 0cb022593e96d3cbb08f0a6a1812e6a62ccc68b9 |
| parent | 340bb8198f58a6bdae3352314f4ff9bdb03d7c38 |
This is only relevant for ELF files.
I also fixed a bug where passing a zig source file to `zig cc` would
incorrectly punt to clang because it thought there were no positional
arguments.4 files changed, 32 insertions(+), 1 deletions(-)
src/Compilation.zig+2| ... | @@ -770,6 +770,7 @@ pub const InitOptions = struct { | ... | @@ -770,6 +770,7 @@ pub const InitOptions = struct { |
| 770 | /// infinite recursion. | 770 | /// infinite recursion. |
| 771 | skip_linker_dependencies: bool = false, | 771 | skip_linker_dependencies: bool = false, |
| 772 | parent_compilation_link_libc: bool = false, | 772 | parent_compilation_link_libc: bool = false, |
| 773 | hash_style: link.HashStyle = .both, | ||
| 773 | entry: ?[]const u8 = null, | 774 | entry: ?[]const u8 = null, |
| 774 | stack_size_override: ?u64 = null, | 775 | stack_size_override: ?u64 = null, |
| 775 | image_base_override: ?u64 = null, | 776 | image_base_override: ?u64 = null, |
| ... | @@ -1520,6 +1521,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1520,6 +1521,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1520 | .is_test = options.is_test, | 1521 | .is_test = options.is_test, |
| 1521 | .wasi_exec_model = wasi_exec_model, | 1522 | .wasi_exec_model = wasi_exec_model, |
| 1522 | .use_stage1 = use_stage1, | 1523 | .use_stage1 = use_stage1, |
| 1524 | .hash_style = options.hash_style, | ||
| 1523 | .enable_link_snapshots = options.enable_link_snapshots, | 1525 | .enable_link_snapshots = options.enable_link_snapshots, |
| 1524 | .native_darwin_sdk = options.native_darwin_sdk, | 1526 | .native_darwin_sdk = options.native_darwin_sdk, |
| 1525 | .install_name = options.install_name, | 1527 | .install_name = options.install_name, |
src/link.zig+3| ... | @@ -127,6 +127,7 @@ pub const Options = struct { | ... | @@ -127,6 +127,7 @@ pub const Options = struct { |
| 127 | disable_lld_caching: bool, | 127 | disable_lld_caching: bool, |
| 128 | is_test: bool, | 128 | is_test: bool, |
| 129 | use_stage1: bool, | 129 | use_stage1: bool, |
| 130 | hash_style: HashStyle, | ||
| 130 | major_subsystem_version: ?u32, | 131 | major_subsystem_version: ?u32, |
| 131 | minor_subsystem_version: ?u32, | 132 | minor_subsystem_version: ?u32, |
| 132 | gc_sections: ?bool = null, | 133 | gc_sections: ?bool = null, |
| ... | @@ -166,6 +167,8 @@ pub const Options = struct { | ... | @@ -166,6 +167,8 @@ pub const Options = struct { |
| 166 | } | 167 | } |
| 167 | }; | 168 | }; |
| 168 | 169 | ||
| 170 | pub const HashStyle = enum { sysv, gnu, both }; | ||
| 171 | |||
| 169 | pub const File = struct { | 172 | pub const File = struct { |
| 170 | tag: Tag, | 173 | tag: Tag, |
| 171 | options: Options, | 174 | options: Options, |
src/link/Elf.zig+7| ... | @@ -1337,6 +1337,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1337,6 +1337,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1337 | man.hash.add(self.base.options.z_noexecstack); | 1337 | man.hash.add(self.base.options.z_noexecstack); |
| 1338 | man.hash.add(self.base.options.z_now); | 1338 | man.hash.add(self.base.options.z_now); |
| 1339 | man.hash.add(self.base.options.z_relro); | 1339 | man.hash.add(self.base.options.z_relro); |
| 1340 | man.hash.add(self.base.options.hash_style); | ||
| 1340 | // strip does not need to go into the linker hash because it is part of the hash namespace | 1341 | // strip does not need to go into the linker hash because it is part of the hash namespace |
| 1341 | if (self.base.options.link_libc) { | 1342 | if (self.base.options.link_libc) { |
| 1342 | man.hash.add(self.base.options.libc_installation != null); | 1343 | man.hash.add(self.base.options.libc_installation != null); |
| ... | @@ -1448,6 +1449,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1448,6 +1449,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1448 | try argv.append(entry); | 1449 | try argv.append(entry); |
| 1449 | } | 1450 | } |
| 1450 | 1451 | ||
| 1452 | switch (self.base.options.hash_style) { | ||
| 1453 | .gnu => try argv.append("--hash-style=gnu"), | ||
| 1454 | .sysv => try argv.append("--hash-style=sysv"), | ||
| 1455 | .both => {}, // this is the default | ||
| 1456 | } | ||
| 1457 | |||
| 1451 | if (self.base.options.output_mode == .Exe) { | 1458 | if (self.base.options.output_mode == .Exe) { |
| 1452 | try argv.append("-z"); | 1459 | try argv.append("-z"); |
| 1453 | try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size})); | 1460 | try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size})); |
src/main.zig+20-1| ... | @@ -672,6 +672,7 @@ fn buildOutputType( | ... | @@ -672,6 +672,7 @@ fn buildOutputType( |
| 672 | var enable_link_snapshots: bool = false; | 672 | var enable_link_snapshots: bool = false; |
| 673 | var native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null; | 673 | var native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null; |
| 674 | var install_name: ?[]const u8 = null; | 674 | var install_name: ?[]const u8 = null; |
| 675 | var hash_style: link.HashStyle = .both; | ||
| 675 | 676 | ||
| 676 | // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names. | 677 | // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names. |
| 677 | // This array is populated by zig cc frontend and then has to be converted to zig-style | 678 | // This array is populated by zig cc frontend and then has to be converted to zig-style |
| ... | @@ -1778,6 +1779,19 @@ fn buildOutputType( | ... | @@ -1778,6 +1779,19 @@ fn buildOutputType( |
| 1778 | .path = linker_args.items[i], | 1779 | .path = linker_args.items[i], |
| 1779 | .must_link = true, | 1780 | .must_link = true, |
| 1780 | }); | 1781 | }); |
| 1782 | } else if (mem.eql(u8, arg, "-hash-style") or | ||
| 1783 | mem.eql(u8, arg, "--hash-style")) | ||
| 1784 | { | ||
| 1785 | i += 1; | ||
| 1786 | if (i >= linker_args.items.len) { | ||
| 1787 | fatal("expected linker arg after '{s}'", .{arg}); | ||
| 1788 | } | ||
| 1789 | const next_arg = linker_args.items[i]; | ||
| 1790 | hash_style = std.meta.stringToEnum(link.HashStyle, next_arg) orelse { | ||
| 1791 | fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{ | ||
| 1792 | next_arg, | ||
| 1793 | }); | ||
| 1794 | }; | ||
| 1781 | } else { | 1795 | } else { |
| 1782 | warn("unsupported linker arg: {s}", .{arg}); | 1796 | warn("unsupported linker arg: {s}", .{arg}); |
| 1783 | } | 1797 | } |
| ... | @@ -1847,8 +1861,12 @@ fn buildOutputType( | ... | @@ -1847,8 +1861,12 @@ fn buildOutputType( |
| 1847 | } | 1861 | } |
| 1848 | }, | 1862 | }, |
| 1849 | } | 1863 | } |
| 1850 | if (c_source_files.items.len == 0 and link_objects.items.len == 0) { | 1864 | if (c_source_files.items.len == 0 and |
| 1865 | link_objects.items.len == 0 and | ||
| 1866 | root_src_file == null) | ||
| 1867 | { | ||
| 1851 | // For example `zig cc` and no args should print the "no input files" message. | 1868 | // For example `zig cc` and no args should print the "no input files" message. |
| 1869 | // There could be other reasons to punt to clang, for example, --help. | ||
| 1852 | return punt_to_clang(arena, all_args); | 1870 | return punt_to_clang(arena, all_args); |
| 1853 | } | 1871 | } |
| 1854 | }, | 1872 | }, |
| ... | @@ -2491,6 +2509,7 @@ fn buildOutputType( | ... | @@ -2491,6 +2509,7 @@ fn buildOutputType( |
| 2491 | .use_lld = use_lld, | 2509 | .use_lld = use_lld, |
| 2492 | .use_clang = use_clang, | 2510 | .use_clang = use_clang, |
| 2493 | .use_stage1 = use_stage1, | 2511 | .use_stage1 = use_stage1, |
| 2512 | .hash_style = hash_style, | ||
| 2494 | .rdynamic = rdynamic, | 2513 | .rdynamic = rdynamic, |
| 2495 | .linker_script = linker_script, | 2514 | .linker_script = linker_script, |
| 2496 | .version_script = version_script, | 2515 | .version_script = version_script, |