Commit dfada0cc77

emekoi <emekankurumeh@outlook.com>
2019-04-27 07:24:26
added static_crt_dir to libc file
1 parent f4c5fa7
src/libc_installation.cpp
@@ -14,6 +14,7 @@ static const char *zig_libc_keys[] = {
     "include_dir",
     "sys_include_dir",
     "crt_dir",
+    "static_crt_dir",
     "msvc_lib_dir",
     "kernel32_lib_dir",
 };
@@ -34,6 +35,7 @@ static void zig_libc_init_empty(ZigLibCInstallation *libc) {
     buf_init_from_str(&libc->include_dir, "");
     buf_init_from_str(&libc->sys_include_dir, "");
     buf_init_from_str(&libc->crt_dir, "");
+    buf_init_from_str(&libc->static_crt_dir, "");
     buf_init_from_str(&libc->msvc_lib_dir, "");
     buf_init_from_str(&libc->kernel32_lib_dir, "");
 }
@@ -74,8 +76,9 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget
         match = match || zig_libc_match_key(name, value, found_keys, 0, &libc->include_dir);
         match = match || zig_libc_match_key(name, value, found_keys, 1, &libc->sys_include_dir);
         match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->crt_dir);
-        match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->msvc_lib_dir);
-        match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->kernel32_lib_dir);
+        match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->static_crt_dir);
+        match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->msvc_lib_dir);
+        match = match || zig_libc_match_key(name, value, found_keys, 5, &libc->kernel32_lib_dir);
     }
 
     for (size_t i = 0; i < zig_libc_keys_len; i += 1) {
@@ -110,6 +113,15 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget
         }
     }
 
+    if (buf_len(&libc->static_crt_dir) == 0) {
+        if (target->os == OsWindows && target_abi_is_gnu(target->abi)) {
+            if (verbose) {
+                fprintf(stderr, "static_crt_dir may not be empty for %s\n", target_os_name(target->os));
+            }
+            return ErrorSemanticAnalyzeFail;
+        }
+    }
+
     if (buf_len(&libc->msvc_lib_dir) == 0) {
         if (target->os == OsWindows && !target_abi_is_gnu(target->abi)) {
             if (verbose) {
@@ -261,7 +273,7 @@ static Error zig_libc_find_native_include_dir_posix(ZigLibCInstallation *self, b
     return ErrorFileNotFound;
 }
 
-Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) {
+static Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) {
     const char *cc_exe = getenv("CC");
     cc_exe = (cc_exe == nullptr) ? CC_EXE : cc_exe;
     ZigList<const char *> args = {};
@@ -308,6 +320,10 @@ static Error zig_libc_find_native_crt_dir_posix(ZigLibCInstallation *self, bool
     return zig_libc_cc_print_file_name("crt1.o", &self->crt_dir, true, verbose);
 }
 
+static Error zig_libc_find_native_static_crt_dir_posix(ZigLibCInstallation *self, bool verbose) {
+    return zig_libc_cc_print_file_name("crtbegin.o", &self->static_crt_dir, true, verbose);
+}
+
 #if defined(ZIG_OS_WINDOWS)
 static Error zig_libc_find_native_include_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
     Error err;
@@ -320,7 +336,7 @@ static Error zig_libc_find_native_include_dir_windows(ZigLibCInstallation *self,
     return ErrorNone;
 }
 
-static Error zig_libc_find_crt_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
+static Error zig_libc_find_native_crt_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
         bool verbose)
 {
     Error err;
@@ -396,11 +412,16 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
         "# On POSIX it's the directory that includes `sys/errno.h`.\n"
         "sys_include_dir=%s\n"
         "\n"
-        "# The directory that contains `crt1.o`.\n"
+        "# The directory that contains `crt1.o` or `crt2.o`.\n"
         "# On POSIX, can be found with `cc -print-file-name=crt1.o`.\n"
         "# Not needed when targeting MacOS.\n"
         "crt_dir=%s\n"
         "\n"
+        "# The directory that contains `crtbegin.o`.\n"
+        "# On POSIX, can be found with `cc -print-file-name=crtbegin.o`.\n"
+        "# Not needed when targeting MacOS.\n"
+        "static_crt_dir=%s\n"
+        "\n"
         "# The directory that contains `vcruntime.lib`.\n"
         "# Only needed when targeting MSVC on Windows.\n"
         "msvc_lib_dir=%s\n"
@@ -413,6 +434,7 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
         buf_ptr(&self->include_dir),
         buf_ptr(&self->sys_include_dir),
         buf_ptr(&self->crt_dir),
+        buf_ptr(&self->static_crt_dir),
         buf_ptr(&self->msvc_lib_dir),
         buf_ptr(&self->kernel32_lib_dir)
     );
@@ -429,6 +451,8 @@ Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) {
             return err;
         if ((err = zig_libc_find_native_crt_dir_posix(self, verbose)))
             return err;
+        if ((err = zig_libc_find_native_static_crt_dir_posix(self, verbose)))
+            return err;
         return ErrorNone;
     } else {
         ZigWindowsSDK *sdk;
@@ -442,7 +466,7 @@ Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) {
                     return err;
                 if ((err = zig_libc_find_native_include_dir_windows(self, sdk, verbose)))
                     return err;
-                if ((err = zig_libc_find_crt_dir_windows(self, sdk, &native_target, verbose)))
+                if ((err = zig_libc_find_native_crt_dir_windows(self, sdk, &native_target, verbose)))
                     return err;
                 return ErrorNone;
             case ZigFindWindowsSdkErrorOutOfMemory:
src/libc_installation.hpp
@@ -19,6 +19,7 @@ struct ZigLibCInstallation {
     Buf include_dir;
     Buf sys_include_dir;
     Buf crt_dir;
+    Buf static_crt_dir;
     Buf msvc_lib_dir;
     Buf kernel32_lib_dir;
 };
@@ -29,6 +30,4 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file);
 
 Error ATTRIBUTE_MUST_USE zig_libc_find_native(ZigLibCInstallation *self, bool verbose);
 
-Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose);
-
 #endif
src/link.cpp
@@ -1170,12 +1170,8 @@ static const char *get_libc_file(ZigLibCInstallation *lib, const char *file) {
 }
 
 static const char *get_libc_static_file(ZigLibCInstallation *lib, const char *file) {
-    Buf *static_crt_dir = buf_alloc();
     Buf *out_buf = buf_alloc();
-    if (zig_libc_cc_print_file_name(file, static_crt_dir, true, true) != ErrorNone) {
-        abort();
-    }
-    os_path_join(static_crt_dir, buf_create_from_str(file), out_buf);
+    os_path_join(&lib->static_crt_dir, buf_create_from_str(file), out_buf);
     return buf_ptr(out_buf);
 }
 
@@ -1198,35 +1194,33 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) {
 
     lj->args.append(get_libc_static_file(g->libc, "crtbegin.o"));
 
-    if (g->libc_link_lib != nullptr) {
-        lj->args.append("libmingw32.a");
+    lj->args.append(get_libc_file(g->libc, "libmingw32.a"));
 
-        if (is_dll) {
-            lj->args.append(get_libc_static_file(g->libc, "libgcc_s.a"));
-            lj->args.append(get_libc_static_file(g->libc, "libgcc.a"));
-        } else {
-            lj->args.append(get_libc_static_file(g->libc, "libgcc.a"));
-            lj->args.append(get_libc_static_file(g->libc, "libgcc_eh.a"));
-        }
+    if (is_dll) {
+        lj->args.append(get_libc_static_file(g->libc, "libgcc_s.a"));
+        lj->args.append(get_libc_static_file(g->libc, "libgcc.a"));
+    } else {
+        lj->args.append(get_libc_static_file(g->libc, "libgcc.a"));
+        lj->args.append(get_libc_static_file(g->libc, "libgcc_eh.a"));
+    }
 
-        lj->args.append(get_libc_static_file(g->libc, "libssp.a"));
-        lj->args.append("libmoldname.a");
-        lj->args.append("libmingwex.a");
-        lj->args.append("libmsvcrt.a");
+    lj->args.append(get_libc_static_file(g->libc, "libssp.a"));
+    lj->args.append(get_libc_file(g->libc, "libmoldname.a"));
+    lj->args.append(get_libc_file(g->libc, "libmingwex.a"));
+    lj->args.append(get_libc_file(g->libc, "libmsvcrt.a"));
 
-        if (g->subsystem == TargetSubsystemWindows) {
-            lj->args.append("libgdi32.a");
-            lj->args.append("libcomdlg32.a");
-        }
+    if (g->subsystem == TargetSubsystemWindows) {
+        lj->args.append(get_libc_file(g->libc, "libgdi32.a"));
+        lj->args.append(get_libc_file(g->libc, "libcomdlg32.a"));
+    }
 
-        lj->args.append("libadvapi32.a");
-        lj->args.append("libadvapi32.a");
-        lj->args.append("libshell32.a");
-        lj->args.append("libuser32.a");
-        lj->args.append("libkernel32.a");
+    lj->args.append(get_libc_file(g->libc, "libadvapi32.a"));
+    lj->args.append(get_libc_file(g->libc, "libadvapi32.a"));
+    lj->args.append(get_libc_file(g->libc, "libshell32.a"));
+    lj->args.append(get_libc_file(g->libc, "libuser32.a"));
+    lj->args.append(get_libc_file(g->libc, "libkernel32.a"));
 
-        lj->args.append(get_libc_static_file(g->libc, "crtend.o"));
-    }
+    lj->args.append(get_libc_static_file(g->libc, "crtend.o"));
 }
 
 static void add_win_link_args(LinkJob *lj, bool is_library) {
@@ -1359,25 +1353,8 @@ static void construct_linker_job_coff(LinkJob *lj) {
         }
         if (link_lib->provided_explicitly) {
             if (target_abi_is_gnu(lj->codegen->zig_target->abi)) {
-                static const char *test_names[3] = { "%s\\lib%s.dll.a", "%s\\lib%s.a", nullptr };
-                bool exists = false;
-
-                for (size_t i = 0; test_names[i] != nullptr && !exists; i++) {
-                    for (size_t j = 0; j < g->lib_dirs.length; j += 1) {
-                        const char *lib_dir = g->lib_dirs.at(j);
-                        Buf *test_path = buf_sprintf(test_names[i], lib_dir, buf_ptr(link_lib->name));
-                        if (os_file_exists(test_path, &exists) != ErrorNone) {
-                            zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path));
-                        } else if (exists) {
-                            lj->args.append(buf_ptr(test_path));
-                            break;
-                        }
-                    }
-                }
-
-                if (!exists) {
-                    zig_panic("link: unable to find library: %s", buf_ptr(link_lib->name));
-                }
+                Buf *lib_name = buf_sprintf("lib%s.a", buf_ptr(link_lib->name));
+                lj->args.append(buf_ptr(lib_name));
             } else {
                 lj->args.append(buf_ptr(link_lib->name));
             }