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-01-26 15:01:59-07:00
log40c9ce2caf8f024a249b3524813eb495cf1341b3
tree84dd4cfca306b33956746650155dd14d4e4fafac
parent35503b3d3fe1bfce19f1ea3e78a75ce87b0ed646

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.

7 files changed, 39 insertions(+), 7 deletions(-)

src/Compilation.zig+5-2
...@@ -791,6 +791,7 @@ pub const InitOptions = struct {...@@ -791,6 +791,7 @@ pub const InitOptions = struct {
791 /// infinite recursion.791 /// infinite recursion.
792 skip_linker_dependencies: bool = false,792 skip_linker_dependencies: bool = false,
793 parent_compilation_link_libc: bool = false,793 parent_compilation_link_libc: bool = false,
794 hash_style: link.HashStyle = .both,
794 entry: ?[]const u8 = null,795 entry: ?[]const u8 = null,
795 stack_size_override: ?u64 = null,796 stack_size_override: ?u64 = null,
796 image_base_override: ?u64 = null,797 image_base_override: ?u64 = null,
...@@ -1610,6 +1611,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1610,6 +1611,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1610 .is_test = options.is_test,1611 .is_test = options.is_test,
1611 .wasi_exec_model = wasi_exec_model,1612 .wasi_exec_model = wasi_exec_model,
1612 .use_stage1 = use_stage1,1613 .use_stage1 = use_stage1,
1614 .hash_style = options.hash_style,
1613 .enable_link_snapshots = options.enable_link_snapshots,1615 .enable_link_snapshots = options.enable_link_snapshots,
1614 .native_darwin_sdk = options.native_darwin_sdk,1616 .native_darwin_sdk = options.native_darwin_sdk,
1615 .install_name = options.install_name,1617 .install_name = options.install_name,
...@@ -2227,7 +2229,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo...@@ -2227,7 +2229,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo
2227/// to remind the programmer to update multiple related pieces of code that2229/// to remind the programmer to update multiple related pieces of code that
2228/// are in different locations. Bump this number when adding or deleting2230/// are in different locations. Bump this number when adding or deleting
2229/// anything from the link cache manifest.2231/// anything from the link cache manifest.
2230pub const link_hash_implementation_version = 1;2232pub const link_hash_implementation_version = 2;
22312233
2232fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void {2234fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void {
2233 const gpa = comp.gpa;2235 const gpa = comp.gpa;
...@@ -2237,7 +2239,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2237,7 +2239,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
2237 defer arena_allocator.deinit();2239 defer arena_allocator.deinit();
2238 const arena = arena_allocator.allocator();2240 const arena = arena_allocator.allocator();
22392241
2240 comptime assert(link_hash_implementation_version == 1);2242 comptime assert(link_hash_implementation_version == 2);
22412243
2242 if (comp.bin_file.options.module) |mod| {2244 if (comp.bin_file.options.module) |mod| {
2243 const main_zig_file = try mod.main_pkg.root_src_directory.join(arena, &[_][]const u8{2245 const main_zig_file = try mod.main_pkg.root_src_directory.join(arena, &[_][]const u8{
...@@ -2308,6 +2310,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2308,6 +2310,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
2308 man.hash.add(comp.bin_file.options.z_noexecstack);2310 man.hash.add(comp.bin_file.options.z_noexecstack);
2309 man.hash.add(comp.bin_file.options.z_now);2311 man.hash.add(comp.bin_file.options.z_now);
2310 man.hash.add(comp.bin_file.options.z_relro);2312 man.hash.add(comp.bin_file.options.z_relro);
2313 man.hash.add(comp.bin_file.options.hash_style);
2311 man.hash.add(comp.bin_file.options.include_compiler_rt);2314 man.hash.add(comp.bin_file.options.include_compiler_rt);
2312 if (comp.bin_file.options.link_libc) {2315 if (comp.bin_file.options.link_libc) {
2313 man.hash.add(comp.bin_file.options.libc_installation != null);2316 man.hash.add(comp.bin_file.options.libc_installation != null);
src/link.zig+3
...@@ -146,6 +146,7 @@ pub const Options = struct {...@@ -146,6 +146,7 @@ pub const Options = struct {
146 disable_lld_caching: bool,146 disable_lld_caching: bool,
147 is_test: bool,147 is_test: bool,
148 use_stage1: bool,148 use_stage1: bool,
149 hash_style: HashStyle,
149 major_subsystem_version: ?u32,150 major_subsystem_version: ?u32,
150 minor_subsystem_version: ?u32,151 minor_subsystem_version: ?u32,
151 gc_sections: ?bool = null,152 gc_sections: ?bool = null,
...@@ -191,6 +192,8 @@ pub const Options = struct {...@@ -191,6 +192,8 @@ pub const Options = struct {
191 }192 }
192};193};
193194
195pub const HashStyle = enum { sysv, gnu, both };
196
194pub const File = struct {197pub const File = struct {
195 tag: Tag,198 tag: Tag,
196 options: Options,199 options: Options,
src/link/Coff.zig+1-1
...@@ -941,7 +941,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {...@@ -941,7 +941,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
941 man = comp.cache_parent.obtain();941 man = comp.cache_parent.obtain();
942 self.base.releaseLock();942 self.base.releaseLock();
943943
944 comptime assert(Compilation.link_hash_implementation_version == 1);944 comptime assert(Compilation.link_hash_implementation_version == 2);
945945
946 for (self.base.options.objects) |obj| {946 for (self.base.options.objects) |obj| {
947 _ = try man.addFile(obj.path, null);947 _ = try man.addFile(obj.path, null);
src/link/Elf.zig+8-1
...@@ -1413,7 +1413,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1413,7 +1413,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1413 // We are about to obtain this lock, so here we give other processes a chance first.1413 // We are about to obtain this lock, so here we give other processes a chance first.
1414 self.base.releaseLock();1414 self.base.releaseLock();
14151415
1416 comptime assert(Compilation.link_hash_implementation_version == 1);1416 comptime assert(Compilation.link_hash_implementation_version == 2);
14171417
1418 try man.addOptionalFile(self.base.options.linker_script);1418 try man.addOptionalFile(self.base.options.linker_script);
1419 try man.addOptionalFile(self.base.options.version_script);1419 try man.addOptionalFile(self.base.options.version_script);
...@@ -1447,6 +1447,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1447,6 +1447,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1447 man.hash.add(self.base.options.z_noexecstack);1447 man.hash.add(self.base.options.z_noexecstack);
1448 man.hash.add(self.base.options.z_now);1448 man.hash.add(self.base.options.z_now);
1449 man.hash.add(self.base.options.z_relro);1449 man.hash.add(self.base.options.z_relro);
1450 man.hash.add(self.base.options.hash_style);
1450 // strip does not need to go into the linker hash because it is part of the hash namespace1451 // strip does not need to go into the linker hash because it is part of the hash namespace
1451 if (self.base.options.link_libc) {1452 if (self.base.options.link_libc) {
1452 man.hash.add(self.base.options.libc_installation != null);1453 man.hash.add(self.base.options.libc_installation != null);
...@@ -1558,6 +1559,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1558,6 +1559,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1558 try argv.append(entry);1559 try argv.append(entry);
1559 }1560 }
15601561
1562 switch (self.base.options.hash_style) {
1563 .gnu => try argv.append("--hash-style=gnu"),
1564 .sysv => try argv.append("--hash-style=sysv"),
1565 .both => {}, // this is the default
1566 }
1567
1561 if (self.base.options.output_mode == .Exe) {1568 if (self.base.options.output_mode == .Exe) {
1562 try argv.append("-z");1569 try argv.append("-z");
1563 try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}));1570 try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}));
src/link/MachO.zig+1-1
...@@ -497,7 +497,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {...@@ -497,7 +497,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
497 // We are about to obtain this lock, so here we give other processes a chance first.497 // We are about to obtain this lock, so here we give other processes a chance first.
498 self.base.releaseLock();498 self.base.releaseLock();
499499
500 comptime assert(Compilation.link_hash_implementation_version == 1);500 comptime assert(Compilation.link_hash_implementation_version == 2);
501501
502 for (self.base.options.objects) |obj| {502 for (self.base.options.objects) |obj| {
503 _ = try man.addFile(obj.path, null);503 _ = try man.addFile(obj.path, null);
src/link/Wasm.zig+1-1
...@@ -1203,7 +1203,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {...@@ -1203,7 +1203,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
1203 // We are about to obtain this lock, so here we give other processes a chance first.1203 // We are about to obtain this lock, so here we give other processes a chance first.
1204 self.base.releaseLock();1204 self.base.releaseLock();
12051205
1206 comptime assert(Compilation.link_hash_implementation_version == 1);1206 comptime assert(Compilation.link_hash_implementation_version == 2);
12071207
1208 for (self.base.options.objects) |obj| {1208 for (self.base.options.objects) |obj| {
1209 _ = try man.addFile(obj.path, null);1209 _ = try man.addFile(obj.path, null);
src/main.zig+20-1
...@@ -676,6 +676,7 @@ fn buildOutputType(...@@ -676,6 +676,7 @@ fn buildOutputType(
676 var enable_link_snapshots: bool = false;676 var enable_link_snapshots: bool = false;
677 var native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null;677 var native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null;
678 var install_name: ?[]const u8 = null;678 var install_name: ?[]const u8 = null;
679 var hash_style: link.HashStyle = .both;
679680
680 // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.681 // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.
681 // This array is populated by zig cc frontend and then has to be converted to zig-style682 // This array is populated by zig cc frontend and then has to be converted to zig-style
...@@ -1790,6 +1791,19 @@ fn buildOutputType(...@@ -1790,6 +1791,19 @@ fn buildOutputType(
1790 .path = linker_args.items[i],1791 .path = linker_args.items[i],
1791 .must_link = true,1792 .must_link = true,
1792 });1793 });
1794 } else if (mem.eql(u8, arg, "-hash-style") or
1795 mem.eql(u8, arg, "--hash-style"))
1796 {
1797 i += 1;
1798 if (i >= linker_args.items.len) {
1799 fatal("expected linker arg after '{s}'", .{arg});
1800 }
1801 const next_arg = linker_args.items[i];
1802 hash_style = std.meta.stringToEnum(link.HashStyle, next_arg) orelse {
1803 fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{
1804 next_arg,
1805 });
1806 };
1793 } else {1807 } else {
1794 warn("unsupported linker arg: {s}", .{arg});1808 warn("unsupported linker arg: {s}", .{arg});
1795 }1809 }
...@@ -1859,8 +1873,12 @@ fn buildOutputType(...@@ -1859,8 +1873,12 @@ fn buildOutputType(
1859 }1873 }
1860 },1874 },
1861 }1875 }
1862 if (c_source_files.items.len == 0 and link_objects.items.len == 0) {1876 if (c_source_files.items.len == 0 and
1877 link_objects.items.len == 0 and
1878 root_src_file == null)
1879 {
1863 // For example `zig cc` and no args should print the "no input files" message.1880 // For example `zig cc` and no args should print the "no input files" message.
1881 // There could be other reasons to punt to clang, for example, --help.
1864 return punt_to_clang(arena, all_args);1882 return punt_to_clang(arena, all_args);
1865 }1883 }
1866 },1884 },
...@@ -2503,6 +2521,7 @@ fn buildOutputType(...@@ -2503,6 +2521,7 @@ fn buildOutputType(
2503 .use_lld = use_lld,2521 .use_lld = use_lld,
2504 .use_clang = use_clang,2522 .use_clang = use_clang,
2505 .use_stage1 = use_stage1,2523 .use_stage1 = use_stage1,
2524 .hash_style = hash_style,
2506 .rdynamic = rdynamic,2525 .rdynamic = rdynamic,
2507 .linker_script = linker_script,2526 .linker_script = linker_script,
2508 .version_script = version_script,2527 .version_script = version_script,