| author | |
| committer | |
| log | 500dde32d5cf59f5700fb3f69ae6c7a0defd8a93 |
| tree | 135d6b28fdb7690a8ef117b378cec0f11392d1ee |
| parent | 07f52119de2a8bdb84389c73332e113cf12ac997 |
| signature |
13 files changed, 137 insertions(+), 127 deletions(-)
lib/std/build.zig+5-7| ... | @@ -1177,8 +1177,6 @@ pub const LibExeObjStep = struct { | ... | @@ -1177,8 +1177,6 @@ pub const LibExeObjStep = struct { |
| 1177 | /// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`. | 1177 | /// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`. |
| 1178 | glibc_multi_install_dir: ?[]const u8 = null, | 1178 | glibc_multi_install_dir: ?[]const u8 = null, |
| 1179 | 1179 | ||
| 1180 | dynamic_linker: ?[]const u8 = null, | ||
| 1181 | |||
| 1182 | /// Position Independent Code | 1180 | /// Position Independent Code |
| 1183 | force_pic: ?bool = null, | 1181 | force_pic: ?bool = null, |
| 1184 | 1182 | ||
| ... | @@ -1978,6 +1976,11 @@ pub const LibExeObjStep = struct { | ... | @@ -1978,6 +1976,11 @@ pub const LibExeObjStep = struct { |
| 1978 | } | 1976 | } |
| 1979 | try zig_args.append(mcpu_buffer.toSliceConst()); | 1977 | try zig_args.append(mcpu_buffer.toSliceConst()); |
| 1980 | } | 1978 | } |
| 1979 | |||
| 1980 | if (self.target.dynamic_linker.get()) |dynamic_linker| { | ||
| 1981 | try zig_args.append("--dynamic-linker"); | ||
| 1982 | try zig_args.append(dynamic_linker); | ||
| 1983 | } | ||
| 1981 | } | 1984 | } |
| 1982 | 1985 | ||
| 1983 | if (self.linker_script) |linker_script| { | 1986 | if (self.linker_script) |linker_script| { |
| ... | @@ -1985,11 +1988,6 @@ pub const LibExeObjStep = struct { | ... | @@ -1985,11 +1988,6 @@ pub const LibExeObjStep = struct { |
| 1985 | zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable; | 1988 | zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable; |
| 1986 | } | 1989 | } |
| 1987 | 1990 | ||
| 1988 | if (self.dynamic_linker) |dynamic_linker| { | ||
| 1989 | try zig_args.append("--dynamic-linker"); | ||
| 1990 | try zig_args.append(dynamic_linker); | ||
| 1991 | } | ||
| 1992 | |||
| 1993 | if (self.version_script) |version_script| { | 1991 | if (self.version_script) |version_script| { |
| 1994 | try zig_args.append("--version-script"); | 1992 | try zig_args.append("--version-script"); |
| 1995 | try zig_args.append(builder.pathFromRoot(version_script)); | 1993 | try zig_args.append(builder.pathFromRoot(version_script)); |
lib/std/target.zig+64-28| ... | @@ -1099,16 +1099,52 @@ pub const Target = struct { | ... | @@ -1099,16 +1099,52 @@ pub const Target = struct { |
| 1099 | } | 1099 | } |
| 1100 | } | 1100 | } |
| 1101 | 1101 | ||
| 1102 | pub const DynamicLinker = struct { | ||
| 1103 | /// Contains the memory used to store the dynamic linker path. This field should | ||
| 1104 | /// not be used directly. See `get` and `set`. This field exists so that this API requires no allocator. | ||
| 1105 | buffer: [255]u8 = undefined, | ||
| 1106 | |||
| 1107 | /// Used to construct the dynamic linker path. This field should not be used | ||
| 1108 | /// directly. See `get` and `set`. | ||
| 1109 | max_byte: ?u8 = null, | ||
| 1110 | |||
| 1111 | /// Asserts that the length is less than or equal to 255 bytes. | ||
| 1112 | pub fn init(dl_or_null: ?[]const u8) DynamicLinker { | ||
| 1113 | var result: DynamicLinker = undefined; | ||
| 1114 | result.set(dl_or_null); | ||
| 1115 | return result; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | /// The returned memory has the same lifetime as the `DynamicLinker`. | ||
| 1119 | pub fn get(self: *const DynamicLinker) ?[]const u8 { | ||
| 1120 | const m: usize = self.max_byte orelse return null; | ||
| 1121 | return self.buffer[0 .. m + 1]; | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | /// Asserts that the length is less than or equal to 255 bytes. | ||
| 1125 | pub fn set(self: *DynamicLinker, dl_or_null: ?[]const u8) void { | ||
| 1126 | if (dl_or_null) |dl| { | ||
| 1127 | mem.copy(u8, &self.buffer, dl); | ||
| 1128 | self.max_byte = @intCast(u8, dl.len - 1); | ||
| 1129 | } else { | ||
| 1130 | self.max_byte = null; | ||
| 1131 | } | ||
| 1132 | } | ||
| 1133 | }; | ||
| 1134 | |||
| 1102 | /// The result will be a byte index *pointing at the final byte*. In other words, length minus one. | 1135 | /// The result will be a byte index *pointing at the final byte*. In other words, length minus one. |
| 1103 | /// A return value of `null` means the concept of a dynamic linker is not meaningful for that target. | 1136 | /// A return value of `null` means the concept of a dynamic linker is not meaningful for that target. |
| 1104 | pub fn standardDynamicLinkerPath(self: Target, buffer: *[255]u8) ?u8 { | 1137 | pub fn standardDynamicLinkerPath(self: Target) DynamicLinker { |
| 1138 | var result: DynamicLinker = .{}; | ||
| 1105 | const S = struct { | 1139 | const S = struct { |
| 1106 | fn print(b: *[255]u8, comptime fmt: []const u8, args: var) u8 { | 1140 | fn print(r: *DynamicLinker, comptime fmt: []const u8, args: var) DynamicLinker { |
| 1107 | return @intCast(u8, (std.fmt.bufPrint(b, fmt, args) catch unreachable).len - 1); | 1141 | r.max_byte = @intCast(u8, (std.fmt.bufPrint(&r.buffer, fmt, args) catch unreachable).len - 1); |
| 1142 | return r.*; | ||
| 1108 | } | 1143 | } |
| 1109 | fn copy(b: *[255]u8, s: []const u8) u8 { | 1144 | fn copy(r: *DynamicLinker, s: []const u8) DynamicLinker { |
| 1110 | mem.copy(u8, b, s); | 1145 | mem.copy(u8, &r.buffer, s); |
| 1111 | return @intCast(u8, s.len - 1); | 1146 | r.max_byte = @intCast(u8, s.len - 1); |
| 1147 | return r.*; | ||
| 1112 | } | 1148 | } |
| 1113 | }; | 1149 | }; |
| 1114 | const print = S.print; | 1150 | const print = S.print; |
| ... | @@ -1116,7 +1152,7 @@ pub const Target = struct { | ... | @@ -1116,7 +1152,7 @@ pub const Target = struct { |
| 1116 | 1152 | ||
| 1117 | if (self.isAndroid()) { | 1153 | if (self.isAndroid()) { |
| 1118 | const suffix = if (self.cpu.arch.ptrBitWidth() == 64) "64" else ""; | 1154 | const suffix = if (self.cpu.arch.ptrBitWidth() == 64) "64" else ""; |
| 1119 | return print(buffer, "/system/bin/linker{}", .{suffix}); | 1155 | return print(&result, "/system/bin/linker{}", .{suffix}); |
| 1120 | } | 1156 | } |
| 1121 | 1157 | ||
| 1122 | if (self.isMusl()) { | 1158 | if (self.isMusl()) { |
| ... | @@ -1130,28 +1166,28 @@ pub const Target = struct { | ... | @@ -1130,28 +1166,28 @@ pub const Target = struct { |
| 1130 | else => |arch| @tagName(arch), | 1166 | else => |arch| @tagName(arch), |
| 1131 | }; | 1167 | }; |
| 1132 | const arch_suffix = if (is_arm and self.getFloatAbi() == .hard) "hf" else ""; | 1168 | const arch_suffix = if (is_arm and self.getFloatAbi() == .hard) "hf" else ""; |
| 1133 | return print(buffer, "/lib/ld-musl-{}{}.so.1", .{ arch_part, arch_suffix }); | 1169 | return print(&result, "/lib/ld-musl-{}{}.so.1", .{ arch_part, arch_suffix }); |
| 1134 | } | 1170 | } |
| 1135 | 1171 | ||
| 1136 | switch (self.os.tag) { | 1172 | switch (self.os.tag) { |
| 1137 | .freebsd => return copy(buffer, "/libexec/ld-elf.so.1"), | 1173 | .freebsd => return copy(&result, "/libexec/ld-elf.so.1"), |
| 1138 | .netbsd => return copy(buffer, "/libexec/ld.elf_so"), | 1174 | .netbsd => return copy(&result, "/libexec/ld.elf_so"), |
| 1139 | .dragonfly => return copy(buffer, "/libexec/ld-elf.so.2"), | 1175 | .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"), |
| 1140 | .linux => switch (self.cpu.arch) { | 1176 | .linux => switch (self.cpu.arch) { |
| 1141 | .i386, | 1177 | .i386, |
| 1142 | .sparc, | 1178 | .sparc, |
| 1143 | .sparcel, | 1179 | .sparcel, |
| 1144 | => return copy(buffer, "/lib/ld-linux.so.2"), | 1180 | => return copy(&result, "/lib/ld-linux.so.2"), |
| 1145 | 1181 | ||
| 1146 | .aarch64 => return copy(buffer, "/lib/ld-linux-aarch64.so.1"), | 1182 | .aarch64 => return copy(&result, "/lib/ld-linux-aarch64.so.1"), |
| 1147 | .aarch64_be => return copy(buffer, "/lib/ld-linux-aarch64_be.so.1"), | 1183 | .aarch64_be => return copy(&result, "/lib/ld-linux-aarch64_be.so.1"), |
| 1148 | .aarch64_32 => return copy(buffer, "/lib/ld-linux-aarch64_32.so.1"), | 1184 | .aarch64_32 => return copy(&result, "/lib/ld-linux-aarch64_32.so.1"), |
| 1149 | 1185 | ||
| 1150 | .arm, | 1186 | .arm, |
| 1151 | .armeb, | 1187 | .armeb, |
| 1152 | .thumb, | 1188 | .thumb, |
| 1153 | .thumbeb, | 1189 | .thumbeb, |
| 1154 | => return copy(buffer, switch (self.getFloatAbi()) { | 1190 | => return copy(&result, switch (self.getFloatAbi()) { |
| 1155 | .hard => "/lib/ld-linux-armhf.so.3", | 1191 | .hard => "/lib/ld-linux-armhf.so.3", |
| 1156 | else => "/lib/ld-linux.so.3", | 1192 | else => "/lib/ld-linux.so.3", |
| 1157 | }), | 1193 | }), |
| ... | @@ -1168,20 +1204,20 @@ pub const Target = struct { | ... | @@ -1168,20 +1204,20 @@ pub const Target = struct { |
| 1168 | }; | 1204 | }; |
| 1169 | const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008); | 1205 | const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008); |
| 1170 | const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1"; | 1206 | const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1"; |
| 1171 | return print(buffer, "/lib{}/{}", .{ lib_suffix, loader }); | 1207 | return print(&result, "/lib{}/{}", .{ lib_suffix, loader }); |
| 1172 | }, | 1208 | }, |
| 1173 | 1209 | ||
| 1174 | .powerpc => return copy(buffer, "/lib/ld.so.1"), | 1210 | .powerpc => return copy(&result, "/lib/ld.so.1"), |
| 1175 | .powerpc64, .powerpc64le => return copy(buffer, "/lib64/ld64.so.2"), | 1211 | .powerpc64, .powerpc64le => return copy(&result, "/lib64/ld64.so.2"), |
| 1176 | .s390x => return copy(buffer, "/lib64/ld64.so.1"), | 1212 | .s390x => return copy(&result, "/lib64/ld64.so.1"), |
| 1177 | .sparcv9 => return copy(buffer, "/lib64/ld-linux.so.2"), | 1213 | .sparcv9 => return copy(&result, "/lib64/ld-linux.so.2"), |
| 1178 | .x86_64 => return copy(buffer, switch (self.abi) { | 1214 | .x86_64 => return copy(&result, switch (self.abi) { |
| 1179 | .gnux32 => "/libx32/ld-linux-x32.so.2", | 1215 | .gnux32 => "/libx32/ld-linux-x32.so.2", |
| 1180 | else => "/lib64/ld-linux-x86-64.so.2", | 1216 | else => "/lib64/ld-linux-x86-64.so.2", |
| 1181 | }), | 1217 | }), |
| 1182 | 1218 | ||
| 1183 | .riscv32 => return copy(buffer, "/lib/ld-linux-riscv32-ilp32.so.1"), | 1219 | .riscv32 => return copy(&result, "/lib/ld-linux-riscv32-ilp32.so.1"), |
| 1184 | .riscv64 => return copy(buffer, "/lib/ld-linux-riscv64-lp64.so.1"), | 1220 | .riscv64 => return copy(&result, "/lib/ld-linux-riscv64-lp64.so.1"), |
| 1185 | 1221 | ||
| 1186 | // Architectures in this list have been verified as not having a standard | 1222 | // Architectures in this list have been verified as not having a standard |
| 1187 | // dynamic linker path. | 1223 | // dynamic linker path. |
| ... | @@ -1191,7 +1227,7 @@ pub const Target = struct { | ... | @@ -1191,7 +1227,7 @@ pub const Target = struct { |
| 1191 | .bpfeb, | 1227 | .bpfeb, |
| 1192 | .nvptx, | 1228 | .nvptx, |
| 1193 | .nvptx64, | 1229 | .nvptx64, |
| 1194 | => return null, | 1230 | => return result, |
| 1195 | 1231 | ||
| 1196 | // TODO go over each item in this list and either move it to the above list, or | 1232 | // TODO go over each item in this list and either move it to the above list, or |
| 1197 | // implement the standard dynamic linker path code for it. | 1233 | // implement the standard dynamic linker path code for it. |
| ... | @@ -1217,7 +1253,7 @@ pub const Target = struct { | ... | @@ -1217,7 +1253,7 @@ pub const Target = struct { |
| 1217 | .lanai, | 1253 | .lanai, |
| 1218 | .renderscript32, | 1254 | .renderscript32, |
| 1219 | .renderscript64, | 1255 | .renderscript64, |
| 1220 | => return null, | 1256 | => return result, |
| 1221 | }, | 1257 | }, |
| 1222 | 1258 | ||
| 1223 | // Operating systems in this list have been verified as not having a standard | 1259 | // Operating systems in this list have been verified as not having a standard |
| ... | @@ -1232,7 +1268,7 @@ pub const Target = struct { | ... | @@ -1232,7 +1268,7 @@ pub const Target = struct { |
| 1232 | .emscripten, | 1268 | .emscripten, |
| 1233 | .wasi, | 1269 | .wasi, |
| 1234 | .other, | 1270 | .other, |
| 1235 | => return null, | 1271 | => return result, |
| 1236 | 1272 | ||
| 1237 | // TODO go over each item in this list and either move it to the above list, or | 1273 | // TODO go over each item in this list and either move it to the above list, or |
| 1238 | // implement the standard dynamic linker path code for it. | 1274 | // implement the standard dynamic linker path code for it. |
| ... | @@ -1259,7 +1295,7 @@ pub const Target = struct { | ... | @@ -1259,7 +1295,7 @@ pub const Target = struct { |
| 1259 | .amdpal, | 1295 | .amdpal, |
| 1260 | .hermit, | 1296 | .hermit, |
| 1261 | .hurd, | 1297 | .hurd, |
| 1262 | => return null, | 1298 | => return result, |
| 1263 | } | 1299 | } |
| 1264 | } | 1300 | } |
| 1265 | }; | 1301 | }; |
lib/std/zig/cross_target.zig+14-3| ... | @@ -40,6 +40,10 @@ pub const CrossTarget = struct { | ... | @@ -40,6 +40,10 @@ pub const CrossTarget = struct { |
| 40 | /// If `isGnuLibC()` is `false`, this must be `null` and is ignored. | 40 | /// If `isGnuLibC()` is `false`, this must be `null` and is ignored. |
| 41 | glibc_version: ?SemVer = null, | 41 | glibc_version: ?SemVer = null, |
| 42 | 42 | ||
| 43 | /// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path | ||
| 44 | /// based on the `os_tag`. | ||
| 45 | dynamic_linker: DynamicLinker = DynamicLinker{}, | ||
| 46 | |||
| 43 | pub const OsVersion = union(enum) { | 47 | pub const OsVersion = union(enum) { |
| 44 | none: void, | 48 | none: void, |
| 45 | semver: SemVer, | 49 | semver: SemVer, |
| ... | @@ -48,6 +52,8 @@ pub const CrossTarget = struct { | ... | @@ -48,6 +52,8 @@ pub const CrossTarget = struct { |
| 48 | 52 | ||
| 49 | pub const SemVer = std.builtin.Version; | 53 | pub const SemVer = std.builtin.Version; |
| 50 | 54 | ||
| 55 | pub const DynamicLinker = Target.DynamicLinker; | ||
| 56 | |||
| 51 | pub fn fromTarget(target: Target) CrossTarget { | 57 | pub fn fromTarget(target: Target) CrossTarget { |
| 52 | var result: CrossTarget = .{ | 58 | var result: CrossTarget = .{ |
| 53 | .cpu_arch = target.cpu.arch, | 59 | .cpu_arch = target.cpu.arch, |
| ... | @@ -170,6 +176,10 @@ pub const CrossTarget = struct { | ... | @@ -170,6 +176,10 @@ pub const CrossTarget = struct { |
| 170 | /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline". | 176 | /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline". |
| 171 | cpu_features: ?[]const u8 = null, | 177 | cpu_features: ?[]const u8 = null, |
| 172 | 178 | ||
| 179 | /// Absolute path to dynamic linker, to override the default, which is either a natively | ||
| 180 | /// detected path, or a standard path. | ||
| 181 | dynamic_linker: ?[]const u8 = null, | ||
| 182 | |||
| 173 | /// If this is provided, the function will populate some information about parsing failures, | 183 | /// If this is provided, the function will populate some information about parsing failures, |
| 174 | /// so that user-friendly error messages can be delivered. | 184 | /// so that user-friendly error messages can be delivered. |
| 175 | diagnostics: ?*Diagnostics = null, | 185 | diagnostics: ?*Diagnostics = null, |
| ... | @@ -199,8 +209,9 @@ pub const CrossTarget = struct { | ... | @@ -199,8 +209,9 @@ pub const CrossTarget = struct { |
| 199 | var dummy_diags: ParseOptions.Diagnostics = undefined; | 209 | var dummy_diags: ParseOptions.Diagnostics = undefined; |
| 200 | const diags = args.diagnostics orelse &dummy_diags; | 210 | const diags = args.diagnostics orelse &dummy_diags; |
| 201 | 211 | ||
| 202 | // Start with everything initialized to default values. | 212 | var result: CrossTarget = .{ |
| 203 | var result: CrossTarget = .{}; | 213 | .dynamic_linker = DynamicLinker.init(args.dynamic_linker), |
| 214 | }; | ||
| 204 | 215 | ||
| 205 | var it = mem.separate(args.arch_os_abi, "-"); | 216 | var it = mem.separate(args.arch_os_abi, "-"); |
| 206 | const arch_name = it.next().?; | 217 | const arch_name = it.next().?; |
| ... | @@ -446,7 +457,7 @@ pub const CrossTarget = struct { | ... | @@ -446,7 +457,7 @@ pub const CrossTarget = struct { |
| 446 | return self.cpu_arch == null and self.cpu_model == null and | 457 | return self.cpu_arch == null and self.cpu_model == null and |
| 447 | self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and | 458 | self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and |
| 448 | self.os_tag == null and self.os_version_min == null and self.os_version_max == null and | 459 | self.os_tag == null and self.os_version_min == null and self.os_version_max == null and |
| 449 | self.abi == null; | 460 | self.abi == null and self.dynamic_linker.get() == null; |
| 450 | } | 461 | } |
| 451 | 462 | ||
| 452 | pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 { | 463 | pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 { |
lib/std/zig/system.zig+25-52| ... | @@ -168,14 +168,9 @@ pub const NativePaths = struct { | ... | @@ -168,14 +168,9 @@ pub const NativePaths = struct { |
| 168 | pub const NativeTargetInfo = struct { | 168 | pub const NativeTargetInfo = struct { |
| 169 | target: Target, | 169 | target: Target, |
| 170 | 170 | ||
| 171 | /// Contains the memory used to store the dynamic linker path. This field should | 171 | dynamic_linker: DynamicLinker = DynamicLinker{}, |
| 172 | /// not be used directly. See `dynamicLinker` and `setDynamicLinker`. This field | ||
| 173 | /// exists so that this API requires no allocator. | ||
| 174 | dynamic_linker_buffer: [255]u8 = undefined, | ||
| 175 | 172 | ||
| 176 | /// Used to construct the dynamic linker path. This field should not be used | 173 | pub const DynamicLinker = Target.DynamicLinker; |
| 177 | /// directly. See `dynamicLinker` and `setDynamicLinker`. | ||
| 178 | dynamic_linker_max: ?u8 = null, | ||
| 179 | 174 | ||
| 180 | pub const DetectError = error{ | 175 | pub const DetectError = error{ |
| 181 | OutOfMemory, | 176 | OutOfMemory, |
| ... | @@ -220,21 +215,6 @@ pub const NativeTargetInfo = struct { | ... | @@ -220,21 +215,6 @@ pub const NativeTargetInfo = struct { |
| 220 | return detectAbiAndDynamicLinker(allocator, cpu, os); | 215 | return detectAbiAndDynamicLinker(allocator, cpu, os); |
| 221 | } | 216 | } |
| 222 | 217 | ||
| 223 | /// The returned memory has the same lifetime as the `NativeTargetInfo`. | ||
| 224 | pub fn dynamicLinker(self: *const NativeTargetInfo) ?[]const u8 { | ||
| 225 | const m: usize = self.dynamic_linker_max orelse return null; | ||
| 226 | return self.dynamic_linker_buffer[0 .. m + 1]; | ||
| 227 | } | ||
| 228 | |||
| 229 | pub fn setDynamicLinker(self: *NativeTargetInfo, dl_or_null: ?[]const u8) void { | ||
| 230 | if (dl_or_null) |dl| { | ||
| 231 | mem.copy(u8, &self.dynamic_linker_buffer, dl); | ||
| 232 | self.dynamic_linker_max = @intCast(u8, dl.len - 1); | ||
| 233 | } else { | ||
| 234 | self.dynamic_linker_max = null; | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | /// First we attempt to use the executable's own binary. If it is dynamically | 218 | /// First we attempt to use the executable's own binary. If it is dynamically |
| 239 | /// linked, then it should answer both the C ABI question and the dynamic linker question. | 219 | /// linked, then it should answer both the C ABI question and the dynamic linker question. |
| 240 | /// If it is statically linked, then we try /usr/bin/env. If that does not provide the answer, then | 220 | /// If it is statically linked, then we try /usr/bin/env. If that does not provide the answer, then |
| ... | @@ -273,15 +253,14 @@ pub const NativeTargetInfo = struct { | ... | @@ -273,15 +253,14 @@ pub const NativeTargetInfo = struct { |
| 273 | .os = os, | 253 | .os = os, |
| 274 | .abi = abi, | 254 | .abi = abi, |
| 275 | }; | 255 | }; |
| 276 | const ld_info = &ld_info_list_buffer[ld_info_list_len]; | 256 | const ld = target.standardDynamicLinkerPath(); |
| 277 | ld_info_list_len += 1; | 257 | if (ld.get() == null) continue; |
| 278 | 258 | ||
| 279 | ld_info.* = .{ | 259 | ld_info_list_buffer[ld_info_list_len] = .{ |
| 280 | .ld_path_buffer = undefined, | 260 | .ld = ld, |
| 281 | .ld_path_max = undefined, | ||
| 282 | .abi = abi, | 261 | .abi = abi, |
| 283 | }; | 262 | }; |
| 284 | ld_info.ld_path_max = target.standardDynamicLinkerPath(&ld_info.ld_path_buffer) orelse continue; | 263 | ld_info_list_len += 1; |
| 285 | } | 264 | } |
| 286 | const ld_info_list = ld_info_list_buffer[0..ld_info_list_len]; | 265 | const ld_info_list = ld_info_list_buffer[0..ld_info_list_len]; |
| 287 | 266 | ||
| ... | @@ -298,7 +277,7 @@ pub const NativeTargetInfo = struct { | ... | @@ -298,7 +277,7 @@ pub const NativeTargetInfo = struct { |
| 298 | // This is O(N^M) but typical case here is N=2 and M=10. | 277 | // This is O(N^M) but typical case here is N=2 and M=10. |
| 299 | find_ld: for (lib_paths) |lib_path| { | 278 | find_ld: for (lib_paths) |lib_path| { |
| 300 | for (ld_info_list) |ld_info| { | 279 | for (ld_info_list) |ld_info| { |
| 301 | const standard_ld_basename = fs.path.basename(ld_info.ldPath()); | 280 | const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); |
| 302 | if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) { | 281 | if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) { |
| 303 | found_ld_info = ld_info; | 282 | found_ld_info = ld_info; |
| 304 | found_ld_path = lib_path; | 283 | found_ld_path = lib_path; |
| ... | @@ -329,8 +308,8 @@ pub const NativeTargetInfo = struct { | ... | @@ -329,8 +308,8 @@ pub const NativeTargetInfo = struct { |
| 329 | .os = os_adjusted, | 308 | .os = os_adjusted, |
| 330 | .abi = found_ld_info.abi, | 309 | .abi = found_ld_info.abi, |
| 331 | }, | 310 | }, |
| 311 | .dynamic_linker = DynamicLinker.init(found_ld_path), | ||
| 332 | }; | 312 | }; |
| 333 | result.setDynamicLinker(found_ld_path); | ||
| 334 | return result; | 313 | return result; |
| 335 | } | 314 | } |
| 336 | 315 | ||
| ... | @@ -472,18 +451,18 @@ pub const NativeTargetInfo = struct { | ... | @@ -472,18 +451,18 @@ pub const NativeTargetInfo = struct { |
| 472 | elf.PT_INTERP => { | 451 | elf.PT_INTERP => { |
| 473 | const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); | 452 | const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); |
| 474 | const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); | 453 | const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); |
| 475 | if (p_filesz > result.dynamic_linker_buffer.len) return error.NameTooLong; | 454 | if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong; |
| 476 | _ = try preadFull(env_file, result.dynamic_linker_buffer[0..p_filesz], p_offset, p_filesz); | 455 | _ = try preadFull(env_file, result.dynamic_linker.buffer[0..p_filesz], p_offset, p_filesz); |
| 477 | // PT_INTERP includes a null byte in p_filesz. | 456 | // PT_INTERP includes a null byte in p_filesz. |
| 478 | const len = p_filesz - 1; | 457 | const len = p_filesz - 1; |
| 479 | // dynamic_linker_max is "max", not "len". | 458 | // dynamic_linker.max_byte is "max", not "len". |
| 480 | // We know it will fit in u8 because we check against dynamic_linker_buffer.len above. | 459 | // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. |
| 481 | result.dynamic_linker_max = @intCast(u8, len - 1); | 460 | result.dynamic_linker.max_byte = @intCast(u8, len - 1); |
| 482 | 461 | ||
| 483 | // Use it to determine ABI. | 462 | // Use it to determine ABI. |
| 484 | const full_ld_path = result.dynamic_linker_buffer[0..len]; | 463 | const full_ld_path = result.dynamic_linker.buffer[0..len]; |
| 485 | for (ld_info_list) |ld_info| { | 464 | for (ld_info_list) |ld_info| { |
| 486 | const standard_ld_basename = fs.path.basename(ld_info.ldPath()); | 465 | const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); |
| 487 | if (std.mem.endsWith(u8, full_ld_path, standard_ld_basename)) { | 466 | if (std.mem.endsWith(u8, full_ld_path, standard_ld_basename)) { |
| 488 | result.target.abi = ld_info.abi; | 467 | result.target.abi = ld_info.abi; |
| 489 | break; | 468 | break; |
| ... | @@ -679,26 +658,20 @@ pub const NativeTargetInfo = struct { | ... | @@ -679,26 +658,20 @@ pub const NativeTargetInfo = struct { |
| 679 | } | 658 | } |
| 680 | 659 | ||
| 681 | fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os) !NativeTargetInfo { | 660 | fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os) !NativeTargetInfo { |
| 682 | var result: NativeTargetInfo = .{ | 661 | const target: Target = .{ |
| 683 | .target = .{ | 662 | .cpu = cpu, |
| 684 | .cpu = cpu, | 663 | .os = os, |
| 685 | .os = os, | 664 | .abi = Target.Abi.default(cpu.arch, os), |
| 686 | .abi = Target.Abi.default(cpu.arch, os), | 665 | }; |
| 687 | }, | 666 | return NativeTargetInfo{ |
| 667 | .target = target, | ||
| 668 | .dynamic_linker = target.standardDynamicLinkerPath(), | ||
| 688 | }; | 669 | }; |
| 689 | result.dynamic_linker_max = result.target.standardDynamicLinkerPath(&result.dynamic_linker_buffer); | ||
| 690 | return result; | ||
| 691 | } | 670 | } |
| 692 | 671 | ||
| 693 | const LdInfo = struct { | 672 | const LdInfo = struct { |
| 694 | ld_path_buffer: [255]u8, | 673 | ld: DynamicLinker, |
| 695 | ld_path_max: u8, | ||
| 696 | abi: Target.Abi, | 674 | abi: Target.Abi, |
| 697 | |||
| 698 | pub fn ldPath(self: *const LdInfo) []const u8 { | ||
| 699 | const m: usize = self.ld_path_max; | ||
| 700 | return self.ld_path_buffer[0 .. m + 1]; | ||
| 701 | } | ||
| 702 | }; | 675 | }; |
| 703 | 676 | ||
| 704 | fn elfInt(is_64: bool, need_bswap: bool, int_32: var, int_64: var) @TypeOf(int_64) { | 677 | fn elfInt(is_64: bool, need_bswap: bool, int_32: var, int_64: var) @TypeOf(int_64) { |
src-self-hosted/stage2.zig+8-7| ... | @@ -651,8 +651,9 @@ export fn stage2_target_parse( | ... | @@ -651,8 +651,9 @@ export fn stage2_target_parse( |
| 651 | target: *Stage2Target, | 651 | target: *Stage2Target, |
| 652 | zig_triple: ?[*:0]const u8, | 652 | zig_triple: ?[*:0]const u8, |
| 653 | mcpu: ?[*:0]const u8, | 653 | mcpu: ?[*:0]const u8, |
| 654 | dynamic_linker: ?[*:0]const u8, | ||
| 654 | ) Error { | 655 | ) Error { |
| 655 | stage2TargetParse(target, zig_triple, mcpu) catch |err| switch (err) { | 656 | stage2TargetParse(target, zig_triple, mcpu, dynamic_linker) catch |err| switch (err) { |
| 656 | error.OutOfMemory => return .OutOfMemory, | 657 | error.OutOfMemory => return .OutOfMemory, |
| 657 | error.UnknownArchitecture => return .UnknownArchitecture, | 658 | error.UnknownArchitecture => return .UnknownArchitecture, |
| 658 | error.UnknownOperatingSystem => return .UnknownOperatingSystem, | 659 | error.UnknownOperatingSystem => return .UnknownOperatingSystem, |
| ... | @@ -676,14 +677,17 @@ fn stage2TargetParse( | ... | @@ -676,14 +677,17 @@ fn stage2TargetParse( |
| 676 | stage1_target: *Stage2Target, | 677 | stage1_target: *Stage2Target, |
| 677 | zig_triple_oz: ?[*:0]const u8, | 678 | zig_triple_oz: ?[*:0]const u8, |
| 678 | mcpu_oz: ?[*:0]const u8, | 679 | mcpu_oz: ?[*:0]const u8, |
| 680 | dynamic_linker_oz: ?[*:0]const u8, | ||
| 679 | ) !void { | 681 | ) !void { |
| 680 | const target: CrossTarget = if (zig_triple_oz) |zig_triple_z| blk: { | 682 | const target: CrossTarget = if (zig_triple_oz) |zig_triple_z| blk: { |
| 681 | const zig_triple = mem.toSliceConst(u8, zig_triple_z); | 683 | const zig_triple = mem.toSliceConst(u8, zig_triple_z); |
| 682 | const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else null; | 684 | const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else null; |
| 685 | const dynamic_linker = if (dynamic_linker_oz) |dl_z| mem.toSliceConst(u8, dl_z) else null; | ||
| 683 | var diags: CrossTarget.ParseOptions.Diagnostics = .{}; | 686 | var diags: CrossTarget.ParseOptions.Diagnostics = .{}; |
| 684 | break :blk CrossTarget.parse(.{ | 687 | break :blk CrossTarget.parse(.{ |
| 685 | .arch_os_abi = zig_triple, | 688 | .arch_os_abi = zig_triple, |
| 686 | .cpu_features = mcpu, | 689 | .cpu_features = mcpu, |
| 690 | .dynamic_linker = dynamic_linker, | ||
| 687 | .diagnostics = &diags, | 691 | .diagnostics = &diags, |
| 688 | }) catch |err| switch (err) { | 692 | }) catch |err| switch (err) { |
| 689 | error.UnknownCpuModel => { | 693 | error.UnknownCpuModel => { |
| ... | @@ -1170,7 +1174,7 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) | ... | @@ -1170,7 +1174,7 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) |
| 1170 | if (cross_target.os_tag == null) { | 1174 | if (cross_target.os_tag == null) { |
| 1171 | adjusted_target.os = detected_info.target.os; | 1175 | adjusted_target.os = detected_info.target.os; |
| 1172 | 1176 | ||
| 1173 | if (detected_info.dynamicLinker()) |dl| { | 1177 | if (detected_info.dynamic_linker.get()) |dl| { |
| 1174 | have_native_dl = true; | 1178 | have_native_dl = true; |
| 1175 | dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); | 1179 | dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); |
| 1176 | } | 1180 | } |
| ... | @@ -1182,11 +1186,8 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) | ... | @@ -1182,11 +1186,8 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) |
| 1182 | } | 1186 | } |
| 1183 | } | 1187 | } |
| 1184 | if (!have_native_dl) { | 1188 | if (!have_native_dl) { |
| 1185 | var buf: [255]u8 = undefined; | 1189 | const dl = adjusted_target.standardDynamicLinkerPath(); |
| 1186 | dynamic_linker_ptr.* = if (adjusted_target.standardDynamicLinkerPath(&buf)) |m| | 1190 | dynamic_linker_ptr.* = if (dl.get()) |s| try mem.dupeZ(std.heap.c_allocator, u8, s) else null; |
| 1187 | try mem.dupeZ(std.heap.c_allocator, u8, buf[0 .. @as(usize, m) + 1]) | ||
| 1188 | else | ||
| 1189 | null; | ||
| 1190 | } | 1191 | } |
| 1191 | return adjusted_target; | 1192 | return adjusted_target; |
| 1192 | } | 1193 | } |
src/all_types.hpp-1| ... | @@ -2255,7 +2255,6 @@ struct CodeGen { | ... | @@ -2255,7 +2255,6 @@ struct CodeGen { |
| 2255 | Buf *test_name_prefix; | 2255 | Buf *test_name_prefix; |
| 2256 | Buf *zig_lib_dir; | 2256 | Buf *zig_lib_dir; |
| 2257 | Buf *zig_std_dir; | 2257 | Buf *zig_std_dir; |
| 2258 | Buf *dynamic_linker_path; | ||
| 2259 | Buf *version_script_path; | 2258 | Buf *version_script_path; |
| 2260 | 2259 | ||
| 2261 | const char **llvm_argv; | 2260 | const char **llvm_argv; |
src/codegen.cpp+3-16| ... | @@ -8832,19 +8832,6 @@ static void init(CodeGen *g) { | ... | @@ -8832,19 +8832,6 @@ static void init(CodeGen *g) { |
| 8832 | } | 8832 | } |
| 8833 | } | 8833 | } |
| 8834 | 8834 | ||
| 8835 | static void detect_dynamic_linker(CodeGen *g) { | ||
| 8836 | if (g->dynamic_linker_path != nullptr) | ||
| 8837 | return; | ||
| 8838 | if (!g->have_dynamic_link) | ||
| 8839 | return; | ||
| 8840 | if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic)) | ||
| 8841 | return; | ||
| 8842 | |||
| 8843 | if (g->zig_target->dynamic_linker != nullptr) { | ||
| 8844 | g->dynamic_linker_path = buf_create_from_str(g->zig_target->dynamic_linker); | ||
| 8845 | } | ||
| 8846 | } | ||
| 8847 | |||
| 8848 | static void detect_libc(CodeGen *g) { | 8835 | static void detect_libc(CodeGen *g) { |
| 8849 | Error err; | 8836 | Error err; |
| 8850 | 8837 | ||
| ... | @@ -10285,6 +10272,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -10285,6 +10272,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 10285 | cache_int(ch, g->zig_target->glibc_or_darwin_version->minor); | 10272 | cache_int(ch, g->zig_target->glibc_or_darwin_version->minor); |
| 10286 | cache_int(ch, g->zig_target->glibc_or_darwin_version->patch); | 10273 | cache_int(ch, g->zig_target->glibc_or_darwin_version->patch); |
| 10287 | } | 10274 | } |
| 10275 | if (g->zig_target->dynamic_linker != nullptr) { | ||
| 10276 | cache_str(ch, g->zig_target->dynamic_linker); | ||
| 10277 | } | ||
| 10288 | cache_int(ch, detect_subsystem(g)); | 10278 | cache_int(ch, detect_subsystem(g)); |
| 10289 | cache_bool(ch, g->strip_debug_symbols); | 10279 | cache_bool(ch, g->strip_debug_symbols); |
| 10290 | cache_bool(ch, g->is_test_build); | 10280 | cache_bool(ch, g->is_test_build); |
| ... | @@ -10325,7 +10315,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -10325,7 +10315,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 10325 | cache_str(ch, g->libc->msvc_lib_dir); | 10315 | cache_str(ch, g->libc->msvc_lib_dir); |
| 10326 | cache_str(ch, g->libc->kernel32_lib_dir); | 10316 | cache_str(ch, g->libc->kernel32_lib_dir); |
| 10327 | } | 10317 | } |
| 10328 | cache_buf_opt(ch, g->dynamic_linker_path); | ||
| 10329 | cache_buf_opt(ch, g->version_script_path); | 10318 | cache_buf_opt(ch, g->version_script_path); |
| 10330 | 10319 | ||
| 10331 | // gen_c_objects appends objects to g->link_objects which we want to include in the hash | 10320 | // gen_c_objects appends objects to g->link_objects which we want to include in the hash |
| ... | @@ -10422,7 +10411,6 @@ void codegen_build_and_link(CodeGen *g) { | ... | @@ -10422,7 +10411,6 @@ void codegen_build_and_link(CodeGen *g) { |
| 10422 | g->have_err_ret_tracing = detect_err_ret_tracing(g); | 10411 | g->have_err_ret_tracing = detect_err_ret_tracing(g); |
| 10423 | g->have_sanitize_c = detect_sanitize_c(g); | 10412 | g->have_sanitize_c = detect_sanitize_c(g); |
| 10424 | detect_libc(g); | 10413 | detect_libc(g); |
| 10425 | detect_dynamic_linker(g); | ||
| 10426 | 10414 | ||
| 10427 | Buf digest = BUF_INIT; | 10415 | Buf digest = BUF_INIT; |
| 10428 | if (g->enable_cache) { | 10416 | if (g->enable_cache) { |
| ... | @@ -10619,7 +10607,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o | ... | @@ -10619,7 +10607,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o |
| 10619 | child_gen->verbose_cc = parent_gen->verbose_cc; | 10607 | child_gen->verbose_cc = parent_gen->verbose_cc; |
| 10620 | child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features; | 10608 | child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features; |
| 10621 | child_gen->llvm_argv = parent_gen->llvm_argv; | 10609 | child_gen->llvm_argv = parent_gen->llvm_argv; |
| 10622 | child_gen->dynamic_linker_path = parent_gen->dynamic_linker_path; | ||
| 10623 | 10610 | ||
| 10624 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); | 10611 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); |
| 10625 | child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled; | 10612 | child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled; |
src/link.cpp+2-2| ... | @@ -1751,9 +1751,9 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -1751,9 +1751,9 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1751 | } | 1751 | } |
| 1752 | 1752 | ||
| 1753 | if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) { | 1753 | if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) { |
| 1754 | assert(g->dynamic_linker_path != nullptr); | 1754 | assert(g->zig_target->dynamic_linker != nullptr); |
| 1755 | lj->args.append("-dynamic-linker"); | 1755 | lj->args.append("-dynamic-linker"); |
| 1756 | lj->args.append(buf_ptr(g->dynamic_linker_path)); | 1756 | lj->args.append(g->zig_target->dynamic_linker); |
| 1757 | } | 1757 | } |
| 1758 | } | 1758 | } |
| 1759 | 1759 |
src/main.cpp+5-6| ... | @@ -401,7 +401,7 @@ static int main0(int argc, char **argv) { | ... | @@ -401,7 +401,7 @@ static int main0(int argc, char **argv) { |
| 401 | bool link_eh_frame_hdr = false; | 401 | bool link_eh_frame_hdr = false; |
| 402 | ErrColor color = ErrColorAuto; | 402 | ErrColor color = ErrColorAuto; |
| 403 | CacheOpt enable_cache = CacheOptAuto; | 403 | CacheOpt enable_cache = CacheOptAuto; |
| 404 | Buf *dynamic_linker = nullptr; | 404 | const char *dynamic_linker = nullptr; |
| 405 | const char *libc_txt = nullptr; | 405 | const char *libc_txt = nullptr; |
| 406 | ZigList<const char *> clang_argv = {0}; | 406 | ZigList<const char *> clang_argv = {0}; |
| 407 | ZigList<const char *> lib_dirs = {0}; | 407 | ZigList<const char *> lib_dirs = {0}; |
| ... | @@ -496,7 +496,7 @@ static int main0(int argc, char **argv) { | ... | @@ -496,7 +496,7 @@ static int main0(int argc, char **argv) { |
| 496 | os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); | 496 | os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); |
| 497 | 497 | ||
| 498 | ZigTarget target; | 498 | ZigTarget target; |
| 499 | if ((err = target_parse_triple(&target, "native", nullptr))) { | 499 | if ((err = target_parse_triple(&target, "native", nullptr, nullptr))) { |
| 500 | fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); | 500 | fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); |
| 501 | return EXIT_FAILURE; | 501 | return EXIT_FAILURE; |
| 502 | } | 502 | } |
| ... | @@ -766,7 +766,7 @@ static int main0(int argc, char **argv) { | ... | @@ -766,7 +766,7 @@ static int main0(int argc, char **argv) { |
| 766 | } else if (strcmp(arg, "--name") == 0) { | 766 | } else if (strcmp(arg, "--name") == 0) { |
| 767 | out_name = argv[i]; | 767 | out_name = argv[i]; |
| 768 | } else if (strcmp(arg, "--dynamic-linker") == 0) { | 768 | } else if (strcmp(arg, "--dynamic-linker") == 0) { |
| 769 | dynamic_linker = buf_create_from_str(argv[i]); | 769 | dynamic_linker = argv[i]; |
| 770 | } else if (strcmp(arg, "--libc") == 0) { | 770 | } else if (strcmp(arg, "--libc") == 0) { |
| 771 | libc_txt = argv[i]; | 771 | libc_txt = argv[i]; |
| 772 | } else if (strcmp(arg, "-D") == 0) { | 772 | } else if (strcmp(arg, "-D") == 0) { |
| ... | @@ -968,7 +968,7 @@ static int main0(int argc, char **argv) { | ... | @@ -968,7 +968,7 @@ static int main0(int argc, char **argv) { |
| 968 | init_all_targets(); | 968 | init_all_targets(); |
| 969 | 969 | ||
| 970 | ZigTarget target; | 970 | ZigTarget target; |
| 971 | if ((err = target_parse_triple(&target, target_string, mcpu))) { | 971 | if ((err = target_parse_triple(&target, target_string, mcpu, dynamic_linker))) { |
| 972 | fprintf(stderr, "invalid target: %s\n" | 972 | fprintf(stderr, "invalid target: %s\n" |
| 973 | "See `%s targets` to display valid targets.\n", err_str(err), arg0); | 973 | "See `%s targets` to display valid targets.\n", err_str(err), arg0); |
| 974 | return print_error_usage(arg0); | 974 | return print_error_usage(arg0); |
| ... | @@ -1193,7 +1193,6 @@ static int main0(int argc, char **argv) { | ... | @@ -1193,7 +1193,6 @@ static int main0(int argc, char **argv) { |
| 1193 | 1193 | ||
| 1194 | codegen_set_strip(g, strip); | 1194 | codegen_set_strip(g, strip); |
| 1195 | g->is_dynamic = is_dynamic; | 1195 | g->is_dynamic = is_dynamic; |
| 1196 | g->dynamic_linker_path = dynamic_linker; | ||
| 1197 | g->verbose_tokenize = verbose_tokenize; | 1196 | g->verbose_tokenize = verbose_tokenize; |
| 1198 | g->verbose_ast = verbose_ast; | 1197 | g->verbose_ast = verbose_ast; |
| 1199 | g->verbose_link = verbose_link; | 1198 | g->verbose_link = verbose_link; |
| ... | @@ -1320,7 +1319,7 @@ static int main0(int argc, char **argv) { | ... | @@ -1320,7 +1319,7 @@ static int main0(int argc, char **argv) { |
| 1320 | return main_exit(root_progress_node, EXIT_SUCCESS); | 1319 | return main_exit(root_progress_node, EXIT_SUCCESS); |
| 1321 | } else if (cmd == CmdTest) { | 1320 | } else if (cmd == CmdTest) { |
| 1322 | ZigTarget native; | 1321 | ZigTarget native; |
| 1323 | if ((err = target_parse_triple(&native, "native", nullptr))) { | 1322 | if ((err = target_parse_triple(&native, "native", nullptr, nullptr))) { |
| 1324 | fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); | 1323 | fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); |
| 1325 | return EXIT_FAILURE; | 1324 | return EXIT_FAILURE; |
| 1326 | } | 1325 | } |
src/stage2.cpp+6-1| ... | @@ -191,7 +191,9 @@ static void get_native_target(ZigTarget *target) { | ... | @@ -191,7 +191,9 @@ static void get_native_target(ZigTarget *target) { |
| 191 | } | 191 | } |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu) { | 194 | Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, |
| 195 | const char *dynamic_linker) | ||
| 196 | { | ||
| 195 | Error err; | 197 | Error err; |
| 196 | 198 | ||
| 197 | if (zig_triple == nullptr) { | 199 | if (zig_triple == nullptr) { |
| ... | @@ -249,6 +251,9 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons | ... | @@ -249,6 +251,9 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons |
| 249 | target->cache_hash = "\n\n"; | 251 | target->cache_hash = "\n\n"; |
| 250 | } | 252 | } |
| 251 | 253 | ||
| 254 | if (dynamic_linker != nullptr) { | ||
| 255 | target->dynamic_linker = dynamic_linker; | ||
| 256 | } | ||
| 252 | return ErrorNone; | 257 | return ErrorNone; |
| 253 | } | 258 | } |
| 254 | 259 |
src/stage2.h+2-1| ... | @@ -298,7 +298,8 @@ struct ZigTarget { | ... | @@ -298,7 +298,8 @@ struct ZigTarget { |
| 298 | }; | 298 | }; |
| 299 | 299 | ||
| 300 | // ABI warning | 300 | // ABI warning |
| 301 | ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu); | 301 | ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, |
| 302 | const char *dynamic_linker); | ||
| 302 | 303 | ||
| 303 | 304 | ||
| 304 | // ABI warning | 305 | // ABI warning |
src/target.cpp+2-2| ... | @@ -410,8 +410,8 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si | ... | @@ -410,8 +410,8 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si |
| 410 | return ErrorUnknownABI; | 410 | return ErrorUnknownABI; |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu) { | 413 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker) { |
| 414 | return stage2_target_parse(target, triple, mcpu); | 414 | return stage2_target_parse(target, triple, mcpu, dynamic_linker); |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | const char *target_arch_name(ZigLLVM_ArchType arch) { | 417 | const char *target_arch_name(ZigLLVM_ArchType arch) { |
src/target.hpp+1-1| ... | @@ -41,7 +41,7 @@ enum CIntType { | ... | @@ -41,7 +41,7 @@ enum CIntType { |
| 41 | CIntTypeCount, | 41 | CIntTypeCount, |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu); | 44 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker); |
| 45 | Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len); | 45 | Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len); |
| 46 | Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); | 46 | Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); |
| 47 | Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); | 47 | Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); |