time_t t;
struct tm *tm;
int put_object_in_manifest = 0;
+ struct file_hash *object_hash_from_manifest = NULL;
t = time(NULL);
tm = localtime(&t);
* so don't readd it later.
*/
put_object_in_manifest = 0;
+
+ object_hash_from_manifest = object_hash;
+ object_hash = NULL;
} else {
/* Add object to manifest later. */
put_object_in_manifest = 1;
*/
find_hash(stripped_args, FINDHASH_CPP_MODE);
+ if (object_hash_from_manifest
+ && !file_hashes_equal(object_hash_from_manifest, object_hash)) {
+ /*
+ * The hash from manifest differs from the hash of the
+ * preprocessor output. This could be because:
+ *
+ * - The preprocessor produces different output for the same
+ * input (not likely).
+ * - There's a bug in ccache (maybe incorrect handling of
+ * compiler arguments).
+ * - The user has used a different CCACHE_BASEDIR (most
+ * likely).
+ *
+ * The best thing here would probably be to remove the hash
+ * entry from the manifest. For now, we use a simpler method:
+ * just remove the manifest file.
+ */
+ cc_log("Hash from manifest doesn't match preprocessor output\n");
+ cc_log("Likely reason: different CCACHE_BASEDIRs used\n");
+ cc_log("Removing manifest as a safety measure\n");
+ unlink(manifest_path);
+
+ put_object_in_manifest = 1;
+ }
+
/* if we can return from cache at this point then do */
from_cache(FROMCACHE_CPP_MODE, put_object_in_manifest);
{
return strcmp((const char *)str1, (const char *)str2) == 0;
}
+
+int file_hashes_equal(struct file_hash *fh1, struct file_hash *fh2)
+{
+ return memcmp(fh1->hash, fh2->hash, 16) == 0
+ && fh1->size == fh2->size;
+}
#ifndef HASHUTIL_H
#define HASHUTIL_H
+#include <inttypes.h>
+
+struct file_hash
+{
+ uint8_t hash[16];
+ uint32_t size;
+};
+
unsigned int hash_from_string(void *str);
int strings_equal(void *str1, void *str2);
+int file_hashes_equal(struct file_hash *fh1, struct file_hash *fh2);
#endif
#ifndef MANIFEST_H
#define MANIFEST_H
-#include <inttypes.h>
+#include "hashutil.h"
#include "hashtable.h"
-struct file_hash
-{
- uint8_t hash[16];
- uint32_t size;
-};
-
struct file_hash *manifest_get(const char *manifest_path);
int manifest_put(const char *manifest_path, struct file_hash *object_hash,
struct hashtable *included_files);