| ... | @@ -2098,6 +2098,60 @@ static bool is_linking_system_lib(CodeGen *g, const char *name) { | ... | @@ -2098,6 +2098,60 @@ static bool is_linking_system_lib(CodeGen *g, const char *name) { |
| 2098 | return false; | 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 | static void add_mingw_link_args(LinkJob *lj, bool is_library) { | 2155 | static void add_mingw_link_args(LinkJob *lj, bool is_library) { |
| 2102 | CodeGen *g = lj->codegen; | 2156 | CodeGen *g = lj->codegen; |
| 2103 | | 2157 | |
| ... | @@ -2125,55 +2179,18 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) { | ... | @@ -2125,55 +2179,18 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) { |
| 2125 | const char *name = mingw_def_list[def_i].name; | 2179 | const char *name = mingw_def_list[def_i].name; |
| 2126 | const bool always_link = mingw_def_list[def_i].always_link; | 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; | 2185 | if (err == ErrorFileNotFound) { |
| 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) { | | |
| 2172 | zig_panic("link: could not find .def file to build %s\n", name); | 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 | if (always_link || is_linking_system_lib(g, name)) { | 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,8 +2324,6 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 2307 | lj->args.append(buf_ptr(compiler_rt_o_path)); | 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 | for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { | 2327 | for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { |
| 2313 | LinkLib *link_lib = g->link_libs_list.at(lib_i); | 2328 | LinkLib *link_lib = g->link_libs_list.at(lib_i); |
| 2314 | if (buf_eql_str(link_lib->name, "c")) { | 2329 | if (buf_eql_str(link_lib->name, "c")) { |
| ... | @@ -2331,36 +2346,27 @@ static void construct_linker_job_coff(LinkJob *lj) { | ... | @@ -2331,36 +2346,27 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 2331 | continue; | 2346 | continue; |
| 2332 | } | 2347 | } |
| 2333 | | 2348 | |
| 2334 | buf_resize(def_contents, 0); | 2349 | // This library may be a system one and we may have a suitable .lib file |
| 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 | } | | |
| 2347 | | 2350 | |
| 2348 | Buf *generated_lib_path = buf_alloc(); | 2351 | // Normalize the library name to lower case, the FS may be |
| 2349 | os_path_join(g->output_dir, buf_sprintf("%s.lib", buf_ptr(link_lib->name)), generated_lib_path); | 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); | 2357 | Buf lib_path = BUF_INIT; |
| 2352 | gen_lib_args.append("link"); | 2358 | err = find_mingw_lib_def(lj, name, &lib_path); |
| 2353 | | 2359 | |
| 2354 | coff_append_machine_arg(g, &gen_lib_args); | 2360 | if (err == ErrorFileNotFound) { |
| 2355 | gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path)))); | 2361 | zig_panic("link: could not find .def file to build %s\n", name); |
| 2356 | gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path)))); | 2362 | } else if (err != ErrorNone) { |
| 2357 | Buf diag = BUF_INIT; | 2363 | zig_panic("link: unable to check if .def file for %s exists: %s", |
| 2358 | ZigLLVM_ObjectFormatType target_ofmt = target_object_format(g->zig_target); | 2364 | name, err_str(err)); |
| 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); | | |
| 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 | |