*read_only* (*CCACHE_READONLY* or *CCACHE_NOREADONLY*, see <<_boolean_values,Boolean values>> above)::
If true, ccache will attempt to use existing cached object files, but it
- will not to try to add anything new to the cache. If you are using this
- because your ccache directory is read-only, then you need to set
- *temporary_dir* as otherwise ccache will fail to create temporary files.
+ will not add new results to the cache. Statistics counters will still be
+ updated, though, unless the *stats* option is set to *false*.
++
+If you are using this because your ccache directory is read-only, you need to
+set *temporary_dir* since ccache will fail to create temporary files otherwise.
+You may also want to set *stats = false* to make ccache not even try to update
+stats files.
*read_only_direct* (*CCACHE_READONLY_DIRECT* or *CCACHE_NOREADONLY_DIRECT*, see <<_boolean_values,Boolean values>> above)::
if (!current_working_dir) {
cc_log("Unable to determine current working directory: %s",
strerror(errno));
+ stats_update(STATS_ERROR);
failed();
}
}
if (x_rename(tmp_stderr, tmp_stderr2)) {
cc_log("Failed to rename %s to %s: %s", tmp_stderr, tmp_stderr2,
strerror(errno));
+ stats_update(STATS_ERROR);
failed();
}
int fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
if (fd_cpp_stderr == -1) {
cc_log("Failed opening %s: %s", cpp_stderr, strerror(errno));
+ stats_update(STATS_ERROR);
failed();
}
int fd_real_stderr = open(tmp_stderr2, O_RDONLY | O_BINARY);
if (fd_real_stderr == -1) {
cc_log("Failed opening %s: %s", tmp_stderr2, strerror(errno));
+ stats_update(STATS_ERROR);
failed();
}
open(tmp_stderr, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
if (fd_result == -1) {
cc_log("Failed opening %s: %s", tmp_stderr, strerror(errno));
+ stats_update(STATS_ERROR);
failed();
}
struct file_hash *object_hash =
object_hash_from_depfile(output_dep, depend_mode_hash);
if (!object_hash) {
+ stats_update(STATS_ERROR);
failed();
}
update_cached_result_globals(object_hash);
MTR_END("file", "file_put");
- stats_update(STATS_TOCACHE);
+ stats_update(STATS_CACHEMISS);
// Make sure we have a CACHEDIR.TAG in the cache part of cache_dir. This can
// be done almost anywhere, but we might as well do it near the end as we
hash_delimiter(hash, "sourcecode");
int result = hash_source_code_file(conf, hash, input_file);
if (result & HASH_SOURCE_CODE_ERROR) {
+ stats_update(STATS_ERROR);
failed();
}
if (result & HASH_SOURCE_CODE_FOUND_TIME) {
i++;
if (i == argc) {
cc_log("--ccache-skip lacks an argument");
+ stats_update(STATS_ARGS);
result = false;
goto out;
}
// know what the user means, and what the compiler will do.
if (arg_profile_dir && profile_dir) {
cc_log("Profile directory already set; giving up");
+ stats_update(STATS_UNSUPPORTED_OPTION);
result = false;
goto out;
} else if (arg_profile_dir) {
int uncached_fd = dup(2); // The file descriptor is intentionally leaked.
if (uncached_fd == -1) {
cc_log("dup(2) failed: %s", strerror(errno));
+ stats_update(STATS_ERROR);
failed();
}
char *buf = format("UNCACHED_ERR_FD=%d", uncached_fd);
if (putenv(buf) == -1) {
cc_log("putenv failed: %s", strerror(errno));
+ stats_update(STATS_ERROR);
failed();
}
}
if (conf->disable) {
cc_log("ccache is disabled");
+ stats_update(STATS_CACHEMISS); // Dummy to trigger stats_flush.
failed();
}
MTR_BEGIN("main", "process_args");
if (!cc_process_args(
orig_args, &preprocessor_args, &extra_args_to_hash, &compiler_args)) {
- failed();
+ failed(); // stats_update is called in cc_process_args.
}
MTR_END("main", "process_args");
if (conf->read_only_direct) {
cc_log("Read-only direct mode; running real compiler");
+ stats_update(STATS_CACHEMISS);
failed();
}
if (conf->read_only) {
cc_log("Read-only mode; running real compiler");
+ stats_update(STATS_CACHEMISS);
failed();
}
// Copyright (C) 2002-2004 Andrew Tridgell
-// Copyright (C) 2009-2019 Joel Rosdahl
+// Copyright (C) 2009-2020 Joel Rosdahl
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
FLAG_ALWAYS
},
{
- STATS_TOCACHE,
+ STATS_CACHEMISS,
"cache_miss",
"cache miss",
NULL,
unsigned direct = counters->data[STATS_CACHEHIT_DIR];
unsigned preprocessed = counters->data[STATS_CACHEHIT_CPP];
unsigned hit = direct + preprocessed;
- unsigned miss = counters->data[STATS_TOCACHE];
+ unsigned miss = counters->data[STATS_CACHEMISS];
unsigned total = hit + miss;
return total > 0 ? (100.0 * hit) / total : 0.0;
}
{
assert(conf);
- if (!conf->stats) {
+ if (!updates) {
return;
}
- if (!updates) {
+ if (conf->disable) {
+ // Just log result, don't update statistics.
+ cc_log("Result: disabled");
+ return;
+ }
+
+ if (!str_eq(conf->log_file, "") || conf->debug) {
+ for (int i = 0; i < STATS_END; ++i) {
+ if (updates->data[stats_info[i].stat] != 0
+ && !(stats_info[i].flags & FLAG_NOZERO)) {
+ cc_log("Result: %s", stats_info[i].message);
+ }
+ }
+ }
+
+ if (!conf->stats) {
return;
}
stats_write(sfile, counters);
lockfile_release(sfile);
- if (!str_eq(conf->log_file, "") || conf->debug) {
- for (int i = 0; i < STATS_END; ++i) {
- if (updates->data[stats_info[i].stat] != 0
- && !(stats_info[i].flags & FLAG_NOZERO)) {
- cc_log("Result: %s", stats_info[i].message);
- }
- }
- }
-
char *subdir = dirname(sfile);
bool need_cleanup = false;
free(value);
}
- if (stat == STATS_TOCACHE) {
+ if (stat == STATS_CACHEMISS) {
double percent = stats_hit_rate(counters);
printf("cache hit rate %6.2f %%\n", percent);
}