| author | |
| committer | |
| log | d1820d2a3ec3d83500126462304f4bf646593c21 |
| tree | 1c5e193da521ad2299f628a0b8b8dd5c7c1f94d4 |
| parent | 328280b566e13e11a1e1e9cb28f3670b7cc8c030 |
9 files changed, 21 insertions(+), 1271 deletions(-)
lib/compiler/aro/aro.zig-1| ... | @@ -37,6 +37,5 @@ test { | ... | @@ -37,6 +37,5 @@ test { |
| 37 | _ = @import("aro/Preprocessor.zig"); | 37 | _ = @import("aro/Preprocessor.zig"); |
| 38 | _ = @import("aro/target.zig"); | 38 | _ = @import("aro/target.zig"); |
| 39 | _ = @import("aro/Tokenizer.zig"); | 39 | _ = @import("aro/Tokenizer.zig"); |
| 40 | _ = @import("aro/toolchains/Linux.zig"); | ||
| 41 | _ = @import("aro/Value.zig"); | 40 | _ = @import("aro/Value.zig"); |
| 42 | } | 41 | } |
lib/compiler/aro/aro/Driver.zig+3-17| ... | @@ -99,7 +99,6 @@ raw_target_triple: ?[]const u8 = null, | ... | @@ -99,7 +99,6 @@ raw_target_triple: ?[]const u8 = null, |
| 99 | use_assembly_backend: bool = false, | 99 | use_assembly_backend: bool = false, |
| 100 | 100 | ||
| 101 | // linker options | 101 | // linker options |
| 102 | use_linker: ?[]const u8 = null, | ||
| 103 | linker_path: ?[]const u8 = null, | 102 | linker_path: ?[]const u8 = null, |
| 104 | nodefaultlibs: bool = false, | 103 | nodefaultlibs: bool = false, |
| 105 | nolibc: bool = false, | 104 | nolibc: bool = false, |
| ... | @@ -572,10 +571,6 @@ pub fn parseArgs( | ... | @@ -572,10 +571,6 @@ pub fn parseArgs( |
| 572 | d.comp.langopts.preserve_comments = true; | 571 | d.comp.langopts.preserve_comments = true; |
| 573 | d.comp.langopts.preserve_comments_in_macros = true; | 572 | d.comp.langopts.preserve_comments_in_macros = true; |
| 574 | comment_arg = arg; | 573 | comment_arg = arg; |
| 575 | } else if (option(arg, "-fuse-ld=")) |linker_name| { | ||
| 576 | d.use_linker = linker_name; | ||
| 577 | } else if (mem.eql(u8, arg, "-fuse-ld=")) { | ||
| 578 | d.use_linker = null; | ||
| 579 | } else if (option(arg, "--ld-path=")) |linker_path| { | 574 | } else if (option(arg, "--ld-path=")) |linker_path| { |
| 580 | d.linker_path = linker_path; | 575 | d.linker_path = linker_path; |
| 581 | } else if (mem.eql(u8, arg, "-r")) { | 576 | } else if (mem.eql(u8, arg, "-r")) { |
| ... | @@ -1150,29 +1145,20 @@ fn exitWithCleanup(d: *Driver, code: u8) noreturn { | ... | @@ -1150,29 +1145,20 @@ fn exitWithCleanup(d: *Driver, code: u8) noreturn { |
| 1150 | /// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments. | 1145 | /// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments. |
| 1151 | /// Then, smooshes them together with platform defaults, to decide whether | 1146 | /// Then, smooshes them together with platform defaults, to decide whether |
| 1152 | /// this compile should be using PIC mode or not. | 1147 | /// this compile should be using PIC mode or not. |
| 1153 | /// Returns a tuple of ( backend.CodeGenOptions.PicLevel, IsPIE). | ||
| 1154 | pub fn getPICMode(d: *Driver, lastpic: []const u8) Compilation.Error!struct { backend.CodeGenOptions.PicLevel, bool } { | 1148 | pub fn getPICMode(d: *Driver, lastpic: []const u8) Compilation.Error!struct { backend.CodeGenOptions.PicLevel, bool } { |
| 1155 | const eqlIgnoreCase = std.ascii.eqlIgnoreCase; | 1149 | const eqlIgnoreCase = std.ascii.eqlIgnoreCase; |
| 1156 | 1150 | ||
| 1157 | const target = d.comp.target; | 1151 | const target = d.comp.target; |
| 1158 | const linker = d.use_linker orelse @import("system_defaults").linker; | ||
| 1159 | const is_bfd_linker = eqlIgnoreCase(linker, "bfd"); | ||
| 1160 | 1152 | ||
| 1161 | const is_pie_default = switch (target_util.isPIEDefault(target)) { | 1153 | const is_pie_default = switch (target_util.isPIEDefault(target)) { |
| 1162 | .yes => true, | 1154 | .yes => true, |
| 1163 | .no => false, | 1155 | .no => false, |
| 1164 | .depends_on_linker => if (is_bfd_linker) | 1156 | .depends_on_linker => false, |
| 1165 | target.cpu.arch == .x86_64 // CrossWindows | ||
| 1166 | else | ||
| 1167 | false, //MSVC | ||
| 1168 | }; | 1157 | }; |
| 1169 | const is_pic_default = switch (target_util.isPICdefault(target)) { | 1158 | const is_pic_default = switch (target_util.isPICdefault(target)) { |
| 1170 | .yes => true, | 1159 | .yes => true, |
| 1171 | .no => false, | 1160 | .no => false, |
| 1172 | .depends_on_linker => if (is_bfd_linker) | 1161 | .depends_on_linker => false, |
| 1173 | target.cpu.arch == .x86_64 | ||
| 1174 | else | ||
| 1175 | (target.cpu.arch == .x86_64 or target.cpu.arch == .aarch64), | ||
| 1176 | }; | 1162 | }; |
| 1177 | 1163 | ||
| 1178 | var pie: bool = is_pie_default; | 1164 | var pie: bool = is_pie_default; |
| ... | @@ -1239,7 +1225,7 @@ pub fn getPICMode(d: *Driver, lastpic: []const u8) Compilation.Error!struct { ba | ... | @@ -1239,7 +1225,7 @@ pub fn getPICMode(d: *Driver, lastpic: []const u8) Compilation.Error!struct { ba |
| 1239 | const forced = switch (target_util.isPICDefaultForced(target)) { | 1225 | const forced = switch (target_util.isPICDefaultForced(target)) { |
| 1240 | .yes => true, | 1226 | .yes => true, |
| 1241 | .no => false, | 1227 | .no => false, |
| 1242 | .depends_on_linker => if (is_bfd_linker) target.cpu.arch == .x86_64 else target.cpu.arch == .aarch64 or target.cpu.arch == .x86_64, | 1228 | .depends_on_linker => false, |
| 1243 | }; | 1229 | }; |
| 1244 | if (!forced) { | 1230 | if (!forced) { |
| 1245 | // -fpic/-fPIC, -fpie/-fPIE | 1231 | // -fpic/-fPIC, -fpie/-fPIE |
lib/compiler/aro/aro/Driver/GCCDetector.zig deleted-632| ... | @@ -1,632 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | const system_defaults = @import("system_defaults"); | ||
| 4 | |||
| 5 | const GCCVersion = @import("GCCVersion.zig"); | ||
| 6 | const Multilib = @import("Multilib.zig"); | ||
| 7 | const target_util = @import("../target.zig"); | ||
| 8 | const Toolchain = @import("../Toolchain.zig"); | ||
| 9 | |||
| 10 | const GCCDetector = @This(); | ||
| 11 | |||
| 12 | is_valid: bool = false, | ||
| 13 | install_path: []const u8 = "", | ||
| 14 | parent_lib_path: []const u8 = "", | ||
| 15 | version: GCCVersion = .{}, | ||
| 16 | gcc_triple: []const u8 = "", | ||
| 17 | selected: Multilib = .{}, | ||
| 18 | biarch_sibling: ?Multilib = null, | ||
| 19 | |||
| 20 | pub fn deinit(self: *GCCDetector) void { | ||
| 21 | if (!self.is_valid) return; | ||
| 22 | } | ||
| 23 | |||
| 24 | pub fn appendToolPath(self: *const GCCDetector, tc: *Toolchain) !void { | ||
| 25 | if (!self.is_valid) return; | ||
| 26 | return tc.addPathFromComponents(&.{ | ||
| 27 | self.parent_lib_path, | ||
| 28 | "..", | ||
| 29 | self.gcc_triple, | ||
| 30 | "bin", | ||
| 31 | }, .program); | ||
| 32 | } | ||
| 33 | |||
| 34 | fn addDefaultGCCPrefixes(prefixes: *std.ArrayListUnmanaged([]const u8), tc: *const Toolchain) !void { | ||
| 35 | const sysroot = tc.getSysroot(); | ||
| 36 | const target = tc.getTarget(); | ||
| 37 | if (sysroot.len == 0 and target.os.tag == .linux and tc.filesystem.exists("/opt/rh")) { | ||
| 38 | prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-12/root/usr"); | ||
| 39 | prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-11/root/usr"); | ||
| 40 | prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-10/root/usr"); | ||
| 41 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-12/root/usr"); | ||
| 42 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-11/root/usr"); | ||
| 43 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-10/root/usr"); | ||
| 44 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-9/root/usr"); | ||
| 45 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-8/root/usr"); | ||
| 46 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-7/root/usr"); | ||
| 47 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-6/root/usr"); | ||
| 48 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-4/root/usr"); | ||
| 49 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-3/root/usr"); | ||
| 50 | prefixes.appendAssumeCapacity("/opt/rh/devtoolset-2/root/usr"); | ||
| 51 | } | ||
| 52 | if (sysroot.len == 0) { | ||
| 53 | prefixes.appendAssumeCapacity("/usr"); | ||
| 54 | } else { | ||
| 55 | var usr_path = try tc.driver.comp.arena.alloc(u8, 4 + sysroot.len); | ||
| 56 | @memcpy(usr_path[0..4], "/usr"); | ||
| 57 | @memcpy(usr_path[4..], sysroot); | ||
| 58 | prefixes.appendAssumeCapacity(usr_path); | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | fn collectLibDirsAndTriples( | ||
| 63 | tc: *Toolchain, | ||
| 64 | lib_dirs: *std.ArrayListUnmanaged([]const u8), | ||
| 65 | triple_aliases: *std.ArrayListUnmanaged([]const u8), | ||
| 66 | biarch_libdirs: *std.ArrayListUnmanaged([]const u8), | ||
| 67 | biarch_triple_aliases: *std.ArrayListUnmanaged([]const u8), | ||
| 68 | ) !void { | ||
| 69 | const AArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 70 | const AArch64Triples: [4][]const u8 = .{ "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux" }; | ||
| 71 | const AArch64beLibDirs: [1][]const u8 = .{"/lib"}; | ||
| 72 | const AArch64beTriples: [2][]const u8 = .{ "aarch64_be-none-linux-gnu", "aarch64_be-linux-gnu" }; | ||
| 73 | |||
| 74 | const ARMLibDirs: [1][]const u8 = .{"/lib"}; | ||
| 75 | const ARMTriples: [1][]const u8 = .{"arm-linux-gnueabi"}; | ||
| 76 | const ARMHFTriples: [4][]const u8 = .{ "arm-linux-gnueabihf", "armv7hl-redhat-linux-gnueabi", "armv6hl-suse-linux-gnueabi", "armv7hl-suse-linux-gnueabi" }; | ||
| 77 | |||
| 78 | const ARMebLibDirs: [1][]const u8 = .{"/lib"}; | ||
| 79 | const ARMebTriples: [1][]const u8 = .{"armeb-linux-gnueabi"}; | ||
| 80 | const ARMebHFTriples: [2][]const u8 = .{ "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi" }; | ||
| 81 | |||
| 82 | const AVRLibDirs: [1][]const u8 = .{"/lib"}; | ||
| 83 | const AVRTriples: [1][]const u8 = .{"avr"}; | ||
| 84 | |||
| 85 | const CSKYLibDirs: [1][]const u8 = .{"/lib"}; | ||
| 86 | const CSKYTriples: [3][]const u8 = .{ "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2" }; | ||
| 87 | |||
| 88 | const X86_64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 89 | const X86_64Triples: [11][]const u8 = .{ | ||
| 90 | "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", | ||
| 91 | "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E", | ||
| 92 | "x86_64-redhat-linux", "x86_64-suse-linux", | ||
| 93 | "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", | ||
| 94 | "x86_64-slackware-linux", "x86_64-unknown-linux", | ||
| 95 | "x86_64-amazon-linux", | ||
| 96 | }; | ||
| 97 | const X32Triples: [2][]const u8 = .{ "x86_64-linux-gnux32", "x86_64-pc-linux-gnux32" }; | ||
| 98 | const X32LibDirs: [2][]const u8 = .{ "/libx32", "/lib" }; | ||
| 99 | const X86LibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; | ||
| 100 | const X86Triples: [9][]const u8 = .{ | ||
| 101 | "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu", | ||
| 102 | "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux", | ||
| 103 | "i586-suse-linux", "i686-montavista-linux", "i686-gnu", | ||
| 104 | }; | ||
| 105 | |||
| 106 | const LoongArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 107 | const LoongArch64Triples: [2][]const u8 = .{ "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu" }; | ||
| 108 | |||
| 109 | const M68kLibDirs: [1][]const u8 = .{"/lib"}; | ||
| 110 | const M68kTriples: [3][]const u8 = .{ "m68k-linux-gnu", "m68k-unknown-linux-gnu", "m68k-suse-linux" }; | ||
| 111 | |||
| 112 | const MIPSLibDirs: [2][]const u8 = .{ "/libo32", "/lib" }; | ||
| 113 | const MIPSTriples: [5][]const u8 = .{ | ||
| 114 | "mips-linux-gnu", "mips-mti-linux", | ||
| 115 | "mips-mti-linux-gnu", "mips-img-linux-gnu", | ||
| 116 | "mipsisa32r6-linux-gnu", | ||
| 117 | }; | ||
| 118 | const MIPSELLibDirs: [2][]const u8 = .{ "/libo32", "/lib" }; | ||
| 119 | const MIPSELTriples: [3][]const u8 = .{ "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu" }; | ||
| 120 | |||
| 121 | const MIPS64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 122 | const MIPS64Triples: [6][]const u8 = .{ | ||
| 123 | "mips64-linux-gnu", "mips-mti-linux-gnu", | ||
| 124 | "mips-img-linux-gnu", "mips64-linux-gnuabi64", | ||
| 125 | "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64", | ||
| 126 | }; | ||
| 127 | const MIPS64ELLibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 128 | const MIPS64ELTriples: [6][]const u8 = .{ | ||
| 129 | "mips64el-linux-gnu", "mips-mti-linux-gnu", | ||
| 130 | "mips-img-linux-gnu", "mips64el-linux-gnuabi64", | ||
| 131 | "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64", | ||
| 132 | }; | ||
| 133 | |||
| 134 | const MIPSN32LibDirs: [1][]const u8 = .{"/lib32"}; | ||
| 135 | const MIPSN32Triples: [2][]const u8 = .{ "mips64-linux-gnuabin32", "mipsisa64r6-linux-gnuabin32" }; | ||
| 136 | const MIPSN32ELLibDirs: [1][]const u8 = .{"/lib32"}; | ||
| 137 | const MIPSN32ELTriples: [2][]const u8 = .{ "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32" }; | ||
| 138 | |||
| 139 | const MSP430LibDirs: [1][]const u8 = .{"/lib"}; | ||
| 140 | const MSP430Triples: [1][]const u8 = .{"msp430-elf"}; | ||
| 141 | |||
| 142 | const PPCLibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; | ||
| 143 | const PPCTriples: [5][]const u8 = .{ | ||
| 144 | "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", | ||
| 145 | // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a | ||
| 146 | // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux". | ||
| 147 | "powerpc64-suse-linux", "powerpc-montavista-linuxspe", | ||
| 148 | }; | ||
| 149 | const PPCLELibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; | ||
| 150 | const PPCLETriples: [3][]const u8 = .{ "powerpcle-linux-gnu", "powerpcle-unknown-linux-gnu", "powerpcle-linux-musl" }; | ||
| 151 | |||
| 152 | const PPC64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 153 | const PPC64Triples: [4][]const u8 = .{ | ||
| 154 | "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu", | ||
| 155 | "powerpc64-suse-linux", "ppc64-redhat-linux", | ||
| 156 | }; | ||
| 157 | const PPC64LELibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 158 | const PPC64LETriples: [5][]const u8 = .{ | ||
| 159 | "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu", | ||
| 160 | "powerpc64le-none-linux-gnu", "powerpc64le-suse-linux", | ||
| 161 | "ppc64le-redhat-linux", | ||
| 162 | }; | ||
| 163 | |||
| 164 | const RISCV32LibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; | ||
| 165 | const RISCV32Triples: [3][]const u8 = .{ "riscv32-unknown-linux-gnu", "riscv32-linux-gnu", "riscv32-unknown-elf" }; | ||
| 166 | const RISCV64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 167 | const RISCV64Triples: [3][]const u8 = .{ | ||
| 168 | "riscv64-unknown-linux-gnu", | ||
| 169 | "riscv64-linux-gnu", | ||
| 170 | "riscv64-unknown-elf", | ||
| 171 | }; | ||
| 172 | |||
| 173 | const SPARCv8LibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; | ||
| 174 | const SPARCv8Triples: [2][]const u8 = .{ "sparc-linux-gnu", "sparcv8-linux-gnu" }; | ||
| 175 | const SPARCv9LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 176 | const SPARCv9Triples: [2][]const u8 = .{ "sparc64-linux-gnu", "sparcv9-linux-gnu" }; | ||
| 177 | |||
| 178 | const SystemZLibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; | ||
| 179 | const SystemZTriples: [5][]const u8 = .{ | ||
| 180 | "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", | ||
| 181 | "s390x-suse-linux", "s390x-redhat-linux", | ||
| 182 | }; | ||
| 183 | const target = tc.getTarget(); | ||
| 184 | if (target.os.tag == .solaris) { | ||
| 185 | // TODO | ||
| 186 | return; | ||
| 187 | } | ||
| 188 | if (target.abi.isAndroid()) { | ||
| 189 | const AArch64AndroidTriples: [1][]const u8 = .{"aarch64-linux-android"}; | ||
| 190 | const ARMAndroidTriples: [1][]const u8 = .{"arm-linux-androideabi"}; | ||
| 191 | const MIPSELAndroidTriples: [1][]const u8 = .{"mipsel-linux-android"}; | ||
| 192 | const MIPS64ELAndroidTriples: [1][]const u8 = .{"mips64el-linux-android"}; | ||
| 193 | const X86AndroidTriples: [1][]const u8 = .{"i686-linux-android"}; | ||
| 194 | const X86_64AndroidTriples: [1][]const u8 = .{"x86_64-linux-android"}; | ||
| 195 | |||
| 196 | switch (target.cpu.arch) { | ||
| 197 | .aarch64 => { | ||
| 198 | lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs); | ||
| 199 | triple_aliases.appendSliceAssumeCapacity(&AArch64AndroidTriples); | ||
| 200 | }, | ||
| 201 | .arm, | ||
| 202 | .thumb, | ||
| 203 | => { | ||
| 204 | lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs); | ||
| 205 | triple_aliases.appendSliceAssumeCapacity(&ARMAndroidTriples); | ||
| 206 | }, | ||
| 207 | .mipsel => { | ||
| 208 | lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs); | ||
| 209 | triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples); | ||
| 210 | biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs); | ||
| 211 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples); | ||
| 212 | }, | ||
| 213 | .mips64el => { | ||
| 214 | lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs); | ||
| 215 | triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples); | ||
| 216 | biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs); | ||
| 217 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples); | ||
| 218 | }, | ||
| 219 | .x86_64 => { | ||
| 220 | lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs); | ||
| 221 | triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples); | ||
| 222 | biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs); | ||
| 223 | biarch_triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples); | ||
| 224 | }, | ||
| 225 | .x86 => { | ||
| 226 | lib_dirs.appendSliceAssumeCapacity(&X86LibDirs); | ||
| 227 | triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples); | ||
| 228 | biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs); | ||
| 229 | biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples); | ||
| 230 | }, | ||
| 231 | else => {}, | ||
| 232 | } | ||
| 233 | return; | ||
| 234 | } | ||
| 235 | switch (target.cpu.arch) { | ||
| 236 | .aarch64 => { | ||
| 237 | lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs); | ||
| 238 | triple_aliases.appendSliceAssumeCapacity(&AArch64Triples); | ||
| 239 | biarch_libdirs.appendSliceAssumeCapacity(&AArch64LibDirs); | ||
| 240 | biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64Triples); | ||
| 241 | }, | ||
| 242 | .aarch64_be => { | ||
| 243 | lib_dirs.appendSliceAssumeCapacity(&AArch64beLibDirs); | ||
| 244 | triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples); | ||
| 245 | biarch_libdirs.appendSliceAssumeCapacity(&AArch64beLibDirs); | ||
| 246 | biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples); | ||
| 247 | }, | ||
| 248 | .arm, .thumb => { | ||
| 249 | lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs); | ||
| 250 | if (target.abi == .gnueabihf) { | ||
| 251 | triple_aliases.appendSliceAssumeCapacity(&ARMHFTriples); | ||
| 252 | } else { | ||
| 253 | triple_aliases.appendSliceAssumeCapacity(&ARMTriples); | ||
| 254 | } | ||
| 255 | }, | ||
| 256 | .armeb, .thumbeb => { | ||
| 257 | lib_dirs.appendSliceAssumeCapacity(&ARMebLibDirs); | ||
| 258 | if (target.abi == .gnueabihf) { | ||
| 259 | triple_aliases.appendSliceAssumeCapacity(&ARMebHFTriples); | ||
| 260 | } else { | ||
| 261 | triple_aliases.appendSliceAssumeCapacity(&ARMebTriples); | ||
| 262 | } | ||
| 263 | }, | ||
| 264 | .avr => { | ||
| 265 | lib_dirs.appendSliceAssumeCapacity(&AVRLibDirs); | ||
| 266 | triple_aliases.appendSliceAssumeCapacity(&AVRTriples); | ||
| 267 | }, | ||
| 268 | .csky => { | ||
| 269 | lib_dirs.appendSliceAssumeCapacity(&CSKYLibDirs); | ||
| 270 | triple_aliases.appendSliceAssumeCapacity(&CSKYTriples); | ||
| 271 | }, | ||
| 272 | .x86_64 => { | ||
| 273 | if (target.abi == .gnux32 or target.abi == .muslx32) { | ||
| 274 | lib_dirs.appendSliceAssumeCapacity(&X32LibDirs); | ||
| 275 | triple_aliases.appendSliceAssumeCapacity(&X32Triples); | ||
| 276 | biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs); | ||
| 277 | biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples); | ||
| 278 | } else { | ||
| 279 | lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs); | ||
| 280 | triple_aliases.appendSliceAssumeCapacity(&X86_64Triples); | ||
| 281 | biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs); | ||
| 282 | biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples); | ||
| 283 | } | ||
| 284 | biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs); | ||
| 285 | biarch_triple_aliases.appendSliceAssumeCapacity(&X86Triples); | ||
| 286 | }, | ||
| 287 | .x86 => { | ||
| 288 | lib_dirs.appendSliceAssumeCapacity(&X86LibDirs); | ||
| 289 | }, | ||
| 290 | .loongarch64 => { | ||
| 291 | lib_dirs.appendSliceAssumeCapacity(&LoongArch64LibDirs); | ||
| 292 | triple_aliases.appendSliceAssumeCapacity(&LoongArch64Triples); | ||
| 293 | }, | ||
| 294 | .m68k => { | ||
| 295 | lib_dirs.appendSliceAssumeCapacity(&M68kLibDirs); | ||
| 296 | triple_aliases.appendSliceAssumeCapacity(&M68kTriples); | ||
| 297 | }, | ||
| 298 | .mips => { | ||
| 299 | lib_dirs.appendSliceAssumeCapacity(&MIPSLibDirs); | ||
| 300 | triple_aliases.appendSliceAssumeCapacity(&MIPSTriples); | ||
| 301 | biarch_libdirs.appendSliceAssumeCapacity(&MIPS64LibDirs); | ||
| 302 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples); | ||
| 303 | biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs); | ||
| 304 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples); | ||
| 305 | }, | ||
| 306 | .mipsel => { | ||
| 307 | lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs); | ||
| 308 | triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples); | ||
| 309 | triple_aliases.appendSliceAssumeCapacity(&MIPSTriples); | ||
| 310 | biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs); | ||
| 311 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples); | ||
| 312 | biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs); | ||
| 313 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples); | ||
| 314 | }, | ||
| 315 | .mips64 => { | ||
| 316 | lib_dirs.appendSliceAssumeCapacity(&MIPS64LibDirs); | ||
| 317 | triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples); | ||
| 318 | biarch_libdirs.appendSliceAssumeCapacity(&MIPSLibDirs); | ||
| 319 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples); | ||
| 320 | biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs); | ||
| 321 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples); | ||
| 322 | }, | ||
| 323 | .mips64el => { | ||
| 324 | lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs); | ||
| 325 | triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples); | ||
| 326 | biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs); | ||
| 327 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples); | ||
| 328 | biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs); | ||
| 329 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples); | ||
| 330 | biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples); | ||
| 331 | }, | ||
| 332 | .msp430 => { | ||
| 333 | lib_dirs.appendSliceAssumeCapacity(&MSP430LibDirs); | ||
| 334 | triple_aliases.appendSliceAssumeCapacity(&MSP430Triples); | ||
| 335 | }, | ||
| 336 | .powerpc => { | ||
| 337 | lib_dirs.appendSliceAssumeCapacity(&PPCLibDirs); | ||
| 338 | triple_aliases.appendSliceAssumeCapacity(&PPCTriples); | ||
| 339 | biarch_libdirs.appendSliceAssumeCapacity(&PPC64LibDirs); | ||
| 340 | biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64Triples); | ||
| 341 | }, | ||
| 342 | .powerpcle => { | ||
| 343 | lib_dirs.appendSliceAssumeCapacity(&PPCLELibDirs); | ||
| 344 | triple_aliases.appendSliceAssumeCapacity(&PPCLETriples); | ||
| 345 | biarch_libdirs.appendSliceAssumeCapacity(&PPC64LELibDirs); | ||
| 346 | biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples); | ||
| 347 | }, | ||
| 348 | .powerpc64 => { | ||
| 349 | lib_dirs.appendSliceAssumeCapacity(&PPC64LibDirs); | ||
| 350 | triple_aliases.appendSliceAssumeCapacity(&PPC64Triples); | ||
| 351 | biarch_libdirs.appendSliceAssumeCapacity(&PPCLibDirs); | ||
| 352 | biarch_triple_aliases.appendSliceAssumeCapacity(&PPCTriples); | ||
| 353 | }, | ||
| 354 | .powerpc64le => { | ||
| 355 | lib_dirs.appendSliceAssumeCapacity(&PPC64LELibDirs); | ||
| 356 | triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples); | ||
| 357 | biarch_libdirs.appendSliceAssumeCapacity(&PPCLELibDirs); | ||
| 358 | biarch_triple_aliases.appendSliceAssumeCapacity(&PPCLETriples); | ||
| 359 | }, | ||
| 360 | .riscv32 => { | ||
| 361 | lib_dirs.appendSliceAssumeCapacity(&RISCV32LibDirs); | ||
| 362 | triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples); | ||
| 363 | biarch_libdirs.appendSliceAssumeCapacity(&RISCV64LibDirs); | ||
| 364 | biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples); | ||
| 365 | }, | ||
| 366 | .riscv64 => { | ||
| 367 | lib_dirs.appendSliceAssumeCapacity(&RISCV64LibDirs); | ||
| 368 | triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples); | ||
| 369 | biarch_libdirs.appendSliceAssumeCapacity(&RISCV32LibDirs); | ||
| 370 | biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples); | ||
| 371 | }, | ||
| 372 | .sparc => { | ||
| 373 | lib_dirs.appendSliceAssumeCapacity(&SPARCv8LibDirs); | ||
| 374 | triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples); | ||
| 375 | biarch_libdirs.appendSliceAssumeCapacity(&SPARCv9LibDirs); | ||
| 376 | biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples); | ||
| 377 | }, | ||
| 378 | .sparc64 => { | ||
| 379 | lib_dirs.appendSliceAssumeCapacity(&SPARCv9LibDirs); | ||
| 380 | triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples); | ||
| 381 | biarch_libdirs.appendSliceAssumeCapacity(&SPARCv8LibDirs); | ||
| 382 | biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples); | ||
| 383 | }, | ||
| 384 | .s390x => { | ||
| 385 | lib_dirs.appendSliceAssumeCapacity(&SystemZLibDirs); | ||
| 386 | triple_aliases.appendSliceAssumeCapacity(&SystemZTriples); | ||
| 387 | }, | ||
| 388 | else => {}, | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | pub fn discover(self: *GCCDetector, tc: *Toolchain) !void { | ||
| 393 | var path_buf: [std.fs.max_path_bytes]u8 = undefined; | ||
| 394 | var fib = std.heap.FixedBufferAllocator.init(&path_buf); | ||
| 395 | |||
| 396 | const target = tc.getTarget(); | ||
| 397 | const biarch_variant_target = if (target.ptrBitWidth() == 32) | ||
| 398 | target_util.get64BitArchVariant(target) | ||
| 399 | else | ||
| 400 | target_util.get32BitArchVariant(target); | ||
| 401 | |||
| 402 | var candidate_lib_dirs_buffer: [16][]const u8 = undefined; | ||
| 403 | var candidate_lib_dirs = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_lib_dirs_buffer); | ||
| 404 | |||
| 405 | var candidate_triple_aliases_buffer: [16][]const u8 = undefined; | ||
| 406 | var candidate_triple_aliases = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_triple_aliases_buffer); | ||
| 407 | |||
| 408 | var candidate_biarch_lib_dirs_buffer: [16][]const u8 = undefined; | ||
| 409 | var candidate_biarch_lib_dirs = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_biarch_lib_dirs_buffer); | ||
| 410 | |||
| 411 | var candidate_biarch_triple_aliases_buffer: [16][]const u8 = undefined; | ||
| 412 | var candidate_biarch_triple_aliases = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_biarch_triple_aliases_buffer); | ||
| 413 | |||
| 414 | try collectLibDirsAndTriples( | ||
| 415 | tc, | ||
| 416 | &candidate_lib_dirs, | ||
| 417 | &candidate_triple_aliases, | ||
| 418 | &candidate_biarch_lib_dirs, | ||
| 419 | &candidate_biarch_triple_aliases, | ||
| 420 | ); | ||
| 421 | |||
| 422 | var target_buf: [64]u8 = undefined; | ||
| 423 | const triple_str = target_util.toLLVMTriple(target, &target_buf); | ||
| 424 | candidate_triple_aliases.appendAssumeCapacity(triple_str); | ||
| 425 | |||
| 426 | // Also include the multiarch variant if it's different. | ||
| 427 | var biarch_buf: [64]u8 = undefined; | ||
| 428 | if (biarch_variant_target) |biarch_target| { | ||
| 429 | const biarch_triple_str = target_util.toLLVMTriple(biarch_target, &biarch_buf); | ||
| 430 | if (!std.mem.eql(u8, biarch_triple_str, triple_str)) { | ||
| 431 | candidate_triple_aliases.appendAssumeCapacity(biarch_triple_str); | ||
| 432 | } | ||
| 433 | } | ||
| 434 | |||
| 435 | var prefixes_buf: [16][]const u8 = undefined; | ||
| 436 | var prefixes = std.ArrayListUnmanaged([]const u8).initBuffer(&prefixes_buf); | ||
| 437 | const gcc_toolchain_dir = gccToolchainDir(tc); | ||
| 438 | if (gcc_toolchain_dir.len != 0) { | ||
| 439 | const adjusted = if (gcc_toolchain_dir[gcc_toolchain_dir.len - 1] == '/') | ||
| 440 | gcc_toolchain_dir[0 .. gcc_toolchain_dir.len - 1] | ||
| 441 | else | ||
| 442 | gcc_toolchain_dir; | ||
| 443 | prefixes.appendAssumeCapacity(adjusted); | ||
| 444 | } else { | ||
| 445 | const sysroot = tc.getSysroot(); | ||
| 446 | if (sysroot.len > 0) { | ||
| 447 | prefixes.appendAssumeCapacity(sysroot); | ||
| 448 | try addDefaultGCCPrefixes(&prefixes, tc); | ||
| 449 | } | ||
| 450 | |||
| 451 | if (sysroot.len == 0) { | ||
| 452 | try addDefaultGCCPrefixes(&prefixes, tc); | ||
| 453 | } | ||
| 454 | // TODO: Special-case handling for Gentoo | ||
| 455 | } | ||
| 456 | |||
| 457 | const v0 = GCCVersion.parse("0.0.0"); | ||
| 458 | for (prefixes.items) |prefix| { | ||
| 459 | if (!tc.filesystem.exists(prefix)) continue; | ||
| 460 | |||
| 461 | for (candidate_lib_dirs.items) |suffix| { | ||
| 462 | defer fib.reset(); | ||
| 463 | const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue; | ||
| 464 | if (!tc.filesystem.exists(lib_dir)) continue; | ||
| 465 | |||
| 466 | const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" }); | ||
| 467 | const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" }); | ||
| 468 | |||
| 469 | try self.scanLibDirForGCCTriple(tc, target, lib_dir, triple_str, false, gcc_dir_exists, gcc_cross_dir_exists); | ||
| 470 | for (candidate_triple_aliases.items) |candidate| { | ||
| 471 | try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, false, gcc_dir_exists, gcc_cross_dir_exists); | ||
| 472 | } | ||
| 473 | } | ||
| 474 | for (candidate_biarch_lib_dirs.items) |suffix| { | ||
| 475 | const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue; | ||
| 476 | if (!tc.filesystem.exists(lib_dir)) continue; | ||
| 477 | |||
| 478 | const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" }); | ||
| 479 | const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" }); | ||
| 480 | for (candidate_biarch_triple_aliases.items) |candidate| { | ||
| 481 | try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, true, gcc_dir_exists, gcc_cross_dir_exists); | ||
| 482 | } | ||
| 483 | } | ||
| 484 | if (self.version.order(v0) == .gt) break; | ||
| 485 | } | ||
| 486 | } | ||
| 487 | |||
| 488 | fn findBiarchMultilibs( | ||
| 489 | tc: *const Toolchain, | ||
| 490 | result: *Multilib.Detected, | ||
| 491 | target: std.Target, | ||
| 492 | path: [2][]const u8, | ||
| 493 | needs_biarch_suffix: bool, | ||
| 494 | ) !bool { | ||
| 495 | const suff64 = if (target.os.tag == .solaris) switch (target.cpu.arch) { | ||
| 496 | .x86, .x86_64 => "/amd64", | ||
| 497 | .sparc => "/sparcv9", | ||
| 498 | else => "/64", | ||
| 499 | } else "/64"; | ||
| 500 | |||
| 501 | const alt_64 = Multilib.init(suff64, suff64, &.{ "-m32", "+m64", "-mx32" }); | ||
| 502 | const alt_32 = Multilib.init("/32", "/32", &.{ "+m32", "-m64", "-mx32" }); | ||
| 503 | const alt_x32 = Multilib.init("/x32", "/x32", &.{ "-m32", "-m64", "+mx32" }); | ||
| 504 | |||
| 505 | const multilib_filter = Multilib.Filter{ | ||
| 506 | .base = path, | ||
| 507 | .file = "crtbegin.o", | ||
| 508 | }; | ||
| 509 | |||
| 510 | const Want = enum { | ||
| 511 | want32, | ||
| 512 | want64, | ||
| 513 | wantx32, | ||
| 514 | }; | ||
| 515 | const is_x32 = target.abi == .gnux32 or target.abi == .muslx32; | ||
| 516 | const target_ptr_width = target.ptrBitWidth(); | ||
| 517 | const want: Want = if (target_ptr_width == 32 and multilib_filter.exists(alt_32, tc.filesystem)) | ||
| 518 | .want64 | ||
| 519 | else if (target_ptr_width == 64 and is_x32 and multilib_filter.exists(alt_x32, tc.filesystem)) | ||
| 520 | .want64 | ||
| 521 | else if (target_ptr_width == 64 and !is_x32 and multilib_filter.exists(alt_64, tc.filesystem)) | ||
| 522 | .want32 | ||
| 523 | else if (target_ptr_width == 32) | ||
| 524 | if (needs_biarch_suffix) .want64 else .want32 | ||
| 525 | else if (is_x32) | ||
| 526 | if (needs_biarch_suffix) .want64 else .wantx32 | ||
| 527 | else if (needs_biarch_suffix) .want32 else .want64; | ||
| 528 | |||
| 529 | const default = switch (want) { | ||
| 530 | .want32 => Multilib.init("", "", &.{ "+m32", "-m64", "-mx32" }), | ||
| 531 | .want64 => Multilib.init("", "", &.{ "-m32", "+m64", "-mx32" }), | ||
| 532 | .wantx32 => Multilib.init("", "", &.{ "-m32", "-m64", "+mx32" }), | ||
| 533 | }; | ||
| 534 | result.multilibs.appendSliceAssumeCapacity(&.{ | ||
| 535 | default, | ||
| 536 | alt_64, | ||
| 537 | alt_32, | ||
| 538 | alt_x32, | ||
| 539 | }); | ||
| 540 | result.filter(multilib_filter, tc.filesystem); | ||
| 541 | var flags: Multilib.Flags = .{}; | ||
| 542 | flags.appendAssumeCapacity(if (target_ptr_width == 64 and !is_x32) "+m64" else "-m64"); | ||
| 543 | flags.appendAssumeCapacity(if (target_ptr_width == 32) "+m32" else "-m32"); | ||
| 544 | flags.appendAssumeCapacity(if (target_ptr_width == 64 and is_x32) "+mx32" else "-mx32"); | ||
| 545 | |||
| 546 | return result.select(flags); | ||
| 547 | } | ||
| 548 | |||
| 549 | fn scanGCCForMultilibs( | ||
| 550 | self: *GCCDetector, | ||
| 551 | tc: *const Toolchain, | ||
| 552 | target: std.Target, | ||
| 553 | path: [2][]const u8, | ||
| 554 | needs_biarch_suffix: bool, | ||
| 555 | ) !bool { | ||
| 556 | var detected: Multilib.Detected = .{}; | ||
| 557 | if (target.cpu.arch == .csky) { | ||
| 558 | // TODO | ||
| 559 | } else if (target.cpu.arch.isMIPS()) { | ||
| 560 | // TODO | ||
| 561 | } else if (target.cpu.arch.isRISCV()) { | ||
| 562 | // TODO | ||
| 563 | } else if (target.cpu.arch == .msp430) { | ||
| 564 | // TODO | ||
| 565 | } else if (target.cpu.arch == .avr) { | ||
| 566 | // No multilibs | ||
| 567 | } else if (!try findBiarchMultilibs(tc, &detected, target, path, needs_biarch_suffix)) { | ||
| 568 | return false; | ||
| 569 | } | ||
| 570 | self.selected = detected.selected; | ||
| 571 | self.biarch_sibling = detected.biarch_sibling; | ||
| 572 | return true; | ||
| 573 | } | ||
| 574 | |||
| 575 | fn scanLibDirForGCCTriple( | ||
| 576 | self: *GCCDetector, | ||
| 577 | tc: *const Toolchain, | ||
| 578 | target: std.Target, | ||
| 579 | lib_dir: []const u8, | ||
| 580 | candidate_triple: []const u8, | ||
| 581 | needs_biarch_suffix: bool, | ||
| 582 | gcc_dir_exists: bool, | ||
| 583 | gcc_cross_dir_exists: bool, | ||
| 584 | ) !void { | ||
| 585 | var path_buf: [std.fs.max_path_bytes]u8 = undefined; | ||
| 586 | var fib = std.heap.FixedBufferAllocator.init(&path_buf); | ||
| 587 | const arena = tc.driver.comp.arena; | ||
| 588 | for (0..2) |i| { | ||
| 589 | if (i == 0 and !gcc_dir_exists) continue; | ||
| 590 | if (i == 1 and !gcc_cross_dir_exists) continue; | ||
| 591 | defer fib.reset(); | ||
| 592 | |||
| 593 | const base: []const u8 = if (i == 0) "gcc" else "gcc-cross"; | ||
| 594 | var lib_suffix_buf: [64]u8 = undefined; | ||
| 595 | var suffix_buf_fib = std.heap.FixedBufferAllocator.init(&lib_suffix_buf); | ||
| 596 | const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue; | ||
| 597 | |||
| 598 | const dir_name = std.fs.path.join(fib.allocator(), &.{ lib_dir, lib_suffix }) catch continue; | ||
| 599 | var parent_dir = tc.filesystem.openDir(dir_name) catch continue; | ||
| 600 | defer parent_dir.close(); | ||
| 601 | |||
| 602 | var it = parent_dir.iterate(); | ||
| 603 | while (it.next() catch continue) |entry| { | ||
| 604 | if (entry.kind != .directory) continue; | ||
| 605 | |||
| 606 | const version_text = entry.name; | ||
| 607 | const candidate_version = GCCVersion.parse(version_text); | ||
| 608 | if (candidate_version.major != -1) { | ||
| 609 | // TODO: cache path so we're not repeatedly scanning | ||
| 610 | } | ||
| 611 | if (candidate_version.isLessThan(4, 1, 1, "")) continue; | ||
| 612 | switch (candidate_version.order(self.version)) { | ||
| 613 | .lt, .eq => continue, | ||
| 614 | .gt => {}, | ||
| 615 | } | ||
| 616 | |||
| 617 | if (!try self.scanGCCForMultilibs(tc, target, .{ dir_name, version_text }, needs_biarch_suffix)) continue; | ||
| 618 | |||
| 619 | self.version = candidate_version; | ||
| 620 | self.gcc_triple = try arena.dupe(u8, candidate_triple); | ||
| 621 | self.install_path = try std.fs.path.join(arena, &.{ lib_dir, lib_suffix, version_text }); | ||
| 622 | self.parent_lib_path = try std.fs.path.join(arena, &.{ self.install_path, "..", "..", ".." }); | ||
| 623 | self.is_valid = true; | ||
| 624 | } | ||
| 625 | } | ||
| 626 | } | ||
| 627 | |||
| 628 | fn gccToolchainDir(tc: *const Toolchain) []const u8 { | ||
| 629 | const sysroot = tc.getSysroot(); | ||
| 630 | if (sysroot.len != 0) return ""; | ||
| 631 | return system_defaults.gcc_install_prefix; | ||
| 632 | } | ||
lib/compiler/aro/aro/Toolchain.zig+1-28| ... | @@ -8,7 +8,6 @@ const Driver = @import("Driver.zig"); | ... | @@ -8,7 +8,6 @@ const Driver = @import("Driver.zig"); |
| 8 | const Filesystem = @import("Driver/Filesystem.zig").Filesystem; | 8 | const Filesystem = @import("Driver/Filesystem.zig").Filesystem; |
| 9 | const Multilib = @import("Driver/Multilib.zig"); | 9 | const Multilib = @import("Driver/Multilib.zig"); |
| 10 | const target_util = @import("target.zig"); | 10 | const target_util = @import("target.zig"); |
| 11 | const Linux = @import("toolchains/Linux.zig"); | ||
| 12 | 11 | ||
| 13 | pub const PathList = std.ArrayListUnmanaged([]const u8); | 12 | pub const PathList = std.ArrayListUnmanaged([]const u8); |
| 14 | 13 | ||
| ... | @@ -37,15 +36,7 @@ pub const UnwindLibKind = enum { | ... | @@ -37,15 +36,7 @@ pub const UnwindLibKind = enum { |
| 37 | 36 | ||
| 38 | const Inner = union(enum) { | 37 | const Inner = union(enum) { |
| 39 | uninitialized, | 38 | uninitialized, |
| 40 | linux: Linux, | ||
| 41 | unknown: void, | 39 | unknown: void, |
| 42 | |||
| 43 | fn deinit(self: *Inner, allocator: mem.Allocator) void { | ||
| 44 | switch (self.*) { | ||
| 45 | .linux => |*linux| linux.deinit(allocator), | ||
| 46 | .uninitialized, .unknown => {}, | ||
| 47 | } | ||
| 48 | } | ||
| 49 | }; | 40 | }; |
| 50 | 41 | ||
| 51 | const Toolchain = @This(); | 42 | const Toolchain = @This(); |
| ... | @@ -81,32 +72,15 @@ fn getDefaultLinker(tc: *const Toolchain) []const u8 { | ... | @@ -81,32 +72,15 @@ fn getDefaultLinker(tc: *const Toolchain) []const u8 { |
| 81 | /// Call this after driver has finished parsing command line arguments to find the toolchain | 72 | /// Call this after driver has finished parsing command line arguments to find the toolchain |
| 82 | pub fn discover(tc: *Toolchain) !void { | 73 | pub fn discover(tc: *Toolchain) !void { |
| 83 | if (tc.inner != .uninitialized) return; | 74 | if (tc.inner != .uninitialized) return; |
| 84 | 75 | tc.inner = .unknown; | |
| 85 | const target = tc.getTarget(); | ||
| 86 | tc.inner = switch (target.os.tag) { | ||
| 87 | .linux, | ||
| 88 | => if (target.cpu.arch == .hexagon) | ||
| 89 | .{ .unknown = {} } // TODO | ||
| 90 | else if (target.cpu.arch.isMIPS()) | ||
| 91 | .{ .unknown = {} } // TODO | ||
| 92 | else if (target.cpu.arch.isPowerPC()) | ||
| 93 | .{ .unknown = {} } // TODO | ||
| 94 | else if (target.cpu.arch == .ve) | ||
| 95 | .{ .unknown = {} } // TODO | ||
| 96 | else | ||
| 97 | .{ .linux = .{} }, | ||
| 98 | else => .{ .unknown = {} }, // TODO | ||
| 99 | }; | ||
| 100 | return switch (tc.inner) { | 76 | return switch (tc.inner) { |
| 101 | .uninitialized => unreachable, | 77 | .uninitialized => unreachable, |
| 102 | .linux => |*linux| linux.discover(tc), | ||
| 103 | .unknown => {}, | 78 | .unknown => {}, |
| 104 | }; | 79 | }; |
| 105 | } | 80 | } |
| 106 | 81 | ||
| 107 | pub fn deinit(tc: *Toolchain) void { | 82 | pub fn deinit(tc: *Toolchain) void { |
| 108 | const gpa = tc.driver.comp.gpa; | 83 | const gpa = tc.driver.comp.gpa; |
| 109 | tc.inner.deinit(gpa); | ||
| 110 | 84 | ||
| 111 | tc.library_paths.deinit(gpa); | 85 | tc.library_paths.deinit(gpa); |
| 112 | tc.file_paths.deinit(gpa); | 86 | tc.file_paths.deinit(gpa); |
| ... | @@ -501,7 +475,6 @@ pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.array_list.Managed([]cons | ... | @@ -501,7 +475,6 @@ pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.array_list.Managed([]cons |
| 501 | pub fn defineSystemIncludes(tc: *Toolchain) !void { | 475 | pub fn defineSystemIncludes(tc: *Toolchain) !void { |
| 502 | return switch (tc.inner) { | 476 | return switch (tc.inner) { |
| 503 | .uninitialized => unreachable, | 477 | .uninitialized => unreachable, |
| 504 | .linux => |*linux| linux.defineSystemIncludes(tc), | ||
| 505 | .unknown => { | 478 | .unknown => { |
| 506 | if (tc.driver.nostdinc) return; | 479 | if (tc.driver.nostdinc) return; |
| 507 | 480 |
lib/compiler/aro/aro/toolchains/Linux.zig deleted-519| ... | @@ -1,519 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const mem = std.mem; | ||
| 3 | |||
| 4 | const system_defaults = @import("system_defaults"); | ||
| 5 | |||
| 6 | const Compilation = @import("../Compilation.zig"); | ||
| 7 | const Driver = @import("../Driver.zig"); | ||
| 8 | const Distro = @import("../Driver/Distro.zig"); | ||
| 9 | const GCCDetector = @import("../Driver/GCCDetector.zig"); | ||
| 10 | const target_util = @import("../target.zig"); | ||
| 11 | const Toolchain = @import("../Toolchain.zig"); | ||
| 12 | |||
| 13 | const Linux = @This(); | ||
| 14 | |||
| 15 | distro: Distro.Tag = .unknown, | ||
| 16 | extra_opts: std.ArrayListUnmanaged([]const u8) = .empty, | ||
| 17 | gcc_detector: GCCDetector = .{}, | ||
| 18 | |||
| 19 | pub fn discover(self: *Linux, tc: *Toolchain) !void { | ||
| 20 | self.distro = Distro.detect(tc.getTarget(), tc.filesystem); | ||
| 21 | try self.gcc_detector.discover(tc); | ||
| 22 | tc.selected_multilib = self.gcc_detector.selected; | ||
| 23 | |||
| 24 | try self.gcc_detector.appendToolPath(tc); | ||
| 25 | try self.buildExtraOpts(tc); | ||
| 26 | try self.findPaths(tc); | ||
| 27 | } | ||
| 28 | |||
| 29 | fn buildExtraOpts(self: *Linux, tc: *const Toolchain) !void { | ||
| 30 | const gpa = tc.driver.comp.gpa; | ||
| 31 | const target = tc.getTarget(); | ||
| 32 | const is_android = target.abi.isAndroid(); | ||
| 33 | if (self.distro.isAlpine() or is_android) { | ||
| 34 | try self.extra_opts.ensureUnusedCapacity(gpa, 2); | ||
| 35 | self.extra_opts.appendAssumeCapacity("-z"); | ||
| 36 | self.extra_opts.appendAssumeCapacity("now"); | ||
| 37 | } | ||
| 38 | |||
| 39 | if (self.distro.isOpenSUSE() or self.distro.isUbuntu() or self.distro.isAlpine() or is_android) { | ||
| 40 | try self.extra_opts.ensureUnusedCapacity(gpa, 2); | ||
| 41 | self.extra_opts.appendAssumeCapacity("-z"); | ||
| 42 | self.extra_opts.appendAssumeCapacity("relro"); | ||
| 43 | } | ||
| 44 | |||
| 45 | if ((target.cpu.arch.isArm() and !target.cpu.arch.isThumb()) or target.cpu.arch.isAARCH64() or is_android) { | ||
| 46 | try self.extra_opts.ensureUnusedCapacity(gpa, 2); | ||
| 47 | self.extra_opts.appendAssumeCapacity("-z"); | ||
| 48 | self.extra_opts.appendAssumeCapacity("max-page-size=4096"); | ||
| 49 | } | ||
| 50 | |||
| 51 | if (target.cpu.arch == .arm or target.cpu.arch == .thumb) { | ||
| 52 | try self.extra_opts.append(gpa, "-X"); | ||
| 53 | } | ||
| 54 | |||
| 55 | if (!target.cpu.arch.isMIPS() and target.cpu.arch != .hexagon) { | ||
| 56 | const hash_style = if (is_android) .both else self.distro.getHashStyle(); | ||
| 57 | try self.extra_opts.append(gpa, switch (hash_style) { | ||
| 58 | inline else => |tag| "--hash-style=" ++ @tagName(tag), | ||
| 59 | }); | ||
| 60 | } | ||
| 61 | |||
| 62 | if (system_defaults.enable_linker_build_id) { | ||
| 63 | try self.extra_opts.append(gpa, "--build-id"); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | fn addMultiLibPaths(self: *Linux, tc: *Toolchain, sysroot: []const u8, os_lib_dir: []const u8) !void { | ||
| 68 | if (!self.gcc_detector.is_valid) return; | ||
| 69 | const gcc_triple = self.gcc_detector.gcc_triple; | ||
| 70 | const lib_path = self.gcc_detector.parent_lib_path; | ||
| 71 | |||
| 72 | // Add lib/gcc/$triple/$version, with an optional /multilib suffix. | ||
| 73 | try tc.addPathIfExists(&.{ self.gcc_detector.install_path, tc.selected_multilib.gcc_suffix }, .file); | ||
| 74 | |||
| 75 | // Add lib/gcc/$triple/$libdir | ||
| 76 | // For GCC built with --enable-version-specific-runtime-libs. | ||
| 77 | try tc.addPathIfExists(&.{ self.gcc_detector.install_path, "..", os_lib_dir }, .file); | ||
| 78 | |||
| 79 | try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", "..", os_lib_dir, tc.selected_multilib.os_suffix }, .file); | ||
| 80 | |||
| 81 | // If the GCC installation we found is inside of the sysroot, we want to | ||
| 82 | // prefer libraries installed in the parent prefix of the GCC installation. | ||
| 83 | // It is important to *not* use these paths when the GCC installation is | ||
| 84 | // outside of the system root as that can pick up unintended libraries. | ||
| 85 | // This usually happens when there is an external cross compiler on the | ||
| 86 | // host system, and a more minimal sysroot available that is the target of | ||
| 87 | // the cross. Note that GCC does include some of these directories in some | ||
| 88 | // configurations but this seems somewhere between questionable and simply | ||
| 89 | // a bug. | ||
| 90 | if (mem.startsWith(u8, lib_path, sysroot)) { | ||
| 91 | try tc.addPathIfExists(&.{ lib_path, "..", os_lib_dir }, .file); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | fn addMultiArchPaths(self: *Linux, tc: *Toolchain) !void { | ||
| 96 | if (!self.gcc_detector.is_valid) return; | ||
| 97 | const lib_path = self.gcc_detector.parent_lib_path; | ||
| 98 | const gcc_triple = self.gcc_detector.gcc_triple; | ||
| 99 | const multilib = self.gcc_detector.selected; | ||
| 100 | try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", multilib.os_suffix }, .file); | ||
| 101 | } | ||
| 102 | |||
| 103 | /// TODO: Very incomplete | ||
| 104 | fn findPaths(self: *Linux, tc: *Toolchain) !void { | ||
| 105 | const target = tc.getTarget(); | ||
| 106 | const sysroot = tc.getSysroot(); | ||
| 107 | |||
| 108 | var output: [64]u8 = undefined; | ||
| 109 | |||
| 110 | const os_lib_dir = getOSLibDir(target); | ||
| 111 | const multiarch_triple = getMultiarchTriple(target) orelse target_util.toLLVMTriple(target, &output); | ||
| 112 | |||
| 113 | try self.addMultiLibPaths(tc, sysroot, os_lib_dir); | ||
| 114 | |||
| 115 | try tc.addPathIfExists(&.{ sysroot, "/lib", multiarch_triple }, .file); | ||
| 116 | try tc.addPathIfExists(&.{ sysroot, "/lib", "..", os_lib_dir }, .file); | ||
| 117 | |||
| 118 | if (target.abi.isAndroid()) { | ||
| 119 | // TODO | ||
| 120 | } | ||
| 121 | try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", multiarch_triple }, .file); | ||
| 122 | try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", "..", os_lib_dir }, .file); | ||
| 123 | |||
| 124 | try self.addMultiArchPaths(tc); | ||
| 125 | |||
| 126 | try tc.addPathIfExists(&.{ sysroot, "/lib" }, .file); | ||
| 127 | try tc.addPathIfExists(&.{ sysroot, "/usr", "lib" }, .file); | ||
| 128 | } | ||
| 129 | |||
| 130 | pub fn deinit(self: *Linux, allocator: std.mem.Allocator) void { | ||
| 131 | self.extra_opts.deinit(allocator); | ||
| 132 | } | ||
| 133 | |||
| 134 | fn isPIEDefault(self: *const Linux) bool { | ||
| 135 | _ = self; | ||
| 136 | return false; | ||
| 137 | } | ||
| 138 | |||
| 139 | fn getPIE(self: *const Linux, d: *const Driver) bool { | ||
| 140 | if (d.shared or d.static or d.relocatable or d.static_pie) { | ||
| 141 | return false; | ||
| 142 | } | ||
| 143 | return d.pie orelse self.isPIEDefault(); | ||
| 144 | } | ||
| 145 | |||
| 146 | fn getStaticPIE(self: *const Linux, d: *Driver) !bool { | ||
| 147 | _ = self; | ||
| 148 | if (d.static_pie and d.pie != null) { | ||
| 149 | try d.err("cannot specify 'nopie' along with 'static-pie'", .{}); | ||
| 150 | } | ||
| 151 | return d.static_pie; | ||
| 152 | } | ||
| 153 | |||
| 154 | fn getStatic(self: *const Linux, d: *const Driver) bool { | ||
| 155 | _ = self; | ||
| 156 | return d.static and !d.static_pie; | ||
| 157 | } | ||
| 158 | |||
| 159 | pub fn getDefaultLinker(self: *const Linux, target: std.Target) []const u8 { | ||
| 160 | _ = self; | ||
| 161 | if (target.abi.isAndroid()) { | ||
| 162 | return "ld.lld"; | ||
| 163 | } | ||
| 164 | return "ld"; | ||
| 165 | } | ||
| 166 | |||
| 167 | pub fn buildLinkerArgs(self: *const Linux, tc: *const Toolchain, argv: *std.array_list.Managed([]const u8)) Compilation.Error!void { | ||
| 168 | const d = tc.driver; | ||
| 169 | const target = tc.getTarget(); | ||
| 170 | |||
| 171 | const is_pie = self.getPIE(d); | ||
| 172 | const is_static_pie = try self.getStaticPIE(d); | ||
| 173 | const is_static = self.getStatic(d); | ||
| 174 | const is_android = target.abi.isAndroid(); | ||
| 175 | const is_ve = target.cpu.arch == .ve; | ||
| 176 | const has_crt_begin_end_files = target.abi != .none; // TODO: clang checks for MIPS vendor | ||
| 177 | |||
| 178 | if (is_pie) { | ||
| 179 | try argv.append("-pie"); | ||
| 180 | } | ||
| 181 | if (is_static_pie) { | ||
| 182 | try argv.appendSlice(&.{ "-static", "-pie", "--no-dynamic-linker", "-z", "text" }); | ||
| 183 | } | ||
| 184 | |||
| 185 | if (d.rdynamic) { | ||
| 186 | try argv.append("-export-dynamic"); | ||
| 187 | } | ||
| 188 | |||
| 189 | if (d.strip) { | ||
| 190 | try argv.append("-s"); | ||
| 191 | } | ||
| 192 | |||
| 193 | try argv.appendSlice(self.extra_opts.items); | ||
| 194 | try argv.append("--eh-frame-hdr"); | ||
| 195 | |||
| 196 | // Todo: Driver should parse `-EL`/`-EB` for arm to set endianness for arm targets | ||
| 197 | if (target_util.ldEmulationOption(d.comp.target, null)) |emulation| { | ||
| 198 | try argv.appendSlice(&.{ "-m", emulation }); | ||
| 199 | } else { | ||
| 200 | try d.err("Unknown target triple", .{}); | ||
| 201 | return; | ||
| 202 | } | ||
| 203 | if (d.comp.target.cpu.arch.isRISCV()) { | ||
| 204 | try argv.append("-X"); | ||
| 205 | } | ||
| 206 | if (d.shared) { | ||
| 207 | try argv.append("-shared"); | ||
| 208 | } | ||
| 209 | if (is_static) { | ||
| 210 | try argv.append("-static"); | ||
| 211 | } else { | ||
| 212 | if (d.rdynamic) { | ||
| 213 | try argv.append("-export-dynamic"); | ||
| 214 | } | ||
| 215 | if (!d.shared and !is_static_pie and !d.relocatable) { | ||
| 216 | const dynamic_linker = d.comp.target.standardDynamicLinkerPath(); | ||
| 217 | // todo: check for --dyld-prefix | ||
| 218 | if (dynamic_linker.get()) |path| { | ||
| 219 | try argv.appendSlice(&.{ "-dynamic-linker", try d.comp.arena.dupe(u8, path) }); | ||
| 220 | } else { | ||
| 221 | try d.err("Could not find dynamic linker path", .{}); | ||
| 222 | } | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | try argv.appendSlice(&.{ "-o", d.output_name orelse "a.out" }); | ||
| 227 | |||
| 228 | if (!d.nostdlib and !d.nostartfiles and !d.relocatable) { | ||
| 229 | if (!is_android) { | ||
| 230 | if (!d.shared) { | ||
| 231 | const crt1 = if (is_pie) | ||
| 232 | "Scrt1.o" | ||
| 233 | else if (is_static_pie) | ||
| 234 | "rcrt1.o" | ||
| 235 | else | ||
| 236 | "crt1.o"; | ||
| 237 | try argv.append(try tc.getFilePath(crt1)); | ||
| 238 | } | ||
| 239 | try argv.append(try tc.getFilePath("crti.o")); | ||
| 240 | } | ||
| 241 | if (is_ve) { | ||
| 242 | try argv.appendSlice(&.{ "-z", "max-page-size=0x4000000" }); | ||
| 243 | } | ||
| 244 | |||
| 245 | if (has_crt_begin_end_files) { | ||
| 246 | var path: []const u8 = ""; | ||
| 247 | if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) { | ||
| 248 | const crt_begin = try tc.getCompilerRt("crtbegin", .object); | ||
| 249 | if (tc.filesystem.exists(crt_begin)) { | ||
| 250 | path = crt_begin; | ||
| 251 | } | ||
| 252 | } | ||
| 253 | if (path.len == 0) { | ||
| 254 | const crt_begin = if (tc.driver.shared) | ||
| 255 | if (is_android) "crtbegin_so.o" else "crtbeginS.o" | ||
| 256 | else if (is_static) | ||
| 257 | if (is_android) "crtbegin_static.o" else "crtbeginT.o" | ||
| 258 | else if (is_pie or is_static_pie) | ||
| 259 | if (is_android) "crtbegin_dynamic.o" else "crtbeginS.o" | ||
| 260 | else if (is_android) "crtbegin_dynamic.o" else "crtbegin.o"; | ||
| 261 | path = try tc.getFilePath(crt_begin); | ||
| 262 | } | ||
| 263 | try argv.append(path); | ||
| 264 | } | ||
| 265 | } | ||
| 266 | |||
| 267 | // TODO add -L opts | ||
| 268 | // TODO add -u opts | ||
| 269 | |||
| 270 | try tc.addFilePathLibArgs(argv); | ||
| 271 | |||
| 272 | // TODO handle LTO | ||
| 273 | |||
| 274 | try argv.appendSlice(d.link_objects.items); | ||
| 275 | |||
| 276 | if (!d.nostdlib and !d.relocatable) { | ||
| 277 | if (!d.nodefaultlibs) { | ||
| 278 | if (is_static or is_static_pie) { | ||
| 279 | try argv.append("--start-group"); | ||
| 280 | } | ||
| 281 | try tc.addRuntimeLibs(argv); | ||
| 282 | |||
| 283 | // TODO: add pthread if needed | ||
| 284 | if (!d.nolibc) { | ||
| 285 | try argv.append("-lc"); | ||
| 286 | } | ||
| 287 | if (is_static or is_static_pie) { | ||
| 288 | try argv.append("--end-group"); | ||
| 289 | } else { | ||
| 290 | try tc.addRuntimeLibs(argv); | ||
| 291 | } | ||
| 292 | } | ||
| 293 | if (!d.nostartfiles) { | ||
| 294 | if (has_crt_begin_end_files) { | ||
| 295 | var path: []const u8 = ""; | ||
| 296 | if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) { | ||
| 297 | const crt_end = try tc.getCompilerRt("crtend", .object); | ||
| 298 | if (tc.filesystem.exists(crt_end)) { | ||
| 299 | path = crt_end; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | if (path.len == 0) { | ||
| 303 | const crt_end = if (d.shared) | ||
| 304 | if (is_android) "crtend_so.o" else "crtendS.o" | ||
| 305 | else if (is_pie or is_static_pie) | ||
| 306 | if (is_android) "crtend_android.o" else "crtendS.o" | ||
| 307 | else if (is_android) "crtend_android.o" else "crtend.o"; | ||
| 308 | path = try tc.getFilePath(crt_end); | ||
| 309 | } | ||
| 310 | try argv.append(path); | ||
| 311 | } | ||
| 312 | if (!is_android) { | ||
| 313 | try argv.append(try tc.getFilePath("crtn.o")); | ||
| 314 | } | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | // TODO add -T args | ||
| 319 | } | ||
| 320 | |||
| 321 | fn getMultiarchTriple(target: std.Target) ?[]const u8 { | ||
| 322 | const is_android = target.abi.isAndroid(); | ||
| 323 | const is_mips_r6 = std.Target.mips.featureSetHas(target.cpu.features, .mips32r6); | ||
| 324 | return switch (target.cpu.arch) { | ||
| 325 | .arm, .thumb => if (is_android) "arm-linux-androideabi" else if (target.abi == .gnueabihf) "arm-linux-gnueabihf" else "arm-linux-gnueabi", | ||
| 326 | .armeb, .thumbeb => if (target.abi == .gnueabihf) "armeb-linux-gnueabihf" else "armeb-linux-gnueabi", | ||
| 327 | .aarch64 => if (is_android) "aarch64-linux-android" else "aarch64-linux-gnu", | ||
| 328 | .aarch64_be => "aarch64_be-linux-gnu", | ||
| 329 | .x86 => if (is_android) "i686-linux-android" else "i386-linux-gnu", | ||
| 330 | .x86_64 => if (is_android) "x86_64-linux-android" else if (target.abi == .gnux32) "x86_64-linux-gnux32" else "x86_64-linux-gnu", | ||
| 331 | .m68k => "m68k-linux-gnu", | ||
| 332 | .mips => if (is_mips_r6) "mipsisa32r6-linux-gnu" else "mips-linux-gnu", | ||
| 333 | .mipsel => if (is_android) "mipsel-linux-android" else if (is_mips_r6) "mipsisa32r6el-linux-gnu" else "mipsel-linux-gnu", | ||
| 334 | .powerpcle => "powerpcle-linux-gnu", | ||
| 335 | .powerpc64 => "powerpc64-linux-gnu", | ||
| 336 | .powerpc64le => "powerpc64le-linux-gnu", | ||
| 337 | .riscv64 => "riscv64-linux-gnu", | ||
| 338 | .sparc => "sparc-linux-gnu", | ||
| 339 | .sparc64 => "sparc64-linux-gnu", | ||
| 340 | .s390x => "s390x-linux-gnu", | ||
| 341 | |||
| 342 | // TODO: expand this | ||
| 343 | else => null, | ||
| 344 | }; | ||
| 345 | } | ||
| 346 | |||
| 347 | fn getOSLibDir(target: std.Target) []const u8 { | ||
| 348 | switch (target.cpu.arch) { | ||
| 349 | .x86, | ||
| 350 | .powerpc, | ||
| 351 | .powerpcle, | ||
| 352 | .sparc, | ||
| 353 | => return "lib32", | ||
| 354 | else => {}, | ||
| 355 | } | ||
| 356 | if (target.cpu.arch == .x86_64 and (target.abi == .gnux32 or target.abi == .muslx32)) { | ||
| 357 | return "libx32"; | ||
| 358 | } | ||
| 359 | if (target.cpu.arch == .riscv32) { | ||
| 360 | return "lib32"; | ||
| 361 | } | ||
| 362 | if (target.ptrBitWidth() == 32) { | ||
| 363 | return "lib"; | ||
| 364 | } | ||
| 365 | return "lib64"; | ||
| 366 | } | ||
| 367 | |||
| 368 | pub fn defineSystemIncludes(self: *const Linux, tc: *const Toolchain) !void { | ||
| 369 | if (tc.driver.nostdinc) return; | ||
| 370 | |||
| 371 | const comp = tc.driver.comp; | ||
| 372 | const target = tc.getTarget(); | ||
| 373 | |||
| 374 | // musl prefers /usr/include before builtin includes, so musl targets will add builtins | ||
| 375 | // at the end of this function (unless disabled with nostdlibinc) | ||
| 376 | if (!tc.driver.nobuiltininc and (!target.abi.isMusl() or tc.driver.nostdlibinc)) { | ||
| 377 | try comp.addBuiltinIncludeDir(tc.driver.aro_name, tc.driver.resource_dir); | ||
| 378 | } | ||
| 379 | |||
| 380 | if (tc.driver.nostdlibinc) return; | ||
| 381 | |||
| 382 | const sysroot = tc.getSysroot(); | ||
| 383 | const local_include = try std.fs.path.join(comp.gpa, &.{ sysroot, "/usr/local/include" }); | ||
| 384 | defer comp.gpa.free(local_include); | ||
| 385 | try comp.addSystemIncludeDir(local_include); | ||
| 386 | |||
| 387 | if (self.gcc_detector.is_valid) { | ||
| 388 | const gcc_include_path = try std.fs.path.join(comp.gpa, &.{ self.gcc_detector.parent_lib_path, "..", self.gcc_detector.gcc_triple, "include" }); | ||
| 389 | defer comp.gpa.free(gcc_include_path); | ||
| 390 | try comp.addSystemIncludeDir(gcc_include_path); | ||
| 391 | } | ||
| 392 | |||
| 393 | if (getMultiarchTriple(target)) |triple| { | ||
| 394 | const joined = try std.fs.path.join(comp.gpa, &.{ sysroot, "/usr/include", triple }); | ||
| 395 | defer comp.gpa.free(joined); | ||
| 396 | if (tc.filesystem.exists(joined)) { | ||
| 397 | try comp.addSystemIncludeDir(joined); | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | if (target.os.tag == .rtems) return; | ||
| 402 | |||
| 403 | try comp.addSystemIncludeDir("/include"); | ||
| 404 | try comp.addSystemIncludeDir("/usr/include"); | ||
| 405 | |||
| 406 | std.debug.assert(!tc.driver.nostdlibinc); | ||
| 407 | if (!tc.driver.nobuiltininc and target.abi.isMusl()) { | ||
| 408 | try comp.addBuiltinIncludeDir(tc.driver.aro_name, tc.driver.resource_dir); | ||
| 409 | } | ||
| 410 | } | ||
| 411 | |||
| 412 | test Linux { | ||
| 413 | if (@import("builtin").os.tag == .windows) return error.SkipZigTest; | ||
| 414 | |||
| 415 | var arena_instance = std.heap.ArenaAllocator.init(std.testing.allocator); | ||
| 416 | defer arena_instance.deinit(); | ||
| 417 | const arena = arena_instance.allocator(); | ||
| 418 | |||
| 419 | var comp = Compilation.init(std.testing.allocator, arena, undefined, std.fs.cwd()); | ||
| 420 | defer comp.deinit(); | ||
| 421 | comp.environment = .{ | ||
| 422 | .path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", | ||
| 423 | }; | ||
| 424 | defer comp.environment = .{}; | ||
| 425 | |||
| 426 | const raw_triple = "x86_64-linux-gnu"; | ||
| 427 | const target_query = try std.Target.Query.parse(.{ .arch_os_abi = raw_triple }); | ||
| 428 | comp.target = try std.zig.system.resolveTargetQuery(target_query); | ||
| 429 | comp.langopts.setEmulatedCompiler(.gcc); | ||
| 430 | |||
| 431 | var driver: Driver = .{ .comp = &comp, .diagnostics = undefined }; | ||
| 432 | defer driver.deinit(); | ||
| 433 | driver.raw_target_triple = raw_triple; | ||
| 434 | |||
| 435 | const link_obj = try driver.comp.gpa.dupe(u8, "/tmp/foo.o"); | ||
| 436 | try driver.link_objects.append(driver.comp.gpa, link_obj); | ||
| 437 | driver.temp_file_count += 1; | ||
| 438 | |||
| 439 | var toolchain: Toolchain = .{ .driver = &driver, .filesystem = .{ .fake = &.{ | ||
| 440 | .{ .path = "/tmp" }, | ||
| 441 | .{ .path = "/usr" }, | ||
| 442 | .{ .path = "/usr/lib64" }, | ||
| 443 | .{ .path = "/usr/bin" }, | ||
| 444 | .{ .path = "/usr/bin/ld", .executable = true }, | ||
| 445 | .{ .path = "/lib" }, | ||
| 446 | .{ .path = "/lib/x86_64-linux-gnu" }, | ||
| 447 | .{ .path = "/lib/x86_64-linux-gnu/crt1.o" }, | ||
| 448 | .{ .path = "/lib/x86_64-linux-gnu/crti.o" }, | ||
| 449 | .{ .path = "/lib/x86_64-linux-gnu/crtn.o" }, | ||
| 450 | .{ .path = "/lib64" }, | ||
| 451 | .{ .path = "/usr/lib" }, | ||
| 452 | .{ .path = "/usr/lib/gcc" }, | ||
| 453 | .{ .path = "/usr/lib/gcc/x86_64-linux-gnu" }, | ||
| 454 | .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9" }, | ||
| 455 | .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o" }, | ||
| 456 | .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o" }, | ||
| 457 | .{ .path = "/usr/lib/x86_64-linux-gnu" }, | ||
| 458 | .{ .path = "/etc/lsb-release", .contents = | ||
| 459 | \\DISTRIB_ID=Ubuntu | ||
| 460 | \\DISTRIB_RELEASE=20.04 | ||
| 461 | \\DISTRIB_CODENAME=focal | ||
| 462 | \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS" | ||
| 463 | \\ | ||
| 464 | }, | ||
| 465 | } } }; | ||
| 466 | defer toolchain.deinit(); | ||
| 467 | |||
| 468 | try toolchain.discover(); | ||
| 469 | |||
| 470 | var argv = std.array_list.Managed([]const u8).init(driver.comp.gpa); | ||
| 471 | defer argv.deinit(); | ||
| 472 | |||
| 473 | var linker_path_buf: [std.fs.max_path_bytes]u8 = undefined; | ||
| 474 | const linker_path = try toolchain.getLinkerPath(&linker_path_buf); | ||
| 475 | try argv.append(linker_path); | ||
| 476 | |||
| 477 | try toolchain.buildLinkerArgs(&argv); | ||
| 478 | |||
| 479 | const expected = [_][]const u8{ | ||
| 480 | "/usr/bin/ld", | ||
| 481 | "-z", | ||
| 482 | "relro", | ||
| 483 | "--hash-style=gnu", | ||
| 484 | "--eh-frame-hdr", | ||
| 485 | "-m", | ||
| 486 | "elf_x86_64", | ||
| 487 | "-dynamic-linker", | ||
| 488 | "/lib64/ld-linux-x86-64.so.2", | ||
| 489 | "-o", | ||
| 490 | "a.out", | ||
| 491 | "/lib/x86_64-linux-gnu/crt1.o", | ||
| 492 | "/lib/x86_64-linux-gnu/crti.o", | ||
| 493 | "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o", | ||
| 494 | "-L/usr/lib/gcc/x86_64-linux-gnu/9", | ||
| 495 | "-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib64", | ||
| 496 | "-L/lib/x86_64-linux-gnu", | ||
| 497 | "-L/lib/../lib64", | ||
| 498 | "-L/usr/lib/x86_64-linux-gnu", | ||
| 499 | "-L/usr/lib/../lib64", | ||
| 500 | "-L/lib", | ||
| 501 | "-L/usr/lib", | ||
| 502 | link_obj, | ||
| 503 | "-lgcc", | ||
| 504 | "--as-needed", | ||
| 505 | "-lgcc_s", | ||
| 506 | "--no-as-needed", | ||
| 507 | "-lc", | ||
| 508 | "-lgcc", | ||
| 509 | "--as-needed", | ||
| 510 | "-lgcc_s", | ||
| 511 | "--no-as-needed", | ||
| 512 | "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o", | ||
| 513 | "/lib/x86_64-linux-gnu/crtn.o", | ||
| 514 | }; | ||
| 515 | try std.testing.expectEqual(expected.len, argv.items.len); | ||
| 516 | for (expected, argv.items) |expected_item, actual_item| { | ||
| 517 | try std.testing.expectEqualStrings(expected_item, actual_item); | ||
| 518 | } | ||
| 519 | } | ||
lib/compiler/translate-c/PatternList.zig+1-1| ... | @@ -10,7 +10,7 @@ const Translator = @import("Translator.zig"); | ... | @@ -10,7 +10,7 @@ const Translator = @import("Translator.zig"); |
| 10 | const Error = Translator.Error; | 10 | const Error = Translator.Error; |
| 11 | pub const MacroProcessingError = Error || error{UnexpectedMacroToken}; | 11 | pub const MacroProcessingError = Error || error{UnexpectedMacroToken}; |
| 12 | 12 | ||
| 13 | const Impl = std.meta.DeclEnum(@import("helpers")); | 13 | const Impl = std.meta.DeclEnum(std.zig.c_translation.helpers); |
| 14 | const Template = struct { []const u8, Impl }; | 14 | const Template = struct { []const u8, Impl }; |
| 15 | 15 | ||
| 16 | /// Templates must be function-like macros | 16 | /// Templates must be function-like macros |
lib/compiler/translate-c/Translator.zig+11-21| ... | @@ -169,7 +169,6 @@ pub const Options = struct { | ... | @@ -169,7 +169,6 @@ pub const Options = struct { |
| 169 | comp: *aro.Compilation, | 169 | comp: *aro.Compilation, |
| 170 | pp: *const aro.Preprocessor, | 170 | pp: *const aro.Preprocessor, |
| 171 | tree: *const aro.Tree, | 171 | tree: *const aro.Tree, |
| 172 | module_libs: bool, | ||
| 173 | }; | 172 | }; |
| 174 | 173 | ||
| 175 | pub fn translate(options: Options) ![]u8 { | 174 | pub fn translate(options: Options) ![]u8 { |
| ... | @@ -217,32 +216,23 @@ pub fn translate(options: Options) ![]u8 { | ... | @@ -217,32 +216,23 @@ pub fn translate(options: Options) ![]u8 { |
| 217 | 216 | ||
| 218 | try translator.global_scope.processContainerMemberFns(); | 217 | try translator.global_scope.processContainerMemberFns(); |
| 219 | 218 | ||
| 220 | var buf: std.ArrayList(u8) = .init(gpa); | 219 | var aw: std.Io.Writer.Allocating = .init(gpa); |
| 221 | defer buf.deinit(); | 220 | defer aw.deinit(); |
| 222 | 221 | ||
| 223 | if (options.module_libs) { | 222 | try aw.writer.writeAll( |
| 224 | try buf.appendSlice( | 223 | \\pub const __builtin = @import("std").zig.c_translation.builtins; |
| 225 | \\pub const __builtin = @import("c_builtins"); | 224 | \\pub const __helpers = @import("std").zig.c_translation.helpers; |
| 226 | \\pub const __helpers = @import("helpers"); | 225 | \\ |
| 227 | \\ | 226 | \\ |
| 228 | \\ | 227 | ); |
| 229 | ); | ||
| 230 | } else { | ||
| 231 | try buf.appendSlice( | ||
| 232 | \\pub const __builtin = @import("c_builtins.zig"); | ||
| 233 | \\pub const __helpers = @import("helpers.zig"); | ||
| 234 | \\ | ||
| 235 | \\ | ||
| 236 | ); | ||
| 237 | } | ||
| 238 | 228 | ||
| 239 | var zig_ast = try ast.render(gpa, translator.global_scope.nodes.items); | 229 | var zig_ast = try ast.render(gpa, translator.global_scope.nodes.items); |
| 240 | defer { | 230 | defer { |
| 241 | gpa.free(zig_ast.source); | 231 | gpa.free(zig_ast.source); |
| 242 | zig_ast.deinit(gpa); | 232 | zig_ast.deinit(gpa); |
| 243 | } | 233 | } |
| 244 | try zig_ast.renderToArrayList(&buf, .{}); | 234 | try zig_ast.render(gpa, &aw.writer, .{}); |
| 245 | return buf.toOwnedSlice(); | 235 | return aw.toOwnedSlice(); |
| 246 | } | 236 | } |
| 247 | 237 | ||
| 248 | fn prepopulateGlobalNameTable(t: *Translator) !void { | 238 | fn prepopulateGlobalNameTable(t: *Translator) !void { |
| ... | @@ -3905,7 +3895,7 @@ fn createBinOpNode( | ... | @@ -3905,7 +3895,7 @@ fn createBinOpNode( |
| 3905 | return ZigNode.initPayload(&payload.base); | 3895 | return ZigNode.initPayload(&payload.base); |
| 3906 | } | 3896 | } |
| 3907 | 3897 | ||
| 3908 | pub fn createHelperCallNode(t: *Translator, name: std.meta.DeclEnum(@import("helpers")), args_opt: ?[]const ZigNode) !ZigNode { | 3898 | pub fn createHelperCallNode(t: *Translator, name: std.meta.DeclEnum(std.zig.c_translation.helpers), args_opt: ?[]const ZigNode) !ZigNode { |
| 3909 | if (args_opt) |args| { | 3899 | if (args_opt) |args| { |
| 3910 | return ZigTag.helper_call.create(t.arena, .{ | 3900 | return ZigTag.helper_call.create(t.arena, .{ |
| 3911 | .name = @tagName(name), | 3901 | .name = @tagName(name), |
lib/compiler/translate-c/main.zig+4-51| ... | @@ -89,8 +89,6 @@ pub const usage = | ... | @@ -89,8 +89,6 @@ pub const usage = |
| 89 | fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { | 89 | fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { |
| 90 | const gpa = d.comp.gpa; | 90 | const gpa = d.comp.gpa; |
| 91 | 91 | ||
| 92 | var module_libs = false; | ||
| 93 | |||
| 94 | const aro_args = args: { | 92 | const aro_args = args: { |
| 95 | var i: usize = 0; | 93 | var i: usize = 0; |
| 96 | for (args) |arg| { | 94 | for (args) |arg| { |
| ... | @@ -108,10 +106,6 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { | ... | @@ -108,10 +106,6 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { |
| 108 | try stdout.interface.writeAll("0.0.0-dev\n"); | 106 | try stdout.interface.writeAll("0.0.0-dev\n"); |
| 109 | try stdout.interface.flush(); | 107 | try stdout.interface.flush(); |
| 110 | return; | 108 | return; |
| 111 | } else if (mem.eql(u8, arg, "-fmodule-libs")) { | ||
| 112 | module_libs = true; | ||
| 113 | } else if (mem.eql(u8, arg, "-fno-module-libs")) { | ||
| 114 | module_libs = false; | ||
| 115 | } else { | 109 | } else { |
| 116 | i += 1; | 110 | i += 1; |
| 117 | } | 111 | } |
| ... | @@ -174,7 +168,6 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { | ... | @@ -174,7 +168,6 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { |
| 174 | .comp = d.comp, | 168 | .comp = d.comp, |
| 175 | .pp = &pp, | 169 | .pp = &pp, |
| 176 | .tree = &c_tree, | 170 | .tree = &c_tree, |
| 177 | .module_libs = module_libs, | ||
| 178 | }); | 171 | }); |
| 179 | defer gpa.free(rendered_zig); | 172 | defer gpa.free(rendered_zig); |
| 180 | 173 | ||
| ... | @@ -201,51 +194,11 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { | ... | @@ -201,51 +194,11 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { |
| 201 | out_writer.interface.writeAll(rendered_zig) catch | 194 | out_writer.interface.writeAll(rendered_zig) catch |
| 202 | return d.fatal("failed to write result to '{s}': {s}", .{ out_file_path, aro.Driver.errorDescription(out_writer.err.?) }); | 195 | return d.fatal("failed to write result to '{s}': {s}", .{ out_file_path, aro.Driver.errorDescription(out_writer.err.?) }); |
| 203 | 196 | ||
| 204 | if (!module_libs) { | ||
| 205 | const dest_path = if (d.output_name) |path| std.fs.path.dirname(path) else null; | ||
| 206 | installLibs(d, dest_path) catch |err| | ||
| 207 | return d.fatal("failed to install library files: {s}", .{aro.Driver.errorDescription(err)}); | ||
| 208 | } | ||
| 209 | |||
| 210 | if (fast_exit) process.exit(0); | 197 | if (fast_exit) process.exit(0); |
| 211 | } | 198 | } |
| 212 | 199 | ||
| 213 | fn installLibs(d: *aro.Driver, dest_path: ?[]const u8) !void { | 200 | test { |
| 214 | const gpa = d.comp.gpa; | 201 | _ = Translator; |
| 215 | const cwd = std.fs.cwd(); | 202 | _ = @import("helpers.zig"); |
| 216 | 203 | _ = @import("PatternList.zig"); | |
| 217 | const self_exe_path = try std.fs.selfExePathAlloc(gpa); | ||
| 218 | defer gpa.free(self_exe_path); | ||
| 219 | |||
| 220 | var cur_dir: []const u8 = self_exe_path; | ||
| 221 | while (std.fs.path.dirname(cur_dir)) |dirname| : (cur_dir = dirname) { | ||
| 222 | var base_dir = cwd.openDir(dirname, .{}) catch continue; | ||
| 223 | defer base_dir.close(); | ||
| 224 | |||
| 225 | var lib_dir = base_dir.openDir("lib", .{}) catch continue; | ||
| 226 | defer lib_dir.close(); | ||
| 227 | |||
| 228 | lib_dir.access("c_builtins.zig", .{}) catch continue; | ||
| 229 | |||
| 230 | { | ||
| 231 | const install_path = try std.fs.path.join(gpa, &.{ dest_path orelse "", "c_builtins.zig" }); | ||
| 232 | defer gpa.free(install_path); | ||
| 233 | try lib_dir.copyFile("c_builtins.zig", cwd, install_path, .{}); | ||
| 234 | } | ||
| 235 | { | ||
| 236 | const install_path = try std.fs.path.join(gpa, &.{ dest_path orelse "", "helpers.zig" }); | ||
| 237 | defer gpa.free(install_path); | ||
| 238 | try lib_dir.copyFile("helpers.zig", cwd, install_path, .{}); | ||
| 239 | } | ||
| 240 | return; | ||
| 241 | } | ||
| 242 | return error.FileNotFound; | ||
| 243 | } | ||
| 244 | |||
| 245 | comptime { | ||
| 246 | if (@import("builtin").is_test) { | ||
| 247 | _ = Translator; | ||
| 248 | _ = @import("helpers.zig"); | ||
| 249 | _ = @import("PatternList.zig"); | ||
| 250 | } | ||
| 251 | } | 204 | } |
src/main.zig+1-1| ... | @@ -4549,7 +4549,7 @@ fn cmdTranslateC( | ... | @@ -4549,7 +4549,7 @@ fn cmdTranslateC( |
| 4549 | 4549 | ||
| 4550 | try jitCmd(comp.gpa, arena, argv.items, .{ | 4550 | try jitCmd(comp.gpa, arena, argv.items, .{ |
| 4551 | .cmd_name = "translate-c", | 4551 | .cmd_name = "translate-c", |
| 4552 | .root_src_path = "translate-c/src/main.zig", | 4552 | .root_src_path = "translate-c/main.zig", |
| 4553 | .depend_on_aro = true, | 4553 | .depend_on_aro = true, |
| 4554 | .progress_node = prog_node, | 4554 | .progress_node = prog_node, |
| 4555 | }); | 4555 | }); |