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");
}
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));
perror(orig_args->argv[0]);
exit(1);
@ -722,7 +722,11 @@ static void find_compiler(int argc, char **argv)
if (strcmp(base, MYNAME) == 0) {
args_remove_first(orig_args);
free(base);
if (strchr(argv[1],'/')) {
if (strchr(argv[1],'/')
#ifdef _WIN32
|| strchr(argv[1],'\\')
#endif
) {
/* a full path was given */
return;
}

View file

@ -2,7 +2,11 @@
#define CCACHE_VERSION SWIG_VERSION
#ifndef _WIN32
#include "config.h"
#else
#define PACKAGE_NAME "ccache-swig.exe"
#endif
#include <stdio.h>
#include <unistd.h>
@ -10,8 +14,16 @@
#include <errno.h>
#include <sys/stat.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 <fcntl.h>
#include <time.h>

View file

@ -18,6 +18,33 @@
#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
@ -27,6 +54,60 @@ int execute(char **argv,
const char *path_stdout,
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;
int status;
@ -69,6 +150,7 @@ int execute(char **argv,
}
return WEXITSTATUS(status);
#endif
}
@ -77,6 +159,19 @@ int execute(char **argv,
*/
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 *tok;
struct stat st1, st2;
@ -131,6 +226,7 @@ char *find_executable(const char *name, const char *exclude_name)
}
return NULL;
#endif
}
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)
{
#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;
struct stat st;
char *map;
@ -265,5 +298,6 @@ int unify_hash(const char *fname)
munmap(map, st.st_size);
return 0;
#endif
}

View file

@ -46,19 +46,24 @@ void fatal(const char *msg)
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
cache entry. This avoids corruption on NFS. */
int status = link( oldpath, newpath );
if( status == 0 || errno == EEXIST )
{
return unlink( oldpath );
}
else
{
return -1;
}
Works like rename(), but it never overwrites an existing
cache entry. This avoids corruption on NFS. */
#ifndef _WIN32
int status = link(oldpath, newpath);
if( status == 0 || errno == EEXIST )
#else
int status = CreateHardLinkA(newpath, oldpath, NULL) ? 0 : -1;
if( status == 0 || GetLastError() == ERROR_ALREADY_EXISTS )
#endif
{
return unlink( oldpath );
}
else
{
return -1;
}
}
#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 */
int move_file(const char *src, const char *dest) {
return safe_rename(src, dest);
@ -119,9 +133,13 @@ static int copy_file(const char *src, const char *dest)
close(fd1);
/* get perms right on the tmp file */
#ifndef _WIN32
mask = umask(0);
fchmod(fd2, 0666 & ~mask);
umask(mask);
#else
(void)mask;
#endif
/* the close can fail on NFS if out of space */
if (close(fd2) == -1) {
@ -333,7 +351,11 @@ int commit_to_cache(const char *src, const char *dest, int hardlink)
int ret = -1;
unlink(dest);
if (hardlink) {
#ifdef _WIN32
ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
#else
ret = link(src, dest);
#endif
}
if (ret == -1) {
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);
/* only make a hardlink if the cache file is uncompressed */
if (hardlink && test_if_compressed(src) == 0) {
#ifdef _WIN32
ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
#else
ret = link(src, dest);
#endif
} else {
ret = copy_file_from_cache(src, dest);
}
@ -393,9 +419,15 @@ int create_dir(const char *dir)
errno = ENOTDIR;
return 1;
}
#ifdef _WIN32
if (mkdir(dir) != 0 && errno != EEXIST) {
return 1;
}
#else
if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
return 1;
}
#endif
return 0;
}
@ -526,7 +558,12 @@ void traverse(const char *dir, void (*fn)(const char *, struct stat *))
if (strlen(de->d_name) == 0) continue;
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) {
perror(fname);
}
@ -551,8 +588,16 @@ char *str_basename(const char *s)
{
char *p = strrchr(s, '/');
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);
}
@ -563,6 +608,9 @@ char *dirname(char *s)
char *p;
s = x_strdup(s);
p = strrchr(s, '/');
#ifdef _WIN32
p = strrchr(s, '\\');
#endif
if (p) {
*p = 0;
}
@ -571,6 +619,7 @@ char *dirname(char *s)
int lock_fd(int fd)
{
#ifndef _WIN32
struct flock fl;
int ret;
@ -586,17 +635,26 @@ int lock_fd(int fd)
ret = fcntl(fd, F_SETLKW, &fl);
} while (ret == -1 && errno == EINTR);
return ret;
#else
(void)fd;
#warning "missing implementation???"
return 0;
#endif
}
/* return size on disk of a file */
size_t file_size(struct stat *st)
{
#ifdef _WIN32
return (st->st_size + 1023) & ~1023;
#else
size_t size = st->st_blocks * 512;
if ((size_t)st->st_size > size) {
/* probably a broken stat() call ... */
size = (st->st_size + 1023) & ~1023;
}
return size;
#endif
}
@ -658,6 +716,17 @@ size_t value_units(const char *s)
*/
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;
char *ret, *p;
#ifdef PATH_MAX
@ -693,6 +762,7 @@ char *x_realpath(const char *path)
}
free(ret);
return NULL;
#endif
}
/* 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 */
int create_empty_file(const char *fname)
{
@ -741,6 +801,24 @@ int create_empty_file(const char *fname)
*/
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");
if (p) {
return p;
@ -753,8 +831,9 @@ const char *get_home_directory(void)
}
}
#endif
cc_log("Unable to determine home directory");
fatal("Unable to determine home directory");
return NULL;
#endif
}
int x_utimes(const char *filename)