| ... | ... | @@ -873,287 +873,302 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 873 | 873 | }; |
| 874 | 874 | } |
| 875 | 875 | |
| 876 | | const is_obj = self.base.options.output_mode == .Obj; |
| 877 | | |
| 878 | | // Create an LLD command line and invoke it. |
| 879 | | var argv = std.ArrayList([]const u8).init(self.base.allocator); |
| 880 | | defer argv.deinit(); |
| 881 | | // Even though we're calling LLD as a library it thinks the first argument is its own exe name. |
| 882 | | try argv.append("lld"); |
| 883 | | if (is_obj) { |
| 884 | | try argv.append("-r"); |
| 885 | | } |
| 876 | const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path}); |
| 886 | 877 | |
| 887 | | try argv.append("-ERRORLIMIT:0"); |
| 888 | | try argv.append("-NOLOGO"); |
| 889 | | if (!self.base.options.strip) { |
| 890 | | try argv.append("-DEBUG"); |
| 891 | | } |
| 892 | | if (self.base.options.output_mode == .Exe) { |
| 893 | | const stack_size = self.base.options.stack_size_override orelse 16777216; |
| 894 | | try argv.append(try allocPrint(arena, "-STACK:{d}", .{stack_size})); |
| 895 | | } |
| 878 | if (self.base.options.output_mode == .Obj) { |
| 879 | // LLD's COFF driver does not support the equvialent of `-r` so we do a simple file copy |
| 880 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 881 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 882 | const the_object_path = blk: { |
| 883 | if (self.base.options.objects.len != 0) |
| 884 | break :blk self.base.options.objects[0]; |
| 896 | 885 | |
| 897 | | if (target.cpu.arch == .i386) { |
| 898 | | try argv.append("-MACHINE:X86"); |
| 899 | | } else if (target.cpu.arch == .x86_64) { |
| 900 | | try argv.append("-MACHINE:X64"); |
| 901 | | } else if (target.cpu.arch.isARM()) { |
| 902 | | if (target.cpu.arch.ptrBitWidth() == 32) { |
| 903 | | try argv.append("-MACHINE:ARM"); |
| 904 | | } else { |
| 905 | | try argv.append("-MACHINE:ARM64"); |
| 886 | if (comp.c_object_table.count() != 0) |
| 887 | break :blk comp.c_object_table.items()[0].key.status.success.object_path; |
| 888 | |
| 889 | if (module_obj_path) |p| |
| 890 | break :blk p; |
| 891 | |
| 892 | // TODO I think this is unreachable. Audit this situation when solving the above TODO |
| 893 | // regarding eliding redundant object -> object transformations. |
| 894 | return error.NoObjectsToLink; |
| 895 | }; |
| 896 | try fs.cwd().copyFile(the_object_path, fs.cwd(), full_out_path, .{}); |
| 897 | } else { |
| 898 | // Create an LLD command line and invoke it. |
| 899 | var argv = std.ArrayList([]const u8).init(self.base.allocator); |
| 900 | defer argv.deinit(); |
| 901 | // Even though we're calling LLD as a library it thinks the first argument is its own exe name. |
| 902 | try argv.append("lld"); |
| 903 | |
| 904 | try argv.append("-ERRORLIMIT:0"); |
| 905 | try argv.append("-NOLOGO"); |
| 906 | if (!self.base.options.strip) { |
| 907 | try argv.append("-DEBUG"); |
| 908 | } |
| 909 | if (self.base.options.output_mode == .Exe) { |
| 910 | const stack_size = self.base.options.stack_size_override orelse 16777216; |
| 911 | try argv.append(try allocPrint(arena, "-STACK:{d}", .{stack_size})); |
| 906 | 912 | } |
| 907 | | } |
| 908 | 913 | |
| 909 | | if (is_dyn_lib) { |
| 910 | | try argv.append("-DLL"); |
| 911 | | } |
| 914 | if (target.cpu.arch == .i386) { |
| 915 | try argv.append("-MACHINE:X86"); |
| 916 | } else if (target.cpu.arch == .x86_64) { |
| 917 | try argv.append("-MACHINE:X64"); |
| 918 | } else if (target.cpu.arch.isARM()) { |
| 919 | if (target.cpu.arch.ptrBitWidth() == 32) { |
| 920 | try argv.append("-MACHINE:ARM"); |
| 921 | } else { |
| 922 | try argv.append("-MACHINE:ARM64"); |
| 923 | } |
| 924 | } |
| 912 | 925 | |
| 913 | | const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path}); |
| 914 | | try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); |
| 926 | if (is_dyn_lib) { |
| 927 | try argv.append("-DLL"); |
| 928 | } |
| 915 | 929 | |
| 916 | | if (self.base.options.link_libc) { |
| 917 | | if (self.base.options.libc_installation) |libc_installation| { |
| 918 | | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?})); |
| 930 | try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); |
| 919 | 931 | |
| 920 | | if (target.abi == .msvc) { |
| 921 | | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.msvc_lib_dir.?})); |
| 922 | | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.kernel32_lib_dir.?})); |
| 932 | if (self.base.options.link_libc) { |
| 933 | if (self.base.options.libc_installation) |libc_installation| { |
| 934 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?})); |
| 935 | |
| 936 | if (target.abi == .msvc) { |
| 937 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.msvc_lib_dir.?})); |
| 938 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.kernel32_lib_dir.?})); |
| 939 | } |
| 923 | 940 | } |
| 924 | 941 | } |
| 925 | | } |
| 926 | 942 | |
| 927 | | for (self.base.options.lib_dirs) |lib_dir| { |
| 928 | | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); |
| 929 | | } |
| 943 | for (self.base.options.lib_dirs) |lib_dir| { |
| 944 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); |
| 945 | } |
| 930 | 946 | |
| 931 | | try argv.appendSlice(self.base.options.objects); |
| 947 | try argv.appendSlice(self.base.options.objects); |
| 932 | 948 | |
| 933 | | for (comp.c_object_table.items()) |entry| { |
| 934 | | try argv.append(entry.key.status.success.object_path); |
| 935 | | } |
| 949 | for (comp.c_object_table.items()) |entry| { |
| 950 | try argv.append(entry.key.status.success.object_path); |
| 951 | } |
| 936 | 952 | |
| 937 | | if (module_obj_path) |p| { |
| 938 | | try argv.append(p); |
| 939 | | } |
| 953 | if (module_obj_path) |p| { |
| 954 | try argv.append(p); |
| 955 | } |
| 940 | 956 | |
| 941 | | const resolved_subsystem: ?std.Target.SubSystem = blk: { |
| 942 | | if (self.base.options.subsystem) |explicit| break :blk explicit; |
| 943 | | switch (target.os.tag) { |
| 944 | | .windows => { |
| 945 | | if (self.base.options.module) |module| { |
| 946 | | if (module.stage1_flags.have_dllmain_crt_startup or is_dyn_lib) |
| 947 | | break :blk null; |
| 948 | | if (module.stage1_flags.have_c_main or self.base.options.is_test or |
| 949 | | module.stage1_flags.have_winmain_crt_startup or |
| 950 | | module.stage1_flags.have_wwinmain_crt_startup) |
| 951 | | { |
| 952 | | break :blk .Console; |
| 957 | const resolved_subsystem: ?std.Target.SubSystem = blk: { |
| 958 | if (self.base.options.subsystem) |explicit| break :blk explicit; |
| 959 | switch (target.os.tag) { |
| 960 | .windows => { |
| 961 | if (self.base.options.module) |module| { |
| 962 | if (module.stage1_flags.have_dllmain_crt_startup or is_dyn_lib) |
| 963 | break :blk null; |
| 964 | if (module.stage1_flags.have_c_main or self.base.options.is_test or |
| 965 | module.stage1_flags.have_winmain_crt_startup or |
| 966 | module.stage1_flags.have_wwinmain_crt_startup) |
| 967 | { |
| 968 | break :blk .Console; |
| 969 | } |
| 970 | if (module.stage1_flags.have_winmain or module.stage1_flags.have_wwinmain) |
| 971 | break :blk .Windows; |
| 953 | 972 | } |
| 954 | | if (module.stage1_flags.have_winmain or module.stage1_flags.have_wwinmain) |
| 955 | | break :blk .Windows; |
| 956 | | } |
| 957 | | }, |
| 958 | | .uefi => break :blk .EfiApplication, |
| 959 | | else => {}, |
| 960 | | } |
| 961 | | break :blk null; |
| 962 | | }; |
| 963 | | const Mode = enum { uefi, win32 }; |
| 964 | | const mode: Mode = mode: { |
| 965 | | if (resolved_subsystem) |subsystem| switch (subsystem) { |
| 966 | | .Console => { |
| 967 | | try argv.append("-SUBSYSTEM:console"); |
| 968 | | break :mode .win32; |
| 969 | | }, |
| 970 | | .EfiApplication => { |
| 971 | | try argv.append("-SUBSYSTEM:efi_application"); |
| 972 | | break :mode .uefi; |
| 973 | | }, |
| 974 | | .EfiBootServiceDriver => { |
| 975 | | try argv.append("-SUBSYSTEM:efi_boot_service_driver"); |
| 976 | | break :mode .uefi; |
| 977 | | }, |
| 978 | | .EfiRom => { |
| 979 | | try argv.append("-SUBSYSTEM:efi_rom"); |
| 980 | | break :mode .uefi; |
| 981 | | }, |
| 982 | | .EfiRuntimeDriver => { |
| 983 | | try argv.append("-SUBSYSTEM:efi_runtime_driver"); |
| 973 | }, |
| 974 | .uefi => break :blk .EfiApplication, |
| 975 | else => {}, |
| 976 | } |
| 977 | break :blk null; |
| 978 | }; |
| 979 | const Mode = enum { uefi, win32 }; |
| 980 | const mode: Mode = mode: { |
| 981 | if (resolved_subsystem) |subsystem| switch (subsystem) { |
| 982 | .Console => { |
| 983 | try argv.append("-SUBSYSTEM:console"); |
| 984 | break :mode .win32; |
| 985 | }, |
| 986 | .EfiApplication => { |
| 987 | try argv.append("-SUBSYSTEM:efi_application"); |
| 988 | break :mode .uefi; |
| 989 | }, |
| 990 | .EfiBootServiceDriver => { |
| 991 | try argv.append("-SUBSYSTEM:efi_boot_service_driver"); |
| 992 | break :mode .uefi; |
| 993 | }, |
| 994 | .EfiRom => { |
| 995 | try argv.append("-SUBSYSTEM:efi_rom"); |
| 996 | break :mode .uefi; |
| 997 | }, |
| 998 | .EfiRuntimeDriver => { |
| 999 | try argv.append("-SUBSYSTEM:efi_runtime_driver"); |
| 1000 | break :mode .uefi; |
| 1001 | }, |
| 1002 | .Native => { |
| 1003 | try argv.append("-SUBSYSTEM:native"); |
| 1004 | break :mode .win32; |
| 1005 | }, |
| 1006 | .Posix => { |
| 1007 | try argv.append("-SUBSYSTEM:posix"); |
| 1008 | break :mode .win32; |
| 1009 | }, |
| 1010 | .Windows => { |
| 1011 | try argv.append("-SUBSYSTEM:windows"); |
| 1012 | break :mode .win32; |
| 1013 | }, |
| 1014 | } else if (target.os.tag == .uefi) { |
| 984 | 1015 | break :mode .uefi; |
| 985 | | }, |
| 986 | | .Native => { |
| 987 | | try argv.append("-SUBSYSTEM:native"); |
| 988 | | break :mode .win32; |
| 989 | | }, |
| 990 | | .Posix => { |
| 991 | | try argv.append("-SUBSYSTEM:posix"); |
| 992 | | break :mode .win32; |
| 993 | | }, |
| 994 | | .Windows => { |
| 995 | | try argv.append("-SUBSYSTEM:windows"); |
| 1016 | } else { |
| 996 | 1017 | break :mode .win32; |
| 997 | | }, |
| 998 | | } else if (target.os.tag == .uefi) { |
| 999 | | break :mode .uefi; |
| 1000 | | } else { |
| 1001 | | break :mode .win32; |
| 1002 | | } |
| 1003 | | }; |
| 1018 | } |
| 1019 | }; |
| 1004 | 1020 | |
| 1005 | | switch (mode) { |
| 1006 | | .uefi => try argv.appendSlice(&[_][]const u8{ |
| 1007 | | "-BASE:0", |
| 1008 | | "-ENTRY:EfiMain", |
| 1009 | | "-OPT:REF", |
| 1010 | | "-SAFESEH:NO", |
| 1011 | | "-MERGE:.rdata=.data", |
| 1012 | | "-ALIGN:32", |
| 1013 | | "-NODEFAULTLIB", |
| 1014 | | "-SECTION:.xdata,D", |
| 1015 | | }), |
| 1016 | | .win32 => { |
| 1017 | | if (link_in_crt) { |
| 1018 | | if (target.abi.isGnu()) { |
| 1019 | | try argv.append("-lldmingw"); |
| 1020 | | |
| 1021 | | if (target.cpu.arch == .i386) { |
| 1022 | | try argv.append("-ALTERNATENAME:__image_base__=___ImageBase"); |
| 1023 | | } else { |
| 1024 | | try argv.append("-ALTERNATENAME:__image_base__=__ImageBase"); |
| 1025 | | } |
| 1021 | switch (mode) { |
| 1022 | .uefi => try argv.appendSlice(&[_][]const u8{ |
| 1023 | "-BASE:0", |
| 1024 | "-ENTRY:EfiMain", |
| 1025 | "-OPT:REF", |
| 1026 | "-SAFESEH:NO", |
| 1027 | "-MERGE:.rdata=.data", |
| 1028 | "-ALIGN:32", |
| 1029 | "-NODEFAULTLIB", |
| 1030 | "-SECTION:.xdata,D", |
| 1031 | }), |
| 1032 | .win32 => { |
| 1033 | if (link_in_crt) { |
| 1034 | if (target.abi.isGnu()) { |
| 1035 | try argv.append("-lldmingw"); |
| 1036 | |
| 1037 | if (target.cpu.arch == .i386) { |
| 1038 | try argv.append("-ALTERNATENAME:__image_base__=___ImageBase"); |
| 1039 | } else { |
| 1040 | try argv.append("-ALTERNATENAME:__image_base__=__ImageBase"); |
| 1041 | } |
| 1026 | 1042 | |
| 1027 | | if (is_dyn_lib) { |
| 1028 | | try argv.append(try comp.get_libc_crt_file(arena, "dllcrt2.o")); |
| 1029 | | } else { |
| 1030 | | try argv.append(try comp.get_libc_crt_file(arena, "crt2.o")); |
| 1031 | | } |
| 1043 | if (is_dyn_lib) { |
| 1044 | try argv.append(try comp.get_libc_crt_file(arena, "dllcrt2.o")); |
| 1045 | } else { |
| 1046 | try argv.append(try comp.get_libc_crt_file(arena, "crt2.o")); |
| 1047 | } |
| 1032 | 1048 | |
| 1033 | | try argv.append(try comp.get_libc_crt_file(arena, "mingw32.lib")); |
| 1034 | | try argv.append(try comp.get_libc_crt_file(arena, "mingwex.lib")); |
| 1035 | | try argv.append(try comp.get_libc_crt_file(arena, "msvcrt-os.lib")); |
| 1049 | try argv.append(try comp.get_libc_crt_file(arena, "mingw32.lib")); |
| 1050 | try argv.append(try comp.get_libc_crt_file(arena, "mingwex.lib")); |
| 1051 | try argv.append(try comp.get_libc_crt_file(arena, "msvcrt-os.lib")); |
| 1036 | 1052 | |
| 1037 | | for (mingw.always_link_libs) |name| { |
| 1038 | | if (!self.base.options.system_libs.contains(name)) { |
| 1039 | | const lib_basename = try allocPrint(arena, "{s}.lib", .{name}); |
| 1040 | | try argv.append(try comp.get_libc_crt_file(arena, lib_basename)); |
| 1053 | for (mingw.always_link_libs) |name| { |
| 1054 | if (!self.base.options.system_libs.contains(name)) { |
| 1055 | const lib_basename = try allocPrint(arena, "{s}.lib", .{name}); |
| 1056 | try argv.append(try comp.get_libc_crt_file(arena, lib_basename)); |
| 1057 | } |
| 1058 | } |
| 1059 | } else { |
| 1060 | const lib_str = switch (self.base.options.link_mode) { |
| 1061 | .Dynamic => "", |
| 1062 | .Static => "lib", |
| 1063 | }; |
| 1064 | const d_str = switch (self.base.options.optimize_mode) { |
| 1065 | .Debug => "d", |
| 1066 | else => "", |
| 1067 | }; |
| 1068 | switch (self.base.options.link_mode) { |
| 1069 | .Static => try argv.append(try allocPrint(arena, "libcmt{s}.lib", .{d_str})), |
| 1070 | .Dynamic => try argv.append(try allocPrint(arena, "msvcrt{s}.lib", .{d_str})), |
| 1041 | 1071 | } |
| 1042 | | } |
| 1043 | | } else { |
| 1044 | | const lib_str = switch (self.base.options.link_mode) { |
| 1045 | | .Dynamic => "", |
| 1046 | | .Static => "lib", |
| 1047 | | }; |
| 1048 | | const d_str = switch (self.base.options.optimize_mode) { |
| 1049 | | .Debug => "d", |
| 1050 | | else => "", |
| 1051 | | }; |
| 1052 | | switch (self.base.options.link_mode) { |
| 1053 | | .Static => try argv.append(try allocPrint(arena, "libcmt{s}.lib", .{d_str})), |
| 1054 | | .Dynamic => try argv.append(try allocPrint(arena, "msvcrt{s}.lib", .{d_str})), |
| 1055 | | } |
| 1056 | 1072 | |
| 1057 | | try argv.append(try allocPrint(arena, "{s}vcruntime{s}.lib", .{ lib_str, d_str })); |
| 1058 | | try argv.append(try allocPrint(arena, "{s}ucrt{s}.lib", .{ lib_str, d_str })); |
| 1073 | try argv.append(try allocPrint(arena, "{s}vcruntime{s}.lib", .{ lib_str, d_str })); |
| 1074 | try argv.append(try allocPrint(arena, "{s}ucrt{s}.lib", .{ lib_str, d_str })); |
| 1059 | 1075 | |
| 1060 | | //Visual C++ 2015 Conformance Changes |
| 1061 | | //https://msdn.microsoft.com/en-us/library/bb531344.aspx |
| 1062 | | try argv.append("legacy_stdio_definitions.lib"); |
| 1076 | //Visual C++ 2015 Conformance Changes |
| 1077 | //https://msdn.microsoft.com/en-us/library/bb531344.aspx |
| 1078 | try argv.append("legacy_stdio_definitions.lib"); |
| 1063 | 1079 | |
| 1064 | | // msvcrt depends on kernel32 and ntdll |
| 1065 | | try argv.append("kernel32.lib"); |
| 1066 | | try argv.append("ntdll.lib"); |
| 1067 | | } |
| 1068 | | } else { |
| 1069 | | try argv.append("-NODEFAULTLIB"); |
| 1070 | | if (!is_lib) { |
| 1071 | | if (self.base.options.module) |module| { |
| 1072 | | if (module.stage1_flags.have_winmain) { |
| 1073 | | try argv.append("-ENTRY:WinMain"); |
| 1074 | | } else if (module.stage1_flags.have_wwinmain) { |
| 1075 | | try argv.append("-ENTRY:wWinMain"); |
| 1076 | | } else if (module.stage1_flags.have_wwinmain_crt_startup) { |
| 1077 | | try argv.append("-ENTRY:wWinMainCRTStartup"); |
| 1080 | // msvcrt depends on kernel32 and ntdll |
| 1081 | try argv.append("kernel32.lib"); |
| 1082 | try argv.append("ntdll.lib"); |
| 1083 | } |
| 1084 | } else { |
| 1085 | try argv.append("-NODEFAULTLIB"); |
| 1086 | if (!is_lib) { |
| 1087 | if (self.base.options.module) |module| { |
| 1088 | if (module.stage1_flags.have_winmain) { |
| 1089 | try argv.append("-ENTRY:WinMain"); |
| 1090 | } else if (module.stage1_flags.have_wwinmain) { |
| 1091 | try argv.append("-ENTRY:wWinMain"); |
| 1092 | } else if (module.stage1_flags.have_wwinmain_crt_startup) { |
| 1093 | try argv.append("-ENTRY:wWinMainCRTStartup"); |
| 1094 | } else { |
| 1095 | try argv.append("-ENTRY:WinMainCRTStartup"); |
| 1096 | } |
| 1078 | 1097 | } else { |
| 1079 | 1098 | try argv.append("-ENTRY:WinMainCRTStartup"); |
| 1080 | 1099 | } |
| 1081 | | } else { |
| 1082 | | try argv.append("-ENTRY:WinMainCRTStartup"); |
| 1083 | 1100 | } |
| 1084 | 1101 | } |
| 1085 | | } |
| 1086 | | }, |
| 1087 | | } |
| 1102 | }, |
| 1103 | } |
| 1088 | 1104 | |
| 1089 | | if (!is_obj) { |
| 1090 | 1105 | // libc++ dep |
| 1091 | 1106 | if (self.base.options.link_libcpp) { |
| 1092 | 1107 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 1093 | 1108 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 1094 | 1109 | try argv.append(comp.libunwind_static_lib.?.full_object_path); |
| 1095 | 1110 | } |
| 1096 | | } |
| 1097 | 1111 | |
| 1098 | | // compiler-rt and libc |
| 1099 | | if (is_exe_or_dyn_lib and !self.base.options.is_compiler_rt_or_libc) { |
| 1100 | | if (!self.base.options.link_libc) { |
| 1101 | | try argv.append(comp.libc_static_lib.?.full_object_path); |
| 1112 | // compiler-rt and libc |
| 1113 | if (is_exe_or_dyn_lib and !self.base.options.is_compiler_rt_or_libc) { |
| 1114 | if (!self.base.options.link_libc) { |
| 1115 | try argv.append(comp.libc_static_lib.?.full_object_path); |
| 1116 | } |
| 1117 | // MSVC compiler_rt is missing some stuff, so we build it unconditionally but |
| 1118 | // and rely on weak linkage to allow MSVC compiler_rt functions to override ours. |
| 1119 | try argv.append(comp.compiler_rt_static_lib.?.full_object_path); |
| 1102 | 1120 | } |
| 1103 | | // MSVC compiler_rt is missing some stuff, so we build it unconditionally but |
| 1104 | | // and rely on weak linkage to allow MSVC compiler_rt functions to override ours. |
| 1105 | | try argv.append(comp.compiler_rt_static_lib.?.full_object_path); |
| 1106 | | } |
| 1107 | 1121 | |
| 1108 | | for (self.base.options.system_libs.items()) |entry| { |
| 1109 | | const lib_basename = try allocPrint(arena, "{s}.lib", .{entry.key}); |
| 1110 | | if (comp.crt_files.get(lib_basename)) |crt_file| { |
| 1111 | | try argv.append(crt_file.full_object_path); |
| 1112 | | } else { |
| 1113 | | try argv.append(lib_basename); |
| 1122 | for (self.base.options.system_libs.items()) |entry| { |
| 1123 | const lib_basename = try allocPrint(arena, "{s}.lib", .{entry.key}); |
| 1124 | if (comp.crt_files.get(lib_basename)) |crt_file| { |
| 1125 | try argv.append(crt_file.full_object_path); |
| 1126 | } else { |
| 1127 | try argv.append(lib_basename); |
| 1128 | } |
| 1114 | 1129 | } |
| 1115 | | } |
| 1116 | 1130 | |
| 1117 | | if (self.base.options.verbose_link) { |
| 1118 | | Compilation.dump_argv(argv.items); |
| 1119 | | } |
| 1131 | if (self.base.options.verbose_link) { |
| 1132 | Compilation.dump_argv(argv.items); |
| 1133 | } |
| 1120 | 1134 | |
| 1121 | | const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null); |
| 1122 | | for (argv.items) |arg, i| { |
| 1123 | | new_argv[i] = try arena.dupeZ(u8, arg); |
| 1124 | | } |
| 1135 | const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null); |
| 1136 | for (argv.items) |arg, i| { |
| 1137 | new_argv[i] = try arena.dupeZ(u8, arg); |
| 1138 | } |
| 1125 | 1139 | |
| 1126 | | var stderr_context: LLDContext = .{ |
| 1127 | | .coff = self, |
| 1128 | | .data = std.ArrayList(u8).init(self.base.allocator), |
| 1129 | | }; |
| 1130 | | defer stderr_context.data.deinit(); |
| 1131 | | var stdout_context: LLDContext = .{ |
| 1132 | | .coff = self, |
| 1133 | | .data = std.ArrayList(u8).init(self.base.allocator), |
| 1134 | | }; |
| 1135 | | defer stdout_context.data.deinit(); |
| 1136 | | const llvm = @import("../llvm.zig"); |
| 1137 | | const ok = llvm.Link( |
| 1138 | | .COFF, |
| 1139 | | new_argv.ptr, |
| 1140 | | new_argv.len, |
| 1141 | | append_diagnostic, |
| 1142 | | @ptrToInt(&stdout_context), |
| 1143 | | @ptrToInt(&stderr_context), |
| 1144 | | ); |
| 1145 | | if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory; |
| 1146 | | if (stdout_context.data.items.len != 0) { |
| 1147 | | std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items}); |
| 1148 | | } |
| 1149 | | if (!ok) { |
| 1150 | | // TODO parse this output and surface with the Compilation API rather than |
| 1151 | | // directly outputting to stderr here. |
| 1152 | | std.debug.print("{}", .{stderr_context.data.items}); |
| 1153 | | return error.LLDReportedFailure; |
| 1154 | | } |
| 1155 | | if (stderr_context.data.items.len != 0) { |
| 1156 | | std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items}); |
| 1140 | var stderr_context: LLDContext = .{ |
| 1141 | .coff = self, |
| 1142 | .data = std.ArrayList(u8).init(self.base.allocator), |
| 1143 | }; |
| 1144 | defer stderr_context.data.deinit(); |
| 1145 | var stdout_context: LLDContext = .{ |
| 1146 | .coff = self, |
| 1147 | .data = std.ArrayList(u8).init(self.base.allocator), |
| 1148 | }; |
| 1149 | defer stdout_context.data.deinit(); |
| 1150 | const llvm = @import("../llvm.zig"); |
| 1151 | const ok = llvm.Link( |
| 1152 | .COFF, |
| 1153 | new_argv.ptr, |
| 1154 | new_argv.len, |
| 1155 | append_diagnostic, |
| 1156 | @ptrToInt(&stdout_context), |
| 1157 | @ptrToInt(&stderr_context), |
| 1158 | ); |
| 1159 | if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory; |
| 1160 | if (stdout_context.data.items.len != 0) { |
| 1161 | std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items}); |
| 1162 | } |
| 1163 | if (!ok) { |
| 1164 | // TODO parse this output and surface with the Compilation API rather than |
| 1165 | // directly outputting to stderr here. |
| 1166 | std.debug.print("{}", .{stderr_context.data.items}); |
| 1167 | return error.LLDReportedFailure; |
| 1168 | } |
| 1169 | if (stderr_context.data.items.len != 0) { |
| 1170 | std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items}); |
| 1171 | } |
| 1157 | 1172 | } |
| 1158 | 1173 | |
| 1159 | 1174 | if (!self.base.options.disable_lld_caching) { |