| ... | @@ -1137,53 +1137,121 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si | ... | @@ -1137,53 +1137,121 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si |
| 1137 | } | 1137 | } |
| 1138 | | 1138 | |
| 1139 | static void add_uefi_link_args(LinkJob *lj) { | 1139 | static void add_uefi_link_args(LinkJob *lj) { |
| 1140 | lj->args.append("/BASE:0"); | 1140 | lj->args.append("-BASE:0"); |
| 1141 | lj->args.append("/ENTRY:EfiMain"); | 1141 | lj->args.append("-ENTRY:EfiMain"); |
| 1142 | lj->args.append("/OPT:REF"); | 1142 | lj->args.append("-OPT:REF"); |
| 1143 | lj->args.append("/SAFESEH:NO"); | 1143 | lj->args.append("-SAFESEH:NO"); |
| 1144 | lj->args.append("/MERGE:.rdata=.data"); | 1144 | lj->args.append("-MERGE:.rdata=.data"); |
| 1145 | lj->args.append("/ALIGN:32"); | 1145 | lj->args.append("-ALIGN:32"); |
| 1146 | lj->args.append("/NODEFAULTLIB"); | 1146 | lj->args.append("-NODEFAULTLIB"); |
| 1147 | lj->args.append("/SECTION:.xdata,D"); | 1147 | lj->args.append("-SECTION:.xdata,D"); |
| 1148 | } | 1148 | } |
| 1149 | | 1149 | |
| 1150 | static void add_nt_link_args(LinkJob *lj, bool is_library) { | 1150 | static void add_msvc_link_args(LinkJob *lj, bool is_library) { |
| 1151 | CodeGen *g = lj->codegen; | 1151 | CodeGen *g = lj->codegen; |
| 1152 | | 1152 | |
| 1153 | if (lj->link_in_crt) { | 1153 | // TODO: https://github.com/ziglang/zig/issues/2064 |
| 1154 | // TODO: https://github.com/ziglang/zig/issues/2064 | 1154 | bool is_dynamic = true; // g->is_dynamic; |
| 1155 | bool is_dynamic = true; // g->is_dynamic; | 1155 | const char *lib_str = is_dynamic ? "" : "lib"; |
| 1156 | const char *lib_str = is_dynamic ? "" : "lib"; | 1156 | const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; |
| 1157 | const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; | 1157 | |
| 1158 | | 1158 | if (!is_dynamic) { |
| 1159 | if (!is_dynamic) { | 1159 | Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str); |
| 1160 | Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str); | 1160 | lj->args.append(buf_ptr(cmt_lib_name)); |
| 1161 | lj->args.append(buf_ptr(cmt_lib_name)); | 1161 | } else { |
| 1162 | } else { | 1162 | Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str); |
| 1163 | Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str); | 1163 | lj->args.append(buf_ptr(msvcrt_lib_name)); |
| 1164 | lj->args.append(buf_ptr(msvcrt_lib_name)); | 1164 | } |
| 1165 | } | 1165 | |
| | 1166 | Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str); |
| | 1167 | lj->args.append(buf_ptr(vcruntime_lib_name)); |
| | 1168 | |
| | 1169 | Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str); |
| | 1170 | lj->args.append(buf_ptr(crt_lib_name)); |
| | 1171 | |
| | 1172 | //Visual C++ 2015 Conformance Changes |
| | 1173 | //https://msdn.microsoft.com/en-us/library/bb531344.aspx |
| | 1174 | lj->args.append("legacy_stdio_definitions.lib"); |
| | 1175 | |
| | 1176 | // msvcrt depends on kernel32 and ntdll |
| | 1177 | lj->args.append("kernel32.lib"); |
| | 1178 | lj->args.append("ntdll.lib"); |
| | 1179 | } |
| 1166 | | 1180 | |
| 1167 | Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str); | 1181 | static const char *get_libc_file(ZigLibCInstallation *lib, const char *file) { |
| 1168 | lj->args.append(buf_ptr(vcruntime_lib_name)); | 1182 | Buf *out_buf = buf_alloc(); |
| | 1183 | os_path_join(&lib->crt_dir, buf_create_from_str(file), out_buf); |
| | 1184 | return buf_ptr(out_buf); |
| | 1185 | } |
| | 1186 | |
| | 1187 | static const char *get_libc_static_file(ZigLibCInstallation *lib, const char *file) { |
| | 1188 | Buf *out_buf = buf_alloc(); |
| | 1189 | os_path_join(&lib->static_crt_dir, buf_create_from_str(file), out_buf); |
| | 1190 | return buf_ptr(out_buf); |
| | 1191 | } |
| 1169 | | 1192 | |
| 1170 | Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str); | 1193 | static void add_mingw_link_args(LinkJob *lj, bool is_library) { |
| 1171 | lj->args.append(buf_ptr(crt_lib_name)); | 1194 | CodeGen *g = lj->codegen; |
| 1172 | | 1195 | |
| 1173 | //Visual C++ 2015 Conformance Changes | 1196 | bool is_dll = g->out_type == OutTypeLib && g->is_dynamic; |
| 1174 | //https://msdn.microsoft.com/en-us/library/bb531344.aspx | | |
| 1175 | lj->args.append("legacy_stdio_definitions.lib"); | | |
| 1176 | | 1197 | |
| 1177 | // msvcrt depends on kernel32 and ntdll | 1198 | if (g->zig_target->arch == ZigLLVM_x86) { |
| 1178 | lj->args.append("kernel32.lib"); | 1199 | lj->args.append("-ALTERNATENAME:__image_base__=___ImageBase"); |
| 1179 | lj->args.append("ntdll.lib"); | | |
| 1180 | } else { | 1200 | } else { |
| 1181 | lj->args.append("/NODEFAULTLIB"); | 1201 | lj->args.append("-ALTERNATENAME:__image_base__=__ImageBase"); |
| | 1202 | } |
| | 1203 | |
| | 1204 | if (is_dll) { |
| | 1205 | lj->args.append(get_libc_file(g->libc, "dllcrt2.o")); |
| | 1206 | } else { |
| | 1207 | lj->args.append(get_libc_file(g->libc, "crt2.o")); |
| | 1208 | } |
| | 1209 | |
| | 1210 | lj->args.append(get_libc_static_file(g->libc, "crtbegin.o")); |
| | 1211 | |
| | 1212 | lj->args.append(get_libc_file(g->libc, "libmingw32.a")); |
| | 1213 | |
| | 1214 | if (is_dll) { |
| | 1215 | lj->args.append(get_libc_static_file(g->libc, "libgcc_s.a")); |
| | 1216 | lj->args.append(get_libc_static_file(g->libc, "libgcc.a")); |
| | 1217 | } else { |
| | 1218 | lj->args.append(get_libc_static_file(g->libc, "libgcc.a")); |
| | 1219 | lj->args.append(get_libc_static_file(g->libc, "libgcc_eh.a")); |
| | 1220 | } |
| | 1221 | |
| | 1222 | lj->args.append(get_libc_static_file(g->libc, "libssp.a")); |
| | 1223 | lj->args.append(get_libc_file(g->libc, "libmoldname.a")); |
| | 1224 | lj->args.append(get_libc_file(g->libc, "libmingwex.a")); |
| | 1225 | lj->args.append(get_libc_file(g->libc, "libmsvcrt.a")); |
| | 1226 | |
| | 1227 | if (g->subsystem == TargetSubsystemWindows) { |
| | 1228 | lj->args.append(get_libc_file(g->libc, "libgdi32.a")); |
| | 1229 | lj->args.append(get_libc_file(g->libc, "libcomdlg32.a")); |
| | 1230 | } |
| | 1231 | |
| | 1232 | lj->args.append(get_libc_file(g->libc, "libadvapi32.a")); |
| | 1233 | lj->args.append(get_libc_file(g->libc, "libadvapi32.a")); |
| | 1234 | lj->args.append(get_libc_file(g->libc, "libshell32.a")); |
| | 1235 | lj->args.append(get_libc_file(g->libc, "libuser32.a")); |
| | 1236 | lj->args.append(get_libc_file(g->libc, "libkernel32.a")); |
| | 1237 | |
| | 1238 | lj->args.append(get_libc_static_file(g->libc, "crtend.o")); |
| | 1239 | } |
| | 1240 | |
| | 1241 | static void add_win_link_args(LinkJob *lj, bool is_library) { |
| | 1242 | if (lj->link_in_crt) { |
| | 1243 | if (target_abi_is_gnu(lj->codegen->zig_target->abi)) { |
| | 1244 | add_mingw_link_args(lj, is_library); |
| | 1245 | } else { |
| | 1246 | add_msvc_link_args(lj, is_library); |
| | 1247 | } |
| | 1248 | } else { |
| | 1249 | lj->args.append("-NODEFAULTLIB"); |
| 1182 | if (!is_library) { | 1250 | if (!is_library) { |
| 1183 | if (g->have_winmain) { | 1251 | if (lj->codegen->have_winmain) { |
| 1184 | lj->args.append("/ENTRY:WinMain"); | 1252 | lj->args.append("-ENTRY:WinMain"); |
| 1185 | } else { | 1253 | } else { |
| 1186 | lj->args.append("/ENTRY:WinMainCRTStartup"); | 1254 | lj->args.append("-ENTRY:WinMainCRTStartup"); |
| 1187 | } | 1255 | } |
| 1188 | } | 1256 | } |
| 1189 | } | 1257 | } |
| ... | @@ -1193,87 +1261,93 @@ static void construct_linker_job_coff(LinkJob *lj) { | ... | @@ -1193,87 +1261,93 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 1193 | Error err; | 1261 | Error err; |
| 1194 | CodeGen *g = lj->codegen; | 1262 | CodeGen *g = lj->codegen; |
| 1195 | | 1263 | |
| 1196 | lj->args.append("/ERRORLIMIT:0"); | 1264 | lj->args.append("-ERRORLIMIT:0"); |
| 1197 | | 1265 | |
| 1198 | lj->args.append("/NOLOGO"); | 1266 | lj->args.append("-NOLOGO"); |
| 1199 | | 1267 | |
| 1200 | if (!g->strip_debug_symbols) { | 1268 | if (!g->strip_debug_symbols) { |
| 1201 | lj->args.append("/DEBUG"); | 1269 | lj->args.append("-DEBUG"); |
| 1202 | } | 1270 | } |
| 1203 | | 1271 | |
| 1204 | if (g->out_type == OutTypeExe) { | 1272 | if (g->out_type == OutTypeExe) { |
| 1205 | // TODO compile time stack upper bound detection | 1273 | // TODO compile time stack upper bound detection |
| 1206 | lj->args.append("/STACK:16777216"); | 1274 | lj->args.append("-STACK:16777216"); |
| 1207 | } | 1275 | } |
| 1208 | | 1276 | |
| 1209 | coff_append_machine_arg(g, &lj->args); | 1277 | coff_append_machine_arg(g, &lj->args); |
| 1210 | | 1278 | |
| 1211 | bool is_library = g->out_type == OutTypeLib; | 1279 | bool is_library = g->out_type == OutTypeLib; |
| | 1280 | if (is_library && g->is_dynamic) { |
| | 1281 | lj->args.append("-DLL"); |
| | 1282 | } |
| | 1283 | |
| | 1284 | lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); |
| | 1285 | |
| | 1286 | if (g->libc_link_lib != nullptr) { |
| | 1287 | assert(g->libc != nullptr); |
| | 1288 | |
| | 1289 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir)))); |
| | 1290 | |
| | 1291 | if (target_abi_is_gnu(g->zig_target->abi)) { |
| | 1292 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->sys_include_dir)))); |
| | 1293 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->include_dir)))); |
| | 1294 | } else { |
| | 1295 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir)))); |
| | 1296 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir)))); |
| | 1297 | } |
| | 1298 | } |
| | 1299 | |
| | 1300 | for (size_t i = 0; i < g->lib_dirs.length; i += 1) { |
| | 1301 | const char *lib_dir = g->lib_dirs.at(i); |
| | 1302 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir))); |
| | 1303 | } |
| | 1304 | |
| | 1305 | for (size_t i = 0; i < g->link_objects.length; i += 1) { |
| | 1306 | lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); |
| | 1307 | } |
| | 1308 | |
| 1212 | switch (g->subsystem) { | 1309 | switch (g->subsystem) { |
| 1213 | case TargetSubsystemAuto: | 1310 | case TargetSubsystemAuto: |
| 1214 | if (g->zig_target->os == OsUefi) { | 1311 | if (g->zig_target->os == OsUefi) { |
| 1215 | add_uefi_link_args(lj); | 1312 | add_uefi_link_args(lj); |
| 1216 | } else { | 1313 | } else { |
| 1217 | add_nt_link_args(lj, is_library); | 1314 | add_win_link_args(lj, is_library); |
| 1218 | } | 1315 | } |
| 1219 | break; | 1316 | break; |
| 1220 | case TargetSubsystemConsole: | 1317 | case TargetSubsystemConsole: |
| 1221 | lj->args.append("/SUBSYSTEM:console"); | 1318 | lj->args.append("-SUBSYSTEM:console"); |
| 1222 | add_nt_link_args(lj, is_library); | 1319 | add_win_link_args(lj, is_library); |
| 1223 | break; | 1320 | break; |
| 1224 | case TargetSubsystemEfiApplication: | 1321 | case TargetSubsystemEfiApplication: |
| 1225 | lj->args.append("/SUBSYSTEM:efi_application"); | 1322 | lj->args.append("-SUBSYSTEM:efi_application"); |
| 1226 | add_uefi_link_args(lj); | 1323 | add_uefi_link_args(lj); |
| 1227 | break; | 1324 | break; |
| 1228 | case TargetSubsystemEfiBootServiceDriver: | 1325 | case TargetSubsystemEfiBootServiceDriver: |
| 1229 | lj->args.append("/SUBSYSTEM:efi_boot_service_driver"); | 1326 | lj->args.append("-SUBSYSTEM:efi_boot_service_driver"); |
| 1230 | add_uefi_link_args(lj); | 1327 | add_uefi_link_args(lj); |
| 1231 | break; | 1328 | break; |
| 1232 | case TargetSubsystemEfiRom: | 1329 | case TargetSubsystemEfiRom: |
| 1233 | lj->args.append("/SUBSYSTEM:efi_rom"); | 1330 | lj->args.append("-SUBSYSTEM:efi_rom"); |
| 1234 | add_uefi_link_args(lj); | 1331 | add_uefi_link_args(lj); |
| 1235 | break; | 1332 | break; |
| 1236 | case TargetSubsystemEfiRuntimeDriver: | 1333 | case TargetSubsystemEfiRuntimeDriver: |
| 1237 | lj->args.append("/SUBSYSTEM:efi_runtime_driver"); | 1334 | lj->args.append("-SUBSYSTEM:efi_runtime_driver"); |
| 1238 | add_uefi_link_args(lj); | 1335 | add_uefi_link_args(lj); |
| 1239 | break; | 1336 | break; |
| 1240 | case TargetSubsystemNative: | 1337 | case TargetSubsystemNative: |
| 1241 | lj->args.append("/SUBSYSTEM:native"); | 1338 | lj->args.append("-SUBSYSTEM:native"); |
| 1242 | add_nt_link_args(lj, is_library); | 1339 | add_win_link_args(lj, is_library); |
| 1243 | break; | 1340 | break; |
| 1244 | case TargetSubsystemPosix: | 1341 | case TargetSubsystemPosix: |
| 1245 | lj->args.append("/SUBSYSTEM:posix"); | 1342 | lj->args.append("-SUBSYSTEM:posix"); |
| 1246 | add_nt_link_args(lj, is_library); | 1343 | add_win_link_args(lj, is_library); |
| 1247 | break; | 1344 | break; |
| 1248 | case TargetSubsystemWindows: | 1345 | case TargetSubsystemWindows: |
| 1249 | lj->args.append("/SUBSYSTEM:windows"); | 1346 | lj->args.append("-SUBSYSTEM:windows"); |
| 1250 | add_nt_link_args(lj, is_library); | 1347 | add_win_link_args(lj, is_library); |
| 1251 | break; | 1348 | break; |
| 1252 | } | 1349 | } |
| 1253 | | 1350 | |
| 1254 | lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); | | |
| 1255 | | | |
| 1256 | if (g->libc_link_lib != nullptr) { | | |
| 1257 | assert(g->libc != nullptr); | | |
| 1258 | | | |
| 1259 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir)))); | | |
| 1260 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir)))); | | |
| 1261 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir)))); | | |
| 1262 | } | | |
| 1263 | | | |
| 1264 | if (is_library && g->is_dynamic) { | | |
| 1265 | lj->args.append("-DLL"); | | |
| 1266 | } | | |
| 1267 | | | |
| 1268 | for (size_t i = 0; i < g->lib_dirs.length; i += 1) { | | |
| 1269 | const char *lib_dir = g->lib_dirs.at(i); | | |
| 1270 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir))); | | |
| 1271 | } | | |
| 1272 | | | |
| 1273 | for (size_t i = 0; i < g->link_objects.length; i += 1) { | | |
| 1274 | lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); | | |
| 1275 | } | | |
| 1276 | | | |
| 1277 | if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) { | 1351 | if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) { |
| 1278 | if (g->libc_link_lib == nullptr && !g->is_dummy_so) { | 1352 | if (g->libc_link_lib == nullptr && !g->is_dummy_so) { |
| 1279 | Buf *builtin_a_path = build_a(g, "builtin"); | 1353 | Buf *builtin_a_path = build_a(g, "builtin"); |
| ... | @@ -1293,11 +1367,10 @@ static void construct_linker_job_coff(LinkJob *lj) { | ... | @@ -1293,11 +1367,10 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 1293 | continue; | 1367 | continue; |
| 1294 | } | 1368 | } |
| 1295 | if (link_lib->provided_explicitly) { | 1369 | if (link_lib->provided_explicitly) { |
| 1296 | if (lj->codegen->zig_target->abi == ZigLLVM_GNU) { | 1370 | if (target_abi_is_gnu(lj->codegen->zig_target->abi)) { |
| 1297 | Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name)); | 1371 | Buf *lib_name = buf_sprintf("lib%s.a", buf_ptr(link_lib->name)); |
| 1298 | lj->args.append(buf_ptr(arg)); | 1372 | lj->args.append(buf_ptr(lib_name)); |
| 1299 | } | 1373 | } else { |
| 1300 | else { | | |
| 1301 | lj->args.append(buf_ptr(link_lib->name)); | 1374 | lj->args.append(buf_ptr(link_lib->name)); |
| 1302 | } | 1375 | } |
| 1303 | } else { | 1376 | } else { |