authorgravatar for emekankurumeh@outlook.comemekoi <emekankurumeh@outlook.com> 2019-03-29 20:37:15-05:00
committergravatar for emekankurumeh@outlook.comemekoi <emekankurumeh@outlook.com> 2019-04-04 19:51:55-05:00
log6cc443ee457d06ea23713bb78ab832d886029d57
tree42dc20b020369a025f70f224f23472f9702b1fcb
parentecd2332bb5c74739ade40f1b9eaf412b4642a36f

added code for linking libc on mingw


1 files changed, 144 insertions(+), 56 deletions(-)

src/link.cpp+144-56
...@@ -1132,40 +1132,114 @@ static void add_uefi_link_args(LinkJob *lj) {...@@ -1132,40 +1132,114 @@ static void add_uefi_link_args(LinkJob *lj) {
1132 lj->args.append("-SECTION:.xdata,D");1132 lj->args.append("-SECTION:.xdata,D");
1133}1133}
11341134
1135static void add_nt_link_args(LinkJob *lj, bool is_library) {1135static void add_msvc_link_args(LinkJob *lj, bool is_library) {
1136 CodeGen *g = lj->codegen;1136 CodeGen *g = lj->codegen;
11371137
1138 if (lj->link_in_crt) {1138 // TODO: https://github.com/ziglang/zig/issues/2064
1139 // TODO: https://github.com/ziglang/zig/issues/20641139 bool is_dynamic = true; // g->is_dynamic;
1140 bool is_dynamic = true; // g->is_dynamic;1140 const char *lib_str = is_dynamic ? "" : "lib";
1141 const char *lib_str = is_dynamic ? "" : "lib";1141 const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : "";
1142 const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : "";1142
11431143 if (!is_dynamic) {
1144 if (!is_dynamic) {1144 Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str);
1145 Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str);1145 lj->args.append(buf_ptr(cmt_lib_name));
1146 lj->args.append(buf_ptr(cmt_lib_name));1146 } else {
1147 Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str);
1148 lj->args.append(buf_ptr(msvcrt_lib_name));
1149 }
1150
1151 Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str);
1152 lj->args.append(buf_ptr(vcruntime_lib_name));
1153
1154 Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str);
1155 lj->args.append(buf_ptr(crt_lib_name));
1156
1157 //Visual C++ 2015 Conformance Changes
1158 //https://msdn.microsoft.com/en-us/library/bb531344.aspx
1159 lj->args.append("legacy_stdio_definitions.lib");
1160
1161 // msvcrt depends on kernel32 and ntdll
1162 lj->args.append("kernel32.lib");
1163 lj->args.append("ntdll.lib");
1164}
1165
1166static const char *get_libc_file(ZigLibCInstallation *lib, const char *file) {
1167 Buf *out_buf = buf_alloc();
1168 os_path_join(&lib->crt_dir, buf_create_from_str(file), out_buf);
1169 return buf_ptr(out_buf);
1170}
1171
1172static const char *get_libc_static_file(ZigLibCInstallation *lib, const char *file) {
1173 Buf *static_crt_dir = buf_alloc();
1174 Buf *out_buf = buf_alloc();
1175 if (zig_libc_cc_print_file_name(file, static_crt_dir, true, true) != ErrorNone) {
1176 abort();
1177 }
1178 os_path_join(static_crt_dir, buf_create_from_str(file), out_buf);
1179 return buf_ptr(out_buf);
1180}
1181
1182static void add_gnu_link_args(LinkJob *lj, bool is_library) {
1183 CodeGen *g = lj->codegen;
1184
1185 bool is_dll = g->out_type == OutTypeLib && g->is_dynamic;
1186
1187 if (g->zig_target->arch == ZigLLVM_x86) {
1188 lj->args.append("-ALTERNATENAME:__image_base__=___ImageBase");
1189 } else {
1190 lj->args.append("-ALTERNATENAME:__image_base__=__ImageBase");
1191 }
1192
1193 if (is_dll) {
1194 lj->args.append(get_libc_file(g->libc, "dllcrt2.o"));
1195 } else {
1196 lj->args.append(get_libc_file(g->libc, "crt2.o"));
1197 }
1198
1199 lj->args.append(get_libc_static_file(g->libc, "crtbegin.o"));
1200
1201 if (g->libc_link_lib != nullptr) {
1202 lj->args.append("libmingw32.a");
1203
1204 if (is_dll) {
1205 lj->args.append(get_libc_static_file(g->libc, "libgcc_s.a"));
1206 lj->args.append(get_libc_static_file(g->libc, "libgcc.a"));
1147 } else {1207 } else {
1148 Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str);1208 lj->args.append(get_libc_static_file(g->libc, "libgcc.a"));
1149 lj->args.append(buf_ptr(msvcrt_lib_name));1209 lj->args.append(get_libc_static_file(g->libc, "libgcc_eh.a"));
1150 }1210 }
11511211
1152 Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str);1212 lj->args.append(get_libc_static_file(g->libc, "libssp.a"));
1153 lj->args.append(buf_ptr(vcruntime_lib_name));1213 lj->args.append("libmoldname.a");
1214 lj->args.append("libmingwex.a");
1215 lj->args.append("libmsvcrt.a");
11541216
1155 Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str);1217 if (g->subsystem == TargetSubsystemWindows) {
1156 lj->args.append(buf_ptr(crt_lib_name));1218 lj->args.append("libgdi32.a");
1219 lj->args.append("libcomdlg32.a");
1220 }
11571221
1158 //Visual C++ 2015 Conformance Changes1222 lj->args.append("libadvapi32.a");
1159 //https://msdn.microsoft.com/en-us/library/bb531344.aspx1223 lj->args.append("libadvapi32.a");
1160 lj->args.append("legacy_stdio_definitions.lib");1224 lj->args.append("libshell32.a");
1225 lj->args.append("libuser32.a");
1226 lj->args.append("libkernel32.a");
11611227
1162 // msvcrt depends on kernel32 and ntdll1228 lj->args.append(get_libc_static_file(g->libc, "crtend.o"));
1163 lj->args.append("kernel32.lib");1229 }
1164 lj->args.append("ntdll.lib");1230}
1231
1232static void add_win_link_args(LinkJob *lj, bool is_library) {
1233 if (lj->link_in_crt) {
1234 if (target_abi_is_gnu(lj->codegen->zig_target->abi)) {
1235 add_gnu_link_args(lj, is_library);
1236 } else {
1237 add_msvc_link_args(lj, is_library);
1238 }
1165 } else {1239 } else {
1166 lj->args.append("-NODEFAULTLIB");1240 lj->args.append("-NODEFAULTLIB");
1167 if (!is_library) {1241 if (!is_library) {
1168 if (g->have_winmain) {1242 if (lj->codegen->have_winmain) {
1169 lj->args.append("-ENTRY:WinMain");1243 lj->args.append("-ENTRY:WinMain");
1170 } else {1244 } else {
1171 lj->args.append("-ENTRY:WinMainCRTStartup");1245 lj->args.append("-ENTRY:WinMainCRTStartup");
...@@ -1194,17 +1268,46 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -1194,17 +1268,46 @@ static void construct_linker_job_coff(LinkJob *lj) {
1194 coff_append_machine_arg(g, &lj->args);1268 coff_append_machine_arg(g, &lj->args);
11951269
1196 bool is_library = g->out_type == OutTypeLib;1270 bool is_library = g->out_type == OutTypeLib;
1271 if (is_library && g->is_dynamic) {
1272 lj->args.append("-DLL");
1273 }
1274
1275 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
1276
1277 if (g->libc_link_lib != nullptr) {
1278 assert(g->libc != nullptr);
1279
1280 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir))));
1281
1282 if (target_abi_is_gnu(g->zig_target->abi)) {
1283 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->sys_include_dir))));
1284 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->include_dir))));
1285 } else {
1286 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));
1287 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));
1288 }
1289 }
1290
1291 for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
1292 const char *lib_dir = g->lib_dirs.at(i);
1293 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));
1294 }
1295
1296 for (size_t i = 0; i < g->link_objects.length; i += 1) {
1297 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
1298 }
1299
1197 switch (g->subsystem) {1300 switch (g->subsystem) {
1198 case TargetSubsystemAuto:1301 case TargetSubsystemAuto:
1199 if (g->zig_target->os == OsUefi) {1302 if (g->zig_target->os == OsUefi) {
1200 add_uefi_link_args(lj);1303 add_uefi_link_args(lj);
1201 } else {1304 } else {
1202 add_nt_link_args(lj, is_library);1305 add_win_link_args(lj, is_library);
1203 }1306 }
1204 break;1307 break;
1205 case TargetSubsystemConsole:1308 case TargetSubsystemConsole:
1206 lj->args.append("-SUBSYSTEM:console");1309 lj->args.append("-SUBSYSTEM:console");
1207 add_nt_link_args(lj, is_library);1310 add_win_link_args(lj, is_library);
1208 break;1311 break;
1209 case TargetSubsystemEfiApplication:1312 case TargetSubsystemEfiApplication:
1210 lj->args.append("-SUBSYSTEM:efi_application");1313 lj->args.append("-SUBSYSTEM:efi_application");
...@@ -1224,41 +1327,18 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -1224,41 +1327,18 @@ static void construct_linker_job_coff(LinkJob *lj) {
1224 break;1327 break;
1225 case TargetSubsystemNative:1328 case TargetSubsystemNative:
1226 lj->args.append("-SUBSYSTEM:native");1329 lj->args.append("-SUBSYSTEM:native");
1227 add_nt_link_args(lj, is_library);1330 add_win_link_args(lj, is_library);
1228 break;1331 break;
1229 case TargetSubsystemPosix:1332 case TargetSubsystemPosix:
1230 lj->args.append("-SUBSYSTEM:posix");1333 lj->args.append("-SUBSYSTEM:posix");
1231 add_nt_link_args(lj, is_library);1334 add_win_link_args(lj, is_library);
1232 break;1335 break;
1233 case TargetSubsystemWindows:1336 case TargetSubsystemWindows:
1234 lj->args.append("-SUBSYSTEM:windows");1337 lj->args.append("-SUBSYSTEM:windows");
1235 add_nt_link_args(lj, is_library);1338 add_win_link_args(lj, is_library);
1236 break;1339 break;
1237 }1340 }
12381341
1239 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
1240
1241 if (g->libc_link_lib != nullptr) {
1242 assert(g->libc != nullptr);
1243
1244 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));
1245 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));
1246 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir))));
1247 }
1248
1249 if (is_library && g->is_dynamic) {
1250 lj->args.append("-DLL");
1251 }
1252
1253 for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
1254 const char *lib_dir = g->lib_dirs.at(i);
1255 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));
1256 }
1257
1258 for (size_t i = 0; i < g->link_objects.length; i += 1) {
1259 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
1260 }
1261
1262 if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {1342 if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {
1263 if (g->libc_link_lib == nullptr && !g->is_dummy_so) {1343 if (g->libc_link_lib == nullptr && !g->is_dummy_so) {
1264 Buf *builtin_a_path = build_a(g, "builtin");1344 Buf *builtin_a_path = build_a(g, "builtin");
...@@ -1278,11 +1358,19 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -1278,11 +1358,19 @@ static void construct_linker_job_coff(LinkJob *lj) {
1278 continue;1358 continue;
1279 }1359 }
1280 if (link_lib->provided_explicitly) {1360 if (link_lib->provided_explicitly) {
1281 if (lj->codegen->zig_target->abi == ZigLLVM_GNU) {1361 if (target_abi_is_gnu(lj->codegen->zig_target->abi)) {
1282 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));1362 static const char *test_names[3] = { "lib%s.dll.a", "lib%s.a", nullptr };
1283 lj->args.append(buf_ptr(arg));1363
1284 }1364 for (size_t i = 0; test_names[i] != nullptr; i++) {
1285 else {1365 Buf *test_path = buf_sprintf(test_names[i], buf_ptr(link_lib->name));
1366 bool exists = false;
1367 if (os_file_exists(test_path, &exists) != ErrorNone) {
1368 zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path));
1369 } else if (exists) {
1370 lj->args.append(buf_ptr(test_path));
1371 }
1372 }
1373 } else {
1286 lj->args.append(buf_ptr(link_lib->name));1374 lj->args.append(buf_ptr(link_lib->name));
1287 }1375 }
1288 } else {1376 } else {