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:
parent
4b79eb9219
commit
5964f3e27d
5 changed files with 255 additions and 30 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
131
CCache/util.c
131
CCache/util.c
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue