initial win32 support mostly using ccache-win32-2.4 patches to ccache-2.4

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10982 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2008-12-17 00:21:13 +00:00
commit 5964f3e27d
5 changed files with 255 additions and 30 deletions

View file

@ -136,7 +136,7 @@ static void failed(void)
putenv("CCACHE_OUTFILES"); putenv("CCACHE_OUTFILES");
} }
execv(orig_args->argv[0], orig_args->argv); execv(orig_args->argv[0], (const char *const *)orig_args->argv);
cc_log("execv returned (%s)!\n", strerror(errno)); cc_log("execv returned (%s)!\n", strerror(errno));
perror(orig_args->argv[0]); perror(orig_args->argv[0]);
exit(1); exit(1);
@ -722,7 +722,11 @@ static void find_compiler(int argc, char **argv)
if (strcmp(base, MYNAME) == 0) { if (strcmp(base, MYNAME) == 0) {
args_remove_first(orig_args); args_remove_first(orig_args);
free(base); free(base);
if (strchr(argv[1],'/')) { if (strchr(argv[1],'/')
#ifdef _WIN32
|| strchr(argv[1],'\\')
#endif
) {
/* a full path was given */ /* a full path was given */
return; return;
} }

View file

@ -2,7 +2,11 @@
#define CCACHE_VERSION SWIG_VERSION #define CCACHE_VERSION SWIG_VERSION
#ifndef _WIN32
#include "config.h" #include "config.h"
#else
#define PACKAGE_NAME "ccache-swig.exe"
#endif
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@ -10,8 +14,16 @@
#include <errno.h> #include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h> #ifndef _WIN32
#include <sys/wait.h>
#include <sys/mman.h>
#else
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <shlobj.h>
#endif
#include <sys/file.h> #include <sys/file.h>
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>

View file

@ -18,6 +18,33 @@
#include "ccache.h" #include "ccache.h"
#ifdef _WIN32
static char *argvtos(char **argv)
{
int i, len;
char *ptr, *str;
for (i = 0, len = 0; argv[i]; i++) {
len += strlen(argv[i]) + 3;
}
str = ptr = (char *)malloc(len + 1);
if (str == NULL)
return NULL;
for (i = 0; argv[i]; i++) {
len = strlen(argv[i]);
*ptr++ = '"';
memcpy(ptr, argv[i], len);
ptr += len;
*ptr++ = '"';
*ptr++ = ' ';
}
*ptr = 0;
return str;
}
#endif
/* /*
execute a compiler backend, capturing all output to the given paths execute a compiler backend, capturing all output to the given paths
@ -27,6 +54,60 @@ int execute(char **argv,
const char *path_stdout, const char *path_stdout,
const char *path_stderr) const char *path_stderr)
{ {
#ifdef _WIN32
PROCESS_INFORMATION pinfo;
STARTUPINFO sinfo;
BOOL ret;
DWORD exitcode;
char *args;
HANDLE fd_out, fd_err;
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
/* TODO: needs moving after possible exit() below, but before stdout is redirected */
if (ccache_verbose) {
display_execute_args(argv);
}
fd_out = CreateFile(path_stdout, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (fd_out == INVALID_HANDLE_VALUE) {
return STATUS_NOCACHE;
}
fd_err = CreateFile(path_stderr, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (fd_err == INVALID_HANDLE_VALUE) {
return STATUS_NOCACHE;
}
ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION));
ZeroMemory(&sinfo, sizeof(STARTUPINFO));
sinfo.cb = sizeof(STARTUPINFO);
sinfo.hStdError = fd_err;
sinfo.hStdOutput = fd_out;
sinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
sinfo.dwFlags |= STARTF_USESTDHANDLES;
args = argvtos(argv);
ret = CreateProcessA(argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL,
&sinfo, &pinfo);
free(args);
CloseHandle(fd_out);
CloseHandle(fd_err);
if (ret == 0)
return -1;
WaitForSingleObject(pinfo.hProcess, INFINITE);
GetExitCodeProcess(pinfo.hProcess, &exitcode);
CloseHandle(pinfo.hProcess);
CloseHandle(pinfo.hThread);
return exitcode;
#else
pid_t pid; pid_t pid;
int status; int status;
@ -69,6 +150,7 @@ int execute(char **argv,
} }
return WEXITSTATUS(status); return WEXITSTATUS(status);
#endif
} }
@ -77,6 +159,19 @@ int execute(char **argv,
*/ */
char *find_executable(const char *name, const char *exclude_name) char *find_executable(const char *name, const char *exclude_name)
{ {
#if _WIN32
(void)exclude_name;
DWORD ret;
char namebuf[MAX_PATH];
ret = SearchPathA(getenv("CCACHE_PATH"), name, ".exe",
sizeof(namebuf), namebuf, NULL);
if (ret != 0) {
return x_strdup(namebuf);
}
return NULL;
#else
char *path; char *path;
char *tok; char *tok;
struct stat st1, st2; struct stat st1, st2;
@ -131,6 +226,7 @@ char *find_executable(const char *name, const char *exclude_name)
} }
return NULL; return NULL;
#endif
} }
void display_execute_args(char **argv) void display_execute_args(char **argv)

View file

@ -238,6 +238,39 @@ static void unify(unsigned char *p, size_t size)
*/ */
int unify_hash(const char *fname) int unify_hash(const char *fname)
{ {
#ifdef _WIN32
HANDLE file;
HANDLE section;
MEMORY_BASIC_INFORMATION minfo;
char *map;
file = CreateFileA(fname, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (file == INVALID_HANDLE_VALUE)
return -1;
section = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
CloseHandle(file);
if (section == NULL)
return -1;
map = MapViewOfFile(section, FILE_MAP_READ, 0, 0, 0);
CloseHandle(section);
if (map == NULL)
return -1;
if (VirtualQuery(map, &minfo, sizeof(minfo)) != sizeof(minfo)) {
UnmapViewOfFile(map);
return -1;
}
/* pass it through the unifier */
unify((unsigned char *)map, minfo.RegionSize);
UnmapViewOfFile(map);
return 0;
#else
int fd; int fd;
struct stat st; struct stat st;
char *map; char *map;
@ -265,5 +298,6 @@ int unify_hash(const char *fname)
munmap(map, st.st_size); munmap(map, st.st_size);
return 0; return 0;
#endif
} }

View file

@ -46,19 +46,24 @@ void fatal(const char *msg)
int safe_rename(const char* oldpath, const char* newpath) int safe_rename(const char* oldpath, const char* newpath)
{ {
/* safe_rename is for creating entries in the cache. /* safe_rename is for creating entries in the cache.
Works like rename(), but it never overwrites an existing Works like rename(), but it never overwrites an existing
cache entry. This avoids corruption on NFS. */ cache entry. This avoids corruption on NFS. */
int status = link( oldpath, newpath ); #ifndef _WIN32
if( status == 0 || errno == EEXIST ) int status = link(oldpath, newpath);
{ if( status == 0 || errno == EEXIST )
return unlink( oldpath ); #else
} int status = CreateHardLinkA(newpath, oldpath, NULL) ? 0 : -1;
else if( status == 0 || GetLastError() == ERROR_ALREADY_EXISTS )
{ #endif
return -1; {
} return unlink( oldpath );
}
else
{
return -1;
}
} }
#ifndef ENABLE_ZLIB #ifndef ENABLE_ZLIB
@ -75,6 +80,15 @@ void copy_fd(int fd_in, int fd_out)
} }
} }
#ifndef HAVE_MKSTEMP
/* cheap and nasty mkstemp replacement */
static int mkstemp(char *template)
{
mktemp(template);
return open(template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
}
#endif
/* move a file using rename */ /* move a file using rename */
int move_file(const char *src, const char *dest) { int move_file(const char *src, const char *dest) {
return safe_rename(src, dest); return safe_rename(src, dest);
@ -119,9 +133,13 @@ static int copy_file(const char *src, const char *dest)
close(fd1); close(fd1);
/* get perms right on the tmp file */ /* get perms right on the tmp file */
#ifndef _WIN32
mask = umask(0); mask = umask(0);
fchmod(fd2, 0666 & ~mask); fchmod(fd2, 0666 & ~mask);
umask(mask); umask(mask);
#else
(void)mask;
#endif
/* the close can fail on NFS if out of space */ /* the close can fail on NFS if out of space */
if (close(fd2) == -1) { if (close(fd2) == -1) {
@ -333,7 +351,11 @@ int commit_to_cache(const char *src, const char *dest, int hardlink)
int ret = -1; int ret = -1;
unlink(dest); unlink(dest);
if (hardlink) { if (hardlink) {
#ifdef _WIN32
ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
#else
ret = link(src, dest); ret = link(src, dest);
#endif
} }
if (ret == -1) { if (ret == -1) {
ret = copy_file_to_cache(src, dest); ret = copy_file_to_cache(src, dest);
@ -358,7 +380,11 @@ int retrieve_from_cache(const char *src, const char *dest, int hardlink)
unlink(dest); unlink(dest);
/* only make a hardlink if the cache file is uncompressed */ /* only make a hardlink if the cache file is uncompressed */
if (hardlink && test_if_compressed(src) == 0) { if (hardlink && test_if_compressed(src) == 0) {
#ifdef _WIN32
ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
#else
ret = link(src, dest); ret = link(src, dest);
#endif
} else { } else {
ret = copy_file_from_cache(src, dest); ret = copy_file_from_cache(src, dest);
} }
@ -393,9 +419,15 @@ int create_dir(const char *dir)
errno = ENOTDIR; errno = ENOTDIR;
return 1; return 1;
} }
#ifdef _WIN32
if (mkdir(dir) != 0 && errno != EEXIST) {
return 1;
}
#else
if (mkdir(dir, 0777) != 0 && errno != EEXIST) { if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
return 1; return 1;
} }
#endif
return 0; return 0;
} }
@ -526,7 +558,12 @@ void traverse(const char *dir, void (*fn)(const char *, struct stat *))
if (strlen(de->d_name) == 0) continue; if (strlen(de->d_name) == 0) continue;
x_asprintf(&fname, "%s/%s", dir, de->d_name); x_asprintf(&fname, "%s/%s", dir, de->d_name);
if (lstat(fname, &st)) { #ifdef _WIN32
if (stat(fname, &st))
#else
if (lstat(fname, &st))
#endif
{
if (errno != ENOENT) { if (errno != ENOENT) {
perror(fname); perror(fname);
} }
@ -551,8 +588,16 @@ char *str_basename(const char *s)
{ {
char *p = strrchr(s, '/'); char *p = strrchr(s, '/');
if (p) { if (p) {
return x_strdup(p+1); s = (p+1);
} }
#ifdef _WIN32
p = strrchr(s, '\\');
if (p) {
s = (p+1);
}
#endif
return x_strdup(s); return x_strdup(s);
} }
@ -563,6 +608,9 @@ char *dirname(char *s)
char *p; char *p;
s = x_strdup(s); s = x_strdup(s);
p = strrchr(s, '/'); p = strrchr(s, '/');
#ifdef _WIN32
p = strrchr(s, '\\');
#endif
if (p) { if (p) {
*p = 0; *p = 0;
} }
@ -571,6 +619,7 @@ char *dirname(char *s)
int lock_fd(int fd) int lock_fd(int fd)
{ {
#ifndef _WIN32
struct flock fl; struct flock fl;
int ret; int ret;
@ -586,17 +635,26 @@ int lock_fd(int fd)
ret = fcntl(fd, F_SETLKW, &fl); ret = fcntl(fd, F_SETLKW, &fl);
} while (ret == -1 && errno == EINTR); } while (ret == -1 && errno == EINTR);
return ret; return ret;
#else
(void)fd;
#warning "missing implementation???"
return 0;
#endif
} }
/* return size on disk of a file */ /* return size on disk of a file */
size_t file_size(struct stat *st) size_t file_size(struct stat *st)
{ {
#ifdef _WIN32
return (st->st_size + 1023) & ~1023;
#else
size_t size = st->st_blocks * 512; size_t size = st->st_blocks * 512;
if ((size_t)st->st_size > size) { if ((size_t)st->st_size > size) {
/* probably a broken stat() call ... */ /* probably a broken stat() call ... */
size = (st->st_size + 1023) & ~1023; size = (st->st_size + 1023) & ~1023;
} }
return size; return size;
#endif
} }
@ -658,6 +716,17 @@ size_t value_units(const char *s)
*/ */
char *x_realpath(const char *path) char *x_realpath(const char *path)
{ {
#ifdef _WIN32
char namebuf[MAX_PATH];
DWORD ret;
ret = GetFullPathNameA(path, sizeof(namebuf), namebuf, NULL);
if (ret == 0 || ret >= sizeof(namebuf)) {
return NULL;
}
return x_strdup(namebuf);
#else
int maxlen; int maxlen;
char *ret, *p; char *ret, *p;
#ifdef PATH_MAX #ifdef PATH_MAX
@ -693,6 +762,7 @@ char *x_realpath(const char *path)
} }
free(ret); free(ret);
return NULL; return NULL;
#endif
} }
/* a getcwd that will returns an allocated buffer */ /* a getcwd that will returns an allocated buffer */
@ -713,16 +783,6 @@ char *gnu_getcwd(void)
} }
} }
#ifndef HAVE_MKSTEMP
/* cheap and nasty mkstemp replacement */
int mkstemp(char *template)
{
mktemp(template);
return open(template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
}
#endif
/* create an empty file */ /* create an empty file */
int create_empty_file(const char *fname) int create_empty_file(const char *fname)
{ {
@ -741,6 +801,24 @@ int create_empty_file(const char *fname)
*/ */
const char *get_home_directory(void) const char *get_home_directory(void)
{ {
#ifdef _WIN32
static char home_path[MAX_PATH] = {0};
HRESULT ret;
/* we already have the path */
if (home_path[0] != 0) {
return home_path;
}
/* get the path to "Application Data" folder */
ret = SHGetFolderPathA(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, home_path);
if (SUCCEEDED(ret)) {
return home_path;
}
fprintf(stderr, "ccache: Unable to determine home directory\n");
return NULL;
#else
const char *p = getenv("HOME"); const char *p = getenv("HOME");
if (p) { if (p) {
return p; return p;
@ -753,8 +831,9 @@ const char *get_home_directory(void)
} }
} }
#endif #endif
cc_log("Unable to determine home directory"); fatal("Unable to determine home directory");
return NULL; return NULL;
#endif
} }
int x_utimes(const char *filename) int x_utimes(const char *filename)