| author | |
| committer | |
| log | 40c9ce2caf8f024a249b3524813eb495cf1341b3 |
| tree | 84dd4cfca306b33956746650155dd14d4e4fafac |
| parent | 35503b3d3fe1bfce19f1ea3e78a75ce87b0ed646 |
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 that | 2229 | /// to remind the programmer to update multiple related pieces of code that |
| 2228 | /// are in different locations. Bump this number when adding or deleting | 2230 | /// 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. |
| 2230 | pub const link_hash_implementation_version = 1; | 2232 | pub const link_hash_implementation_version = 2; |
| 2231 | 2233 | ||
| 2232 | fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void { | 2234 | fn 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(); |
| 2239 | 2241 | ||
| 2240 | comptime assert(link_hash_implementation_version == 1); | 2242 | comptime assert(link_hash_implementation_version == 2); |
| 2241 | 2243 | ||
| 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 | }; |
| 193 | 194 | ||
| 195 | pub const HashStyle = enum { sysv, gnu, both }; | ||
| 196 | |||
| 194 | pub const File = struct { | 197 | pub 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(); |
| 943 | 943 | ||
| 944 | comptime assert(Compilation.link_hash_implementation_version == 1); | 944 | comptime assert(Compilation.link_hash_implementation_version == 2); |
| 945 | 945 | ||
| 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(); |
| 1415 | 1415 | ||
| 1416 | comptime assert(Compilation.link_hash_implementation_version == 1); | 1416 | comptime assert(Compilation.link_hash_implementation_version == 2); |
| 1417 | 1417 | ||
| 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 namespace | 1451 | // 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 | } |
| 1560 | 1561 | ||
| 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(); |
| 499 | 499 | ||
| 500 | comptime assert(Compilation.link_hash_implementation_version == 1); | 500 | comptime assert(Compilation.link_hash_implementation_version == 2); |
| 501 | 501 | ||
| 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(); |
| 1205 | 1205 | ||
| 1206 | comptime assert(Compilation.link_hash_implementation_version == 1); | 1206 | comptime assert(Compilation.link_hash_implementation_version == 2); |
| 1207 | 1207 | ||
| 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; | ||
| 679 | 680 | ||
| 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-style | 682 | // 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, |