authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-26 14:59:15-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-02 21:50:52-07:00
log7e61bdbaa48dcf3a280c5c9a6b10c26ef4f687d5
tree0cb022593e96d3cbb08f0a6a1812e6a62ccc68b9
parent340bb8198f58a6bdae3352314f4ff9bdb03d7c38

zig cc: add --hash-style linker parameter

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};
168169
170pub const HashStyle = enum { sysv, gnu, both };
171
169pub const File = struct {172pub 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 namespace1341 // 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 }
14501451
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;
675676
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-style678 // 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,