| ... | ... | @@ -2098,6 +2098,60 @@ static bool is_linking_system_lib(CodeGen *g, const char *name) { |
| 2098 | 2098 | return false; |
| 2099 | 2099 | } |
| 2100 | 2100 | |
| 2101 | static Error find_mingw_lib_def(LinkJob *lj, const char *name, Buf *out_path) { |
| 2102 | CodeGen *g = lj->codegen; |
| 2103 | Buf override_path = BUF_INIT; |
| 2104 | Error err; |
| 2105 | |
| 2106 | char const *lib_path = nullptr; |
| 2107 | if (g->zig_target->arch == ZigLLVM_x86) { |
| 2108 | lib_path = "lib32"; |
| 2109 | } else if (g->zig_target->arch == ZigLLVM_x86_64) { |
| 2110 | lib_path = "lib64"; |
| 2111 | } else if (target_is_arm(g->zig_target)) { |
| 2112 | const bool is_32 = target_arch_pointer_bit_width(g->zig_target->arch) == 32; |
| 2113 | lib_path = is_32 ? "libarm32" : "libarm64"; |
| 2114 | } else { |
| 2115 | zig_unreachable(); |
| 2116 | } |
| 2117 | |
| 2118 | // Try the archtecture-specific path first |
| 2119 | buf_resize(&override_path, 0); |
| 2120 | buf_appendf(&override_path, "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s" OS_SEP "%s.def", buf_ptr(g->zig_lib_dir), lib_path, name); |
| 2121 | |
| 2122 | bool does_exist; |
| 2123 | if ((err = os_file_exists(&override_path, &does_exist)) != ErrorNone) { |
| 2124 | return err; |
| 2125 | } |
| 2126 | |
| 2127 | if (!does_exist) { |
| 2128 | // Try the generic version |
| 2129 | buf_resize(&override_path, 0); |
| 2130 | buf_appendf(&override_path, "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "lib-common" OS_SEP "%s.def", buf_ptr(g->zig_lib_dir), name); |
| 2131 | |
| 2132 | if ((err = os_file_exists(&override_path, &does_exist)) != ErrorNone) { |
| 2133 | return err; |
| 2134 | } |
| 2135 | } |
| 2136 | |
| 2137 | if (!does_exist) { |
| 2138 | // Try the generic version and preprocess it |
| 2139 | buf_resize(&override_path, 0); |
| 2140 | buf_appendf(&override_path, "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "lib-common" OS_SEP "%s.def.in", buf_ptr(g->zig_lib_dir), name); |
| 2141 | |
| 2142 | if ((err = os_file_exists(&override_path, &does_exist)) != ErrorNone) { |
| 2143 | return err; |
| 2144 | } |
| 2145 | } |
| 2146 | |
| 2147 | if (!does_exist) { |
| 2148 | return ErrorFileNotFound; |
| 2149 | } |
| 2150 | |
| 2151 | buf_init_from_buf(out_path, &override_path); |
| 2152 | return ErrorNone; |
| 2153 | } |
| 2154 | |
| 2101 | 2155 | static void add_mingw_link_args(LinkJob *lj, bool is_library) { |
| 2102 | 2156 | CodeGen *g = lj->codegen; |
| 2103 | 2157 | |
| ... | ... | @@ -2125,55 +2179,18 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) { |
| 2125 | 2179 | const char *name = mingw_def_list[def_i].name; |
| 2126 | 2180 | const bool always_link = mingw_def_list[def_i].always_link; |
| 2127 | 2181 | |
| 2128 | | Buf override_path = BUF_INIT; |
| 2182 | Buf lib_path = BUF_INIT; |
| 2183 | Error err = find_mingw_lib_def(lj, name, &lib_path); |
| 2129 | 2184 | |
| 2130 | | char const *lib_path = nullptr; |
| 2131 | | if (g->zig_target->arch == ZigLLVM_x86) { |
| 2132 | | lib_path = "lib32"; |
| 2133 | | } else if (g->zig_target->arch == ZigLLVM_x86_64) { |
| 2134 | | lib_path = "lib64"; |
| 2135 | | } else if (target_is_arm(g->zig_target)) { |
| 2136 | | const bool is_32 = target_arch_pointer_bit_width(g->zig_target->arch) == 32; |
| 2137 | | lib_path = is_32 ? "libarm32" : "libarm64"; |
| 2138 | | } else { |
| 2139 | | zig_unreachable(); |
| 2140 | | } |
| 2141 | | |
| 2142 | | // Try the archtecture-specific path first |
| 2143 | | buf_resize(&override_path, 0); |
| 2144 | | buf_appendf(&override_path, "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s" OS_SEP "%s.def", buf_ptr(g->zig_lib_dir), lib_path, name); |
| 2145 | | |
| 2146 | | bool does_exist; |
| 2147 | | if (os_file_exists(&override_path, &does_exist) != ErrorNone) { |
| 2148 | | zig_panic("link: unable to check if file exists: %s", buf_ptr(&override_path)); |
| 2149 | | } |
| 2150 | | |
| 2151 | | if (!does_exist) { |
| 2152 | | // Try the generic version |
| 2153 | | buf_resize(&override_path, 0); |
| 2154 | | buf_appendf(&override_path, "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "lib-common" OS_SEP "%s.def", buf_ptr(g->zig_lib_dir), name); |
| 2155 | | |
| 2156 | | if (os_file_exists(&override_path, &does_exist) != ErrorNone) { |
| 2157 | | zig_panic("link: unable to check if file exists: %s", buf_ptr(&override_path)); |
| 2158 | | } |
| 2159 | | } |
| 2160 | | |
| 2161 | | if (!does_exist) { |
| 2162 | | // Try the generic version and preprocess it |
| 2163 | | buf_resize(&override_path, 0); |
| 2164 | | buf_appendf(&override_path, "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "lib-common" OS_SEP "%s.def.in", buf_ptr(g->zig_lib_dir), name); |
| 2165 | | |
| 2166 | | if (os_file_exists(&override_path, &does_exist) != ErrorNone) { |
| 2167 | | zig_panic("link: unable to check if file exists: %s", buf_ptr(&override_path)); |
| 2168 | | } |
| 2169 | | } |
| 2170 | | |
| 2171 | | if (!does_exist) { |
| 2185 | if (err == ErrorFileNotFound) { |
| 2172 | 2186 | zig_panic("link: could not find .def file to build %s\n", name); |
| 2187 | } else if (err != ErrorNone) { |
| 2188 | zig_panic("link: unable to check if .def file for %s exists: %s", |
| 2189 | name, err_str(err)); |
| 2173 | 2190 | } |
| 2174 | 2191 | |
| 2175 | 2192 | if (always_link || is_linking_system_lib(g, name)) { |
| 2176 | | lj->args.append(get_def_lib(g, name, &override_path)); |
| 2193 | lj->args.append(get_def_lib(g, name, &lib_path)); |
| 2177 | 2194 | } |
| 2178 | 2195 | } |
| 2179 | 2196 | } |
| ... | ... | @@ -2307,8 +2324,6 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 2307 | 2324 | lj->args.append(buf_ptr(compiler_rt_o_path)); |
| 2308 | 2325 | } |
| 2309 | 2326 | |
| 2310 | | Buf *def_contents = buf_alloc(); |
| 2311 | | ZigList<const char *> gen_lib_args = {0}; |
| 2312 | 2327 | for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { |
| 2313 | 2328 | LinkLib *link_lib = g->link_libs_list.at(lib_i); |
| 2314 | 2329 | if (buf_eql_str(link_lib->name, "c")) { |
| ... | ... | @@ -2331,36 +2346,27 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 2331 | 2346 | continue; |
| 2332 | 2347 | } |
| 2333 | 2348 | |
| 2334 | | buf_resize(def_contents, 0); |
| 2335 | | buf_appendf(def_contents, "LIBRARY %s\nEXPORTS\n", buf_ptr(link_lib->name)); |
| 2336 | | for (size_t exp_i = 0; exp_i < link_lib->symbols.length; exp_i += 1) { |
| 2337 | | Buf *symbol_name = link_lib->symbols.at(exp_i); |
| 2338 | | buf_appendf(def_contents, "%s\n", buf_ptr(symbol_name)); |
| 2339 | | } |
| 2340 | | buf_appendf(def_contents, "\n"); |
| 2341 | | |
| 2342 | | Buf *def_path = buf_alloc(); |
| 2343 | | os_path_join(g->output_dir, buf_sprintf("%s.def", buf_ptr(link_lib->name)), def_path); |
| 2344 | | if ((err = os_write_file(def_path, def_contents))) { |
| 2345 | | zig_panic("error writing def file: %s", err_str(err)); |
| 2346 | | } |
| 2349 | // This library may be a system one and we may have a suitable .lib file |
| 2347 | 2350 | |
| 2348 | | Buf *generated_lib_path = buf_alloc(); |
| 2349 | | os_path_join(g->output_dir, buf_sprintf("%s.lib", buf_ptr(link_lib->name)), generated_lib_path); |
| 2351 | // Normalize the library name to lower case, the FS may be |
| 2352 | // case-sensitive |
| 2353 | char *name = strdup(buf_ptr(link_lib->name)); |
| 2354 | assert(name != nullptr); |
| 2355 | for (char *ch = name; *ch; ++ch) *ch = tolower(*ch); |
| 2350 | 2356 | |
| 2351 | | gen_lib_args.resize(0); |
| 2352 | | gen_lib_args.append("link"); |
| 2357 | Buf lib_path = BUF_INIT; |
| 2358 | err = find_mingw_lib_def(lj, name, &lib_path); |
| 2353 | 2359 | |
| 2354 | | coff_append_machine_arg(g, &gen_lib_args); |
| 2355 | | gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path)))); |
| 2356 | | gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path)))); |
| 2357 | | Buf diag = BUF_INIT; |
| 2358 | | ZigLLVM_ObjectFormatType target_ofmt = target_object_format(g->zig_target); |
| 2359 | | if (!zig_lld_link(target_ofmt, gen_lib_args.items, gen_lib_args.length, &diag)) { |
| 2360 | | fprintf(stderr, "%s\n", buf_ptr(&diag)); |
| 2361 | | exit(1); |
| 2360 | if (err == ErrorFileNotFound) { |
| 2361 | zig_panic("link: could not find .def file to build %s\n", name); |
| 2362 | } else if (err != ErrorNone) { |
| 2363 | zig_panic("link: unable to check if .def file for %s exists: %s", |
| 2364 | name, err_str(err)); |
| 2362 | 2365 | } |
| 2363 | | lj->args.append(buf_ptr(generated_lib_path)); |
| 2366 | |
| 2367 | lj->args.append(get_def_lib(g, name, &lib_path)); |
| 2368 | |
| 2369 | free(name); |
| 2364 | 2370 | } |
| 2365 | 2371 | } |
| 2366 | 2372 | |