From: Andrew Tridgell Date: Tue, 26 Mar 2002 22:25:14 +0000 (+0100) Subject: ccache is now pretty well ready for use X-Git-Tag: v1.0~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11628d7f7bd4f5f134e95877d835ae6fa68b8a6f;p=thirdparty%2Fccache.git ccache is now pretty well ready for use --- diff --git a/ccache.c b/ccache.c index a4a1010b1..d0ed0193b 100644 --- a/ccache.c +++ b/ccache.c @@ -57,7 +57,7 @@ static void stabs_hash(const char *fname) { FILE *f; char *s; - char line[1024]; + static char line[102400]; line[sizeof(line)-2] = 0; @@ -93,6 +93,7 @@ static void find_hash(ARGS *args) char *path_stdout, *path_stderr, *path_status; char *hash_dir; char *s; + struct stat st; hash_start(); @@ -101,6 +102,15 @@ static void find_hash(ARGS *args) hash_string(args->argv[i]); } + /* the compiler driver size and date. This is a simple minded way + to try and detect compiler upgrades. It is not 100% reliable */ + if (stat(args->argv[0], &st) != 0) { + cc_log("Couldn't stat the compiler!?\n"); + failed(); + } + hash_int(st.st_size); + hash_int(st.st_mtime); + /* now the run */ x_asprintf(&path_stdout, "%s/tmp.stdout.%d", cache_dir, getpid()); x_asprintf(&path_stderr, "%s/tmp.stderr.%d", cache_dir, getpid()); @@ -110,6 +120,11 @@ static void find_hash(ARGS *args) execute(args->argv, path_stdout, path_stderr, path_status); args->argc--; + /* if the compilation is with -g then we have to inlcude the whole of the + preprocessor output, which means we are sensitive to line number + information. Otherwise we can discard line number info, which makes + us less sensitive to reformatting changes + */ if (found_debug) { hash_file(path_stdout); } else { @@ -127,7 +142,10 @@ static void find_hash(ARGS *args) s = hash_result(); x_asprintf(&hash_dir, "%s/%c", cache_dir, *s); - mkdir(hash_dir, 0755); + if (create_dir(hash_dir) != 0) { + cc_log("failed to create %s\n", cache_dir); + failed(); + } x_asprintf(&hashname, "%s/%s", hash_dir, s+1); free(hash_dir); } @@ -168,9 +186,10 @@ static void from_cache(int first) unlink(output_file); ret = link(hashname, output_file); if (ret == -1 && errno != ENOENT) { - /* copy it instead */ - cc_log("copy not implemented\n"); - failed(); + ret = symlink(hashname, output_file); + } + if (ret == 0) { + utime(output_file, NULL); } /* send the stderr */ @@ -217,8 +236,14 @@ static char *find_compiler(const char *argv0) base = argv0; } - path = getenv("PATH"); - if (!path) return NULL; + path = getenv("CCACHE_PATH"); + if (!path) { + path = getenv("PATH"); + } + if (!path) { + cc_log("no PATH variable!?\n"); + failed(); + } path = x_strdup(path); @@ -380,8 +405,8 @@ static void ccache(int argc, char *argv[]) int main(int argc, char *argv[]) { - if (mkdir(cache_dir, 0755) != 0 && errno != EEXIST) { - fprintf(stderr,"Failed to create %s (%s)\n", + if (create_dir(cache_dir) != 0) { + fprintf(stderr,"ccache: failed to create %s (%s)\n", cache_dir, strerror(errno)); exit(1); } diff --git a/ccache.h b/ccache.h index 6c633312c..093e11bea 100644 --- a/ccache.h +++ b/ccache.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #define STATUS_NOTFOUND 3 @@ -27,6 +28,7 @@ typedef unsigned uint32; void hash_start(void); void hash_string(const char *s); +void hash_int(int x); void hash_file(const char *fname); char *hash_result(void); @@ -36,6 +38,8 @@ void oom(const char *msg); void copy_fd(int fd_in, int fd_out); +int create_dir(const char *dir); + void execute(char **argv, const char *path_stdout, const char *path_stderr, diff --git a/hash.c b/hash.c index 125945ff4..ebcd8a7eb 100644 --- a/hash.c +++ b/hash.c @@ -18,6 +18,11 @@ void hash_string(const char *s) mdfour_update(&md, s, strlen(s)); } +void hash_int(int x) +{ + mdfour_update(&md, (unsigned char *)&x, sizeof(x)); +} + /* add contents of a file to the hash */ void hash_file(const char *fname) { diff --git a/util.c b/util.c index 52cdd0120..98f48617a 100644 --- a/util.c +++ b/util.c @@ -41,3 +41,19 @@ void oom(const char *msg) cc_log("Out of memory: %s\n", msg); exit(1); } + +int create_dir(const char *dir) +{ + struct stat st; + if (stat(dir, &st) == 0) { + if (S_ISDIR(st.st_mode)) { + return 0; + } + errno = ENOTDIR; + return 1; + } + if (mkdir(dir, 0777) != 0) { + return 1; + } + return 0; +}