| 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 | 37 | _ = @import("aro/Preprocessor.zig"); |
| 38 | 38 | _ = @import("aro/target.zig"); |
| 39 | 39 | _ = @import("aro/Tokenizer.zig"); |
| 40 | _ = @import("aro/toolchains/Linux.zig"); | |
| 41 | 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 | 99 | use_assembly_backend: bool = false, |
| 100 | 100 | |
| 101 | 101 | // linker options |
| 102 | use_linker: ?[]const u8 = null, | |
| 103 | 102 | linker_path: ?[]const u8 = null, |
| 104 | 103 | nodefaultlibs: bool = false, |
| 105 | 104 | nolibc: bool = false, |
| ... | ... | @@ -572,10 +571,6 @@ pub fn parseArgs( |
| 572 | 571 | d.comp.langopts.preserve_comments = true; |
| 573 | 572 | d.comp.langopts.preserve_comments_in_macros = true; |
| 574 | 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 | 574 | } else if (option(arg, "--ld-path=")) |linker_path| { |
| 580 | 575 | d.linker_path = linker_path; |
| 581 | 576 | } else if (mem.eql(u8, arg, "-r")) { |
| ... | ... | @@ -1150,29 +1145,20 @@ fn exitWithCleanup(d: *Driver, code: u8) noreturn { |
| 1150 | 1145 | /// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments. |
| 1151 | 1146 | /// Then, smooshes them together with platform defaults, to decide whether |
| 1152 | 1147 | /// this compile should be using PIC mode or not. |
| 1153 | /// Returns a tuple of ( backend.CodeGenOptions.PicLevel, IsPIE). | |
| 1154 | 1148 | pub fn getPICMode(d: *Driver, lastpic: []const u8) Compilation.Error!struct { backend.CodeGenOptions.PicLevel, bool } { |
| 1155 | 1149 | const eqlIgnoreCase = std.ascii.eqlIgnoreCase; |
| 1156 | 1150 | |
| 1157 | 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 | 1153 | const is_pie_default = switch (target_util.isPIEDefault(target)) { |
| 1162 | 1154 | .yes => true, |
| 1163 | 1155 | .no => false, |
| 1164 | .depends_on_linker => if (is_bfd_linker) | |
| 1165 | target.cpu.arch == .x86_64 // CrossWindows | |
| 1166 | else | |
| 1167 | false, //MSVC | |
| 1156 | .depends_on_linker => false, | |
| 1168 | 1157 | }; |
| 1169 | 1158 | const is_pic_default = switch (target_util.isPICdefault(target)) { |
| 1170 | 1159 | .yes => true, |
| 1171 | 1160 | .no => false, |
| 1172 | .depends_on_linker => if (is_bfd_linker) | |
| 1173 | target.cpu.arch == .x86_64 | |
| 1174 | else | |
| 1175 | (target.cpu.arch == .x86_64 or target.cpu.arch == .aarch64), | |
| 1161 | .depends_on_linker => false, | |
| 1176 | 1162 | }; |
| 1177 | 1163 | |
| 1178 | 1164 | var pie: bool = is_pie_default; |
| ... | ... | @@ -1239,7 +1225,7 @@ pub fn getPICMode(d: *Driver, lastpic: []const u8) Compilation.Error!struct { ba |
| 1239 | 1225 | const forced = switch (target_util.isPICDefaultForced(target)) { |
| 1240 | 1226 | .yes => true, |
| 1241 | 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 | 1230 | if (!forced) { |
| 1245 | 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 | 8 | const Filesystem = @import("Driver/Filesystem.zig").Filesystem; |
| 9 | 9 | const Multilib = @import("Driver/Multilib.zig"); |
| 10 | 10 | const target_util = @import("target.zig"); |
| 11 | const Linux = @import("toolchains/Linux.zig"); | |
| 12 | 11 | |
| 13 | 12 | pub const PathList = std.ArrayListUnmanaged([]const u8); |
| 14 | 13 | |
| ... | ... | @@ -37,15 +36,7 @@ pub const UnwindLibKind = enum { |
| 37 | 36 | |
| 38 | 37 | const Inner = union(enum) { |
| 39 | 38 | uninitialized, |
| 40 | linux: Linux, | |
| 41 | 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 | 42 | const Toolchain = @This(); |
| ... | ... | @@ -81,32 +72,15 @@ fn getDefaultLinker(tc: *const Toolchain) []const u8 { |
| 81 | 72 | /// Call this after driver has finished parsing command line arguments to find the toolchain |
| 82 | 73 | pub fn discover(tc: *Toolchain) !void { |
| 83 | 74 | if (tc.inner != .uninitialized) return; |
| 84 | ||
| 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 | }; | |
| 75 | tc.inner = .unknown; | |
| 100 | 76 | return switch (tc.inner) { |
| 101 | 77 | .uninitialized => unreachable, |
| 102 | .linux => |*linux| linux.discover(tc), | |
| 103 | 78 | .unknown => {}, |
| 104 | 79 | }; |
| 105 | 80 | } |
| 106 | 81 | |
| 107 | 82 | pub fn deinit(tc: *Toolchain) void { |
| 108 | 83 | const gpa = tc.driver.comp.gpa; |
| 109 | tc.inner.deinit(gpa); | |
| 110 | 84 | |
| 111 | 85 | tc.library_paths.deinit(gpa); |
| 112 | 86 | tc.file_paths.deinit(gpa); |
| ... | ... | @@ -501,7 +475,6 @@ pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.array_list.Managed([]cons |
| 501 | 475 | pub fn defineSystemIncludes(tc: *Toolchain) !void { |
| 502 | 476 | return switch (tc.inner) { |
| 503 | 477 | .uninitialized => unreachable, |
| 504 | .linux => |*linux| linux.defineSystemIncludes(tc), | |
| 505 | 478 | .unknown => { |
| 506 | 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 | 10 | const Error = Translator.Error; |
| 11 | 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 | 14 | const Template = struct { []const u8, Impl }; |
| 15 | 15 | |
| 16 | 16 | /// Templates must be function-like macros |
lib/compiler/translate-c/Translator.zig+11-21| ... | ... | @@ -169,7 +169,6 @@ pub const Options = struct { |
| 169 | 169 | comp: *aro.Compilation, |
| 170 | 170 | pp: *const aro.Preprocessor, |
| 171 | 171 | tree: *const aro.Tree, |
| 172 | module_libs: bool, | |
| 173 | 172 | }; |
| 174 | 173 | |
| 175 | 174 | pub fn translate(options: Options) ![]u8 { |
| ... | ... | @@ -217,32 +216,23 @@ pub fn translate(options: Options) ![]u8 { |
| 217 | 216 | |
| 218 | 217 | try translator.global_scope.processContainerMemberFns(); |
| 219 | 218 | |
| 220 | var buf: std.ArrayList(u8) = .init(gpa); | |
| 221 | defer buf.deinit(); | |
| 219 | var aw: std.Io.Writer.Allocating = .init(gpa); | |
| 220 | defer aw.deinit(); | |
| 222 | 221 | |
| 223 | if (options.module_libs) { | |
| 224 | try buf.appendSlice( | |
| 225 | \\pub const __builtin = @import("c_builtins"); | |
| 226 | \\pub const __helpers = @import("helpers"); | |
| 227 | \\ | |
| 228 | \\ | |
| 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 | } | |
| 222 | try aw.writer.writeAll( | |
| 223 | \\pub const __builtin = @import("std").zig.c_translation.builtins; | |
| 224 | \\pub const __helpers = @import("std").zig.c_translation.helpers; | |
| 225 | \\ | |
| 226 | \\ | |
| 227 | ); | |
| 238 | 228 | |
| 239 | 229 | var zig_ast = try ast.render(gpa, translator.global_scope.nodes.items); |
| 240 | 230 | defer { |
| 241 | 231 | gpa.free(zig_ast.source); |
| 242 | 232 | zig_ast.deinit(gpa); |
| 243 | 233 | } |
| 244 | try zig_ast.renderToArrayList(&buf, .{}); | |
| 245 | return buf.toOwnedSlice(); | |
| 234 | try zig_ast.render(gpa, &aw.writer, .{}); | |
| 235 | return aw.toOwnedSlice(); | |
| 246 | 236 | } |
| 247 | 237 | |
| 248 | 238 | fn prepopulateGlobalNameTable(t: *Translator) !void { |
| ... | ... | @@ -3905,7 +3895,7 @@ fn createBinOpNode( |
| 3905 | 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 | 3899 | if (args_opt) |args| { |
| 3910 | 3900 | return ZigTag.helper_call.create(t.arena, .{ |
| 3911 | 3901 | .name = @tagName(name), |
lib/compiler/translate-c/main.zig+4-51| ... | ... | @@ -89,8 +89,6 @@ pub const usage = |
| 89 | 89 | fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { |
| 90 | 90 | const gpa = d.comp.gpa; |
| 91 | 91 | |
| 92 | var module_libs = false; | |
| 93 | ||
| 94 | 92 | const aro_args = args: { |
| 95 | 93 | var i: usize = 0; |
| 96 | 94 | for (args) |arg| { |
| ... | ... | @@ -108,10 +106,6 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { |
| 108 | 106 | try stdout.interface.writeAll("0.0.0-dev\n"); |
| 109 | 107 | try stdout.interface.flush(); |
| 110 | 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 | 109 | } else { |
| 116 | 110 | i += 1; |
| 117 | 111 | } |
| ... | ... | @@ -174,7 +168,6 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { |
| 174 | 168 | .comp = d.comp, |
| 175 | 169 | .pp = &pp, |
| 176 | 170 | .tree = &c_tree, |
| 177 | .module_libs = module_libs, | |
| 178 | 171 | }); |
| 179 | 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 | 194 | out_writer.interface.writeAll(rendered_zig) catch |
| 202 | 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 | 197 | if (fast_exit) process.exit(0); |
| 211 | 198 | } |
| 212 | 199 | |
| 213 | fn installLibs(d: *aro.Driver, dest_path: ?[]const u8) !void { | |
| 214 | const gpa = d.comp.gpa; | |
| 215 | const cwd = std.fs.cwd(); | |
| 216 | ||
| 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 | } | |
| 200 | test { | |
| 201 | _ = Translator; | |
| 202 | _ = @import("helpers.zig"); | |
| 203 | _ = @import("PatternList.zig"); | |
| 251 | 204 | } |
src/main.zig+1-1| ... | ... | @@ -4549,7 +4549,7 @@ fn cmdTranslateC( |
| 4549 | 4549 | |
| 4550 | 4550 | try jitCmd(comp.gpa, arena, argv.items, .{ |
| 4551 | 4551 | .cmd_name = "translate-c", |
| 4552 | .root_src_path = "translate-c/src/main.zig", | |
| 4552 | .root_src_path = "translate-c/main.zig", | |
| 4553 | 4553 | .depend_on_aro = true, |
| 4554 | 4554 | .progress_node = prog_node, |
| 4555 | 4555 | }); |