diff --git a/CCache/Makefile.in b/CCache/Makefile.in index b4d201208..32e8db101 100644 --- a/CCache/Makefile.in +++ b/CCache/Makefile.in @@ -8,6 +8,8 @@ bindir=@bindir@ mandir=@mandir@ INSTALLCMD=@INSTALL@ PACKAGE_NAME=@PACKAGE_NAME@ +# Soft link test can be skipped on systems that don't support soft linking +NOSOFTLINKSTEST= CC=@CC@ CFLAGS=@CFLAGS@ -I. @@ -56,7 +58,7 @@ clean-docs: check : test test: test.sh - SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' ./test.sh + SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' ./test.sh check: test diff --git a/CCache/ccache.c b/CCache/ccache.c index 1706fe38d..ce9717b84 100644 --- a/CCache/ccache.c +++ b/CCache/ccache.c @@ -136,10 +136,40 @@ static void failed(void) putenv("CCACHE_OUTFILES"); } +#ifndef _WIN32 execv(orig_args->argv[0], orig_args->argv); cc_log("execv returned (%s)!\n", strerror(errno)); perror(orig_args->argv[0]); exit(1); +#else + /* execv on Windows causes the 'non-regular' testcase to fail, so use Win32 API instead */ + { + PROCESS_INFORMATION pinfo; + STARTUPINFO sinfo; + BOOL ret; + DWORD exitcode; + char *args; + + ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION)); + ZeroMemory(&sinfo, sizeof(STARTUPINFO)); + sinfo.cb = sizeof(STARTUPINFO); + args = argvtos(orig_args->argv); + ret = CreateProcessA(orig_args->argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL, + &sinfo, &pinfo); + if (!ret) { + exitcode = 1; + cc_log("CreateProcessA failed starting %s\n", orig_args->argv[0]); + perror_win32(orig_args->argv[0]); + } else { + WaitForSingleObject(pinfo.hProcess, INFINITE); + GetExitCodeProcess(pinfo.hProcess, &exitcode); + CloseHandle(pinfo.hProcess); + CloseHandle(pinfo.hThread); + } + free(args); + exit(exitcode); + } +#endif } diff --git a/CCache/ccache.h b/CCache/ccache.h index d34588586..4b4776dd2 100644 --- a/CCache/ccache.h +++ b/CCache/ccache.h @@ -130,6 +130,9 @@ char *gnu_getcwd(void); int create_empty_file(const char *fname); const char *get_home_directory(void); int x_utimes(const char *filename); +#ifdef _WIN32 +void perror_win32(LPTSTR pszFunction); +#endif void stats_update(enum stats stat); void stats_zero(void); @@ -158,6 +161,9 @@ void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize); void cleanup_all(const char *dir); void wipe_all(const char *dir); +#ifdef _WIN32 +char *argvtos(char **argv); +#endif int execute(char **argv, const char *path_stdout, const char *path_stderr); diff --git a/CCache/execute.c b/CCache/execute.c index be6beef69..d7d031d83 100644 --- a/CCache/execute.c +++ b/CCache/execute.c @@ -19,7 +19,7 @@ #include "ccache.h" #ifdef _WIN32 -static char *argvtos(char **argv) +char *argvtos(char **argv) { int i, len; char *ptr, *str; diff --git a/CCache/test.sh b/CCache/test.sh index 051cff92b..2720462ba 100755 --- a/CCache/test.sh +++ b/CCache/test.sh @@ -65,6 +65,7 @@ checkstat() { stat="$1" expected_value="$2" value=`getstat "$stat"` +# echo "exp: $expected_value got: $value $testname" if [ "$expected_value" != "$value" ]; then test_failed "SUITE: $testsuite TEST: $testname - Expected $stat to be $expected_value got $value" fi @@ -393,15 +394,19 @@ basetests CCACHE_COMPILE="$CCACHE $SWIG" swigtests -testsuite="link" -ln -s $CCACHE $COMPILER -CCACHE_COMPILE="./$COMPILER" -basetests -rm "./$COMPILER" -ln -s $CCACHE $SWIG -CCACHE_COMPILE="./$SWIG" -swigtests -rm "./$SWIG" +if test -z "$NOSOFTLINKSTEST"; then + testsuite="link" + ln -s $CCACHE $COMPILER + CCACHE_COMPILE="./$COMPILER" + basetests + rm "./$COMPILER" + ln -s $CCACHE $SWIG + CCACHE_COMPILE="./$SWIG" + swigtests + rm "./$SWIG" +else + echo "skipping testsuite link" +fi testsuite="hardlink" CCACHE_COMPILE="env CCACHE_NOCOMPRESS=1 CCACHE_HARDLINK=1 $CCACHE $COMPILER" diff --git a/CCache/unify.c b/CCache/unify.c index 758756ddd..a93d48a02 100644 --- a/CCache/unify.c +++ b/CCache/unify.c @@ -241,31 +241,34 @@ int unify_hash(const char *fname) #ifdef _WIN32 HANDLE file; HANDLE section; - MEMORY_BASIC_INFORMATION minfo; + DWORD filesize_low; char *map; + int ret = -1; file = CreateFileA(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if (file == INVALID_HANDLE_VALUE) - return -1; + if (file != INVALID_HANDLE_VALUE) { + filesize_low = GetFileSize(file, NULL); + if (!(filesize_low == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)) { + section = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL); + CloseHandle(file); + if (section != NULL) { + map = MapViewOfFile(section, FILE_MAP_READ, 0, 0, 0); + CloseHandle(section); + if (map != NULL) + ret = 0; + } + } + } - section = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL); - CloseHandle(file); - if (section == NULL) + if (ret == -1) { + cc_log("Failed to open preprocessor output %s\n", fname); + stats_update(STATS_PREPROCESSOR); 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); + unify((unsigned char *)map, filesize_low); UnmapViewOfFile(map); @@ -288,6 +291,7 @@ int unify_hash(const char *fname) map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (map == (char *)-1) { cc_log("Failed to mmap %s\n", fname); + stats_update(STATS_PREPROCESSOR); return -1; } close(fd); diff --git a/CCache/util.c b/CCache/util.c index cdb654d5d..fdd832446 100644 --- a/CCache/util.c +++ b/CCache/util.c @@ -845,3 +845,23 @@ int x_utimes(const char *filename) #endif } +#ifdef _WIN32 +/* perror for Win32 API calls, using GetLastError() instead of errno */ +void perror_win32(LPTSTR pszFunction) +{ + LPTSTR pszMessage; + DWORD dwLastError = GetLastError(); + + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwLastError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&pszMessage, + 0, NULL ); + + fprintf(stderr, "%s: %s\n", pszFunction, pszMessage); + LocalFree(pszMessage); +} +#endif