]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix windows build and successfully tested on windows with android NDK
authorleanid <leanid.chaika@gmail.com>
Thu, 20 Nov 2014 13:10:03 +0000 (16:10 +0300)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 28 Jan 2015 21:33:48 +0000 (22:33 +0100)
ccache.c
ccache.h
execute.c
util.c

index 1be106b875dd15a18247e4c9f35840357ec25570..b6afe844edca234ad7f0e6c21ff5f8148d23f151 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -802,9 +802,20 @@ to_cache(struct args *args)
                char *tmp_stderr2;
 
                tmp_stderr2 = format("%s.2", tmp_stderr);
-               if (x_rename(tmp_stderr, tmp_stderr2)) {
+#ifdef _WIN32
+               // on Windows file descriptor should be closed before rename
+               int prev_stderr_fd = tmp_stderr_fd;
+               close(tmp_stderr_fd);
+#endif
+               int rename_result = x_rename(tmp_stderr, tmp_stderr2);
+#ifdef _WIN32
+               tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
+               assert(prev_stderr_fd == tmp_stderr_fd);
+#endif
+               if (rename_result) {
+                       const char* err_str = strerror(errno);
                        cc_log("Failed to rename %s to %s: %s", tmp_stderr, tmp_stderr2,
-                              strerror(errno));
+                              err_str);
                        failed();
                }
                fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
@@ -990,6 +1001,8 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash)
 
        time_of_compilation = time(NULL);
 
+       int path_stdout_fd = -1;
+
        if (direct_i_file) {
                /* We are compiling a .i or .ii file - that means we can skip the cpp stage
                 * and directly form the correct i_tmpfile. */
@@ -997,7 +1010,6 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash)
                status = 0;
        } else {
                /* Run cpp on the input file to obtain the .i. */
-               int path_stdout_fd;
                path_stdout = format("%s/%s.stdout", temp_dir(), input_base);
                path_stdout_fd = create_tmp_fd(&path_stdout);
                add_pending_tmp_file(path_stdout);
@@ -1046,7 +1058,21 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash)
                /* i_tmpfile needs the proper cpp_extension for the compiler to do its
                 * thing correctly. */
                i_tmpfile = format("%s.%s", path_stdout, conf->cpp_extension);
+#ifdef _WIN32
+               // on Windows rename only if file descriptor closed
+               if (path_stdout_fd != -1)
+               {
+                       close(path_stdout_fd);
+               }
+#endif
                x_rename(path_stdout, i_tmpfile);
+#ifdef _WIN32
+               if (path_stdout_fd != -1)
+               {
+                       int tmp_fd = create_tmp_fd(&path_stdout);
+                       assert(tmp_fd == path_stdout_fd);
+               }
+#endif
                add_pending_tmp_file(i_tmpfile);
        }
 
@@ -1150,11 +1176,32 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
        hash_delimiter(hash, "ext");
        hash_string(hash, conf->cpp_extension);
 
+#ifdef _WIN32
+       const char* ext = strchr(args->argv[0], '.');
+       char full_path_win_ext[MAX_PATH] = {0};
+       strncat(full_path_win_ext, args->argv[0], MAX_PATH);
+       if (!ext
+               || (strcmp(".exe", ext) != 0
+                       && strcmp(".bat", ext) != 0
+                       && strcmp(".EXE", ext) != 0
+                       && strcmp(".BAT", ext) != 0
+                       )
+               )
+       {
+               strncat(full_path_win_ext, ".exe", MAX_PATH);
+       }
+       if (stat(full_path_win_ext, &st) != 0) {
+               cc_log("Couldn't stat compiler %s: %s", args->argv[0], strerror(errno));
+               stats_update(STATS_COMPILER);
+               failed();
+       }
+#else
        if (stat(args->argv[0], &st) != 0) {
                cc_log("Couldn't stat compiler %s: %s", args->argv[0], strerror(errno));
                stats_update(STATS_COMPILER);
                failed();
        }
+#endif
 
        /*
         * Hash information about the compiler.
index 6fdd55f6c88e7f1e33275e92a40aa971d2a5109d..461831360b11172df9746096ef629a5e93d6651b 100644 (file)
--- a/ccache.h
+++ b/ccache.h
@@ -251,7 +251,7 @@ typedef int (*COMPAR_FN_T)(const void *, const void *);
 char *win32argvtos(char *prefix, char **argv);
 char *win32getshell(char *path);
 int win32execute(char *path, char **argv, int doreturn,
-                 const char *path_stdout, const char *path_stderr);
+                 int fd_stdout, int fd_stderr);
 #    ifndef _WIN32_WINNT
 #    define _WIN32_WINNT 0x0501
 #    endif
@@ -259,8 +259,7 @@ int win32execute(char *path, char **argv, int doreturn,
 #    define mkdir(a,b) mkdir(a)
 #    define link(src,dst) (CreateHardLink(dst,src,NULL) ? 0 : -1)
 #    define lstat(a,b) stat(a,b)
-#    define execv(a,b) win32execute(a,b,0,NULL,NULL)
-#error TODO: Adapt win32execute to new execute API
+#    define execv(a,b) win32execute(a,b,0,0,0)
 #    define execute(a,b,c) win32execute(*(a),a,1,b,c)
 #    define PATH_DELIM ";"
 #    define F_RDLCK 0
index 78f1e4b7888e9a948c58ee92042e4e10c252ecf8..52a9b98975e773c8b8c9a94003d0b274aeb9d4bc 100644 (file)
--- a/execute.c
+++ b/execute.c
@@ -119,7 +119,7 @@ win32getshell(char *path)
 
 int
 win32execute(char *path, char **argv, int doreturn,
-             const char *path_stdout, const char *path_stderr)
+             int fd_stdout, int fd_stderr)
 {
        PROCESS_INFORMATION pi;
        STARTUPINFO si;
@@ -136,29 +136,60 @@ win32execute(char *path, char **argv, int doreturn,
                path = sh;
 
        si.cb = sizeof(STARTUPINFO);
-       if (path_stdout) {
-               SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
-               si.hStdOutput = CreateFile(path_stdout, GENERIC_WRITE, 0, &sa,
-                                          CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY |
-                                          FILE_FLAG_SEQUENTIAL_SCAN, NULL);
-               si.hStdError  = CreateFile(path_stderr, GENERIC_WRITE, 0, &sa,
-                                          CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY |
-                                          FILE_FLAG_SEQUENTIAL_SCAN, NULL);
-               si.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);
-               si.dwFlags    = STARTF_USESTDHANDLES;
-               if (si.hStdOutput == INVALID_HANDLE_VALUE ||
-                   si.hStdError  == INVALID_HANDLE_VALUE)
+       if (fd_stdout != -1) {
+               si.hStdOutput = (HANDLE)_get_osfhandle(fd_stdout);
+               si.hStdError = (HANDLE)_get_osfhandle(fd_stderr);
+
+               si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+               si.dwFlags = STARTF_USESTDHANDLES;
+               if (si.hStdOutput == INVALID_HANDLE_VALUE
+                               || si.hStdError == INVALID_HANDLE_VALUE) {
                        return -1;
+               }
        }
        args = win32argvtos(sh, argv);
-       ret = CreateProcess(path, args, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
-       free(args);
-       if (path_stdout) {
-               CloseHandle(si.hStdOutput);
-               CloseHandle(si.hStdError);
+
+       const char* ext = strchr(path, '.');
+       char full_path_win_ext[MAX_PATH] = { 0 };
+       strncat(full_path_win_ext, path, MAX_PATH);
+       if (!ext
+                       || (strcmp(".exe", ext) != 0 && strcmp(".bat", ext) != 0
+                                       && strcmp(".EXE", ext) != 0 && strcmp(".BAT", ext) != 0)) {
+               strncat(full_path_win_ext, ".exe", MAX_PATH);
        }
-       if (ret == 0)
+
+       ret = CreateProcess(full_path_win_ext, args, NULL, NULL, 1, 0, NULL, NULL,
+                       &si, &pi);
+       free(args);
+       if (ret == 0) {
+               LPVOID lpMsgBuf;
+               LPVOID lpDisplayBuf;
+               DWORD dw = GetLastError();
+
+               FormatMessage(
+               FORMAT_MESSAGE_ALLOCATE_BUFFER |
+               FORMAT_MESSAGE_FROM_SYSTEM |
+               FORMAT_MESSAGE_IGNORE_INSERTS,
+               NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
+                               0, NULL);
+
+               lpDisplayBuf =
+                               (LPVOID) LocalAlloc(LMEM_ZEROINIT,
+                                               (lstrlen((LPCTSTR) lpMsgBuf)
+                                                               + lstrlen((LPCTSTR) __FILE__) + 200)
+                                                               * sizeof(TCHAR));
+               _snprintf((LPTSTR) lpDisplayBuf,
+                               LocalSize(lpDisplayBuf) / sizeof(TCHAR),
+                               TEXT("%s failed with error %d: %s"), __FILE__, dw, lpMsgBuf);
+
+               cc_log("can't execute %s\nOS returned error: %s\n",
+                               full_path_win_ext, (char*)lpDisplayBuf);
+
+               LocalFree(lpMsgBuf);
+               LocalFree(lpDisplayBuf);
+
                return -1;
+       }
        WaitForSingleObject(pi.hProcess, INFINITE);
        GetExitCodeProcess(pi.hProcess, &exitcode);
        CloseHandle(pi.hProcess);
diff --git a/util.c b/util.c
index 80eb58b6e8d5b2c30e762f836eb944df5ed9ed01..72e641f98eed0797f6d3d78436e5773065be1986 100644 (file)
--- a/util.c
+++ b/util.c
@@ -494,12 +494,73 @@ create_parent_dirs(const char *path)
 const char *
 get_hostname(void)
 {
-       static char hostname[200] = "";
+       static char hostname[260] = "";
 
        if (!hostname[0]) {
                strcpy(hostname, "unknown");
 #if HAVE_GETHOSTNAME
                gethostname(hostname, sizeof(hostname)-1);
+#elif defined(_WIN32)
+
+               const char* computer_name = getenv("COMPUTERNAME");
+               if (computer_name)
+               {
+                       strncpy(hostname, computer_name, sizeof(hostname) -1);
+                       return hostname;
+               }
+
+               WORD wVersionRequested;
+               WSADATA wsaData;
+               int err;
+
+               wVersionRequested = MAKEWORD(2, 2);
+
+               err = WSAStartup(wVersionRequested, &wsaData);
+               if (err != 0) {
+                       /* Tell the user that we could not find a usable */
+                       /* Winsock DLL.                                  */
+                       cc_log("WSAStartup failed with error: %d\n", err);
+                       return hostname;
+               }
+
+           if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
+               /* Tell the user that we could not find a usable */
+               /* WinSock DLL.                                  */
+               cc_log("Could not find a usable version of Winsock.dll\n");
+               WSACleanup();
+               return hostname;
+           }
+
+               int result = gethostname(hostname, sizeof(hostname)-1);
+               if (result != 0)
+               {
+                       int last_error = WSAGetLastError();
+                       LPVOID lpMsgBuf;
+                       LPVOID lpDisplayBuf;
+                       DWORD dw = last_error;
+
+                       FormatMessage(
+                               FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                               FORMAT_MESSAGE_FROM_SYSTEM |
+                               FORMAT_MESSAGE_IGNORE_INSERTS,
+                               NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                               (LPTSTR) &lpMsgBuf, 0, NULL);
+
+                       lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT,
+                                       (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__)
+                                                       + 200) * sizeof(TCHAR));
+                       _snprintf((LPTSTR) lpDisplayBuf,
+                                       LocalSize(lpDisplayBuf) / sizeof(TCHAR),
+                                       TEXT("%s failed with error %d: %s"), __FILE__, dw,
+                                       lpMsgBuf);
+
+                       cc_log("can't get hostname OS returned error: %s\n",
+                                       (char*) lpDisplayBuf);
+
+                       LocalFree(lpMsgBuf);
+                       LocalFree(lpDisplayBuf);
+               }
+               WSACleanup();
 #endif
                hostname[sizeof(hostname)-1] = 0;
        }
@@ -986,9 +1047,16 @@ x_realpath(const char *path)
        path_handle = CreateFile(
                path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL, NULL);
-       GetFinalPathNameByHandle(path_handle, ret, maxlen, FILE_NAME_NORMALIZED);
-       CloseHandle(path_handle);
-       p = ret+4;// strip the \\?\ from the file name
+       if(INVALID_HANDLE_VALUE != path_handle)
+       {
+               GetFinalPathNameByHandle(path_handle, ret, maxlen, FILE_NAME_NORMALIZED);
+               CloseHandle(path_handle);
+               p = ret+4;// strip the \\?\ from the file name
+       } else
+       {
+               strncpy(ret, path, maxlen);
+               p = ret;
+       }
 #else
        /* yes, there are such systems. This replacement relies on
           the fact that when we call x_realpath we only care about symlinks */
@@ -1301,14 +1369,47 @@ update_mtime(const char *path)
 /*
  * Rename oldpath to newpath (deleting newpath).
  */
+
 int
 x_rename(const char *oldpath, const char *newpath)
 {
 #ifdef _WIN32
        /* Windows' rename() refuses to overwrite an existing file. */
        unlink(newpath);  /* not x_unlink, as x_unlink calls x_rename */
-#endif
+       /*If the function succeeds, the return value is nonzero.*/
+       if (MoveFileA(oldpath, newpath) == 0)
+       {
+               LPVOID lpMsgBuf;
+               LPVOID lpDisplayBuf;
+               DWORD dw = GetLastError();
+
+               FormatMessage(
+               FORMAT_MESSAGE_ALLOCATE_BUFFER |
+               FORMAT_MESSAGE_FROM_SYSTEM |
+               FORMAT_MESSAGE_IGNORE_INSERTS,
+               NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
+                               0, NULL);
+
+               lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT,
+                               (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 40)
+                                               * sizeof(TCHAR));
+               _snprintf((LPTSTR) lpDisplayBuf,
+                               LocalSize(lpDisplayBuf) / sizeof(TCHAR),
+                               TEXT("%s failed with error %d: %s"), __FILE__, dw, lpMsgBuf);
+
+               cc_log("can't rename file %s to %s OS returned error: %s\n",
+                               oldpath, newpath, (char*) lpDisplayBuf);
+
+               LocalFree(lpMsgBuf);
+               LocalFree(lpDisplayBuf);
+               return -1;
+       } else
+       {
+               return 0;
+       }
+#else
        return rename(oldpath, newpath);
+#endif
 }
 
 /*