compiled, but that sometimes doesn't work. For example, when using the
``aCC'' compiler on HP-UX, set the cpp extension to *i*.
+ *debug* (*CCACHE_DEBUG* or *CCACHE_NODEBUG*, see <<_boolean_values,Boolean values>> above)::
+
+ If true, enable the debug mode. The debug mode creates per-object debug
+ files that are helpful when debugging unexpected cache misses. Note however
+ that ccache performance will be reduced slightly. See
+ <<_cache_debugging_,debugging>> for more information. The default is false.
+
+*depend_mode* (*CCACHE_DEPEND* or *CCACHE_NODEPEND*, see <<_boolean_values,Boolean values>> above)::
+
+ If true, the depend mode will be used. The default is false. See
+ <<_the_depend_mode,THE DEPEND MODE>>.
+
*direct_mode* (*CCACHE_DIRECT* or *CCACHE_NODIRECT*, see <<_boolean_values,Boolean values>> above)::
If true, the direct mode will be used. The default is true. See
Based on the hash, the cached compilation result can be looked up directly in
the cache.
+The depend mode
+~~~~~~~~~~~~~~~
+
+In the depend mode, the hash is formed of the common information and:
+
+* make dependencies, as generated by the compiler with *-MD* or *-MMD*
+
+When using *run_second_cpp* (which is the default now), ccache executes
+the preprocessor just to determine the object hash, and will do so for
+every cache miss. While compiling, the same work is done again.
+
+When executing a massively parallel build using ccache and distcc,
+the system controlling the build can get a fairly high load because of
+all these ccache-only preprocessor executions.
+
+Having only hashed compiler flags and per file checksums as in direct mode
+might be just enough for practical caching purposes.
+
+The dependencies also allows doing correct incremental builds, by allowing
+the build system to check if dependencies are up-to-date.
+
+The depend mode will be disabled if any of the following holds:
+
+* the configuration setting *depend_mode* is false
+* the compiler is not generating dependencies
+* the configuration setting *run_second_cpp* is false
+ Cache debugging
+ ---------------
+
+ To find out what information ccache actually is hashing, you can enable the
+ debug mode via the configuration setting *debug* or by setting *CCACHE_DEBUG*
+ in the environment. This can be useful if you are investigating why you don't
+ get cache hits. Note that performance will be reduced slightly.
+
+ When the debug mode is enabled, ccache will create up to five additional files
+ next to the object file:
+
+ [options="header",cols="30%,70%"]
+ |==============================================================================
+ |Filename | Description
+ | *<objectfile>.ccache-input-c* |
+ Binary input hashed by both the direct mode and the preprocessor mode.
+
+ | *<objectfile>.ccache-input-d* |
+ Binary input only hashed by the direct mode.
+
+ | *<objectfile>.ccache-input-p* |
+ Binary input only hashed by the preprocessor mode.
+
+ | *<objectfile>.ccache-input-text* |
+ Human-readable combined diffable text version of the three files above.
+
+ | *<objectfile>.ccache-log* |
+ Log for this object file.
+
+ |==============================================================================
+
+ In the direct mode, ccache uses the MD4 hash of the *ccache-input-c*
+ + *ccache-input-d* data (where *+* means concatenation), while the
+ *ccache-input-c* + *ccache-input-p* data is used in the preprocessor mode.
+
+ The *ccache-input-text* file is a combined text version of the three
+ binary input files. It has three sections (“COMMON”, “DIRECT MODE” and
+ “PREPROCESSOR MODE”), which is turn contain annotations that say what kind of
+ data comes next.
+
+ To debug why you don’t get an expected cache hit for an object file, you can do
+ something like this:
+
+ 1. Build with debug mode enabled.
+ 2. Save the *<objectfile>.ccache-** files.
+ 3. Build again with debug mode enabled.
+ 4. Compare *<objectfile>.ccache-input-text* for the two builds. This together
+ with the *<objectfile>.ccache-log* files should give you some clues about
+ what is happening.
+
+
Compiling in different directories
----------------------------------
// global included_files variable. If the include file is a PCH, cpp_hash is
// also updated. Takes over ownership of path.
static void
- remember_include_file(char *path, struct mdfour *cpp_hash, bool system,
- struct mdfour *depend_mode_hash)
-remember_include_file(char *path, struct hash *cpp_hash, bool system)
++remember_include_file(char *path, struct hash *cpp_hash, bool system,
++ struct hash *depend_mode_hash)
{
+ struct hash *fhash = NULL;
+
size_t path_len = strlen(path);
if (path_len >= 2 && (path[0] == '<' && path[path_len - 1] == '>')) {
// Typically <built-in> or <command-line>.
}
struct file_hash *h = x_malloc(sizeof(*h));
- hash_result_as_bytes(&fhash, h->hash);
- h->size = fhash.totalN;
+ hash_result_as_bytes(fhash, h->hash);
+ h->size = hash_input_size(fhash);
hashtable_insert(included_files, path, h);
- } else {
- free(path);
+ path = NULL; // Ownership transferred to included_files.
+
+ if (depend_mode_hash) {
+ hash_delimiter(depend_mode_hash, "include");
+ hash_buffer(depend_mode_hash, h->hash, sizeof(h->hash));
+ }
}
- return;
+ goto out;
failure:
if (conf->direct_mode) {
}
}
if (should_hash_inc_path) {
- hash_string(hash, inc_path);
+ hash_string_buffer(hash, inc_path, strlen(inc_path));
}
- remember_include_file(inc_path, hash, system);
+ remember_include_file(inc_path, hash, system, NULL);
p = q; // Everything of interest between p and q has been hashed now.
} else if (q[0] == '.' && q[1] == 'i' && q[2] == 'n' && q[3] == 'c'
&& q[4] == 'b' && q[5] == 'i' && q[6] == 'n') {
// Explicitly check the .gch/.pch/.pth file, Clang does not include any
// mention of it in the preprocessed output.
if (included_pch_file) {
- char *path = x_strdup(included_pch_file);
- path = make_relative_path(path);
- hash_string(hash, path);
- remember_include_file(path, hash, false, NULL);
+ char *pch_path = x_strdup(included_pch_file);
+ pch_path = make_relative_path(pch_path);
+ hash_string(hash, pch_path);
- remember_include_file(pch_path, hash, false);
++ remember_include_file(pch_path, hash, false, NULL);
+ }
+
+ bool debug_included = getenv("CCACHE_DEBUG_INCLUDED");
+ if (debug_included) {
+ print_included_files(stdout);
}
return true;
free(tmp_file);
}
- object_hash_from_depfile(const char *depfile, struct mdfour *hash) {
+// extract the used includes from the dependency file
+// note we cannot distinguish system headers from other includes here
+static struct file_hash *
- result->size = hash->totalN;
++object_hash_from_depfile(const char *depfile, struct hash *hash) {
+ FILE *f;
+ f = fopen(depfile, "r");
+ if (!f) {
+ cc_log("Cannot open dependency file: %s (%s)", depfile, strerror(errno));
+ return NULL;
+ }
+
+ if (!included_files) {
+ included_files = create_hashtable(1000, hash_from_string, strings_equal);
+ }
+
+ char buf[10000];
+ while (fgets(buf, sizeof(buf), f) && !ferror(f)) {
+ char *saveptr;
+ char *token;
+ for (token = strtok_r(buf, " \t\n", &saveptr);
+ token;
+ token = strtok_r(NULL, " \t\n", &saveptr)) {
+ if (str_endswith(token, ":") || str_eq(token, "\\")) {
+ continue;
+ }
+ remember_include_file(x_strdup(token), hash, false, hash);
+ }
+ }
+
+ bool debug_included = getenv("CCACHE_DEBUG_INCLUDED");
+ if (debug_included) {
+ print_included_files(stdout);
+ }
+
+ struct file_hash *result = x_malloc(sizeof(*result));
+ hash_result_as_bytes(hash, result->hash);
++ result->size = hash_input_size(hash);
+ return result;
+}
+
// Helper method for copy_file_to_cache and move_file_to_cache_same_fs.
static void
do_copy_or_move_file_to_cache(const char *source, const char *dest, bool copy)
}
}
-// Run the real compiler and put the result in cache.
static void
-to_cache(struct args *args)
+update_cached_result_globals(struct file_hash *hash)
{
- char *tmp_stdout = format("%s.tmp.stdout", cached_obj);
- int tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
- char *tmp_stderr = format("%s.tmp.stderr", cached_obj);
- int tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
+ char *object_name = format_hash_as_string(hash->hash, hash->size);
+ cached_obj_hash = hash;
+ cached_obj = get_path_in_cache(object_name, ".o");
+ cached_stderr = get_path_in_cache(object_name, ".stderr");
+ cached_dep = get_path_in_cache(object_name, ".d");
+ cached_cov = get_path_in_cache(object_name, ".gcno");
+ cached_su = get_path_in_cache(object_name, ".su");
+ cached_dia = get_path_in_cache(object_name, ".dia");
+ cached_dwo = get_path_in_cache(object_name, ".dwo");
+
+ stats_file = format("%s/%c/stats", conf->cache_dir, object_name[0]);
+ free(object_name);
+}
- to_cache(struct args *args, struct mdfour *depend_mode_hash)
+// Run the real compiler and put the result in cache.
+static void
++to_cache(struct args *args, struct hash *depend_mode_hash)
+{
args_add(args, "-o");
args_add(args, output_obj);
}
cc_log("Running real compiler");
- int status =
- execute(args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
- args_pop(args, 3);
+ char *tmp_stdout;
+ int tmp_stdout_fd;
+ char *tmp_stderr;
+ int tmp_stderr_fd;
+ int status;
+ if (!conf->depend_mode) {
+ tmp_stdout = format("%s.tmp.stdout", cached_obj);
+ tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
+ tmp_stderr = format("%s.tmp.stderr", cached_obj);
+ tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
+
+ status = execute(args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
+ args_pop(args, 3);
+ } else {
+ // The cached object path is not known yet, use temporary files.
+ tmp_stdout = format("%s/tmp.stdout", temp_dir());
+ tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
+ tmp_stderr = format("%s/tmp.stderr", temp_dir());
+ tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
+
+ // Use the original arguments (including deps) in depend mode.
+ // Similar to failed();
+ // FIXME: on error we probably do not want to fall back to failed() anymore
+ assert(orig_args);
+ struct args *depend_mode_args = args_copy(orig_args);
+ args_strip(depend_mode_args, "--ccache-");
+ add_prefix(depend_mode_args, conf->prefix_command);
+
+ time_of_compilation = time(NULL);
- status = execute(depend_mode_args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
++ status = execute(
++ depend_mode_args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
+ }
struct stat st;
if (x_stat(tmp_stdout, &st) != 0) {
failed();
}
- // Find the hash using the preprocessed output. Also updates included_files.
- struct hash *cpp_hash = hash_copy(common_hash);
- init_hash_debug(
+ if (!conf->depend_mode) {
+ // Find the hash using the preprocessed output. Also updates included_files.
- struct mdfour cpp_hash = common_hash;
- object_hash = calculate_object_hash(preprocessor_args, &cpp_hash, 0);
++ struct hash *cpp_hash = hash_copy(common_hash);
++ init_hash_debug(
+ cpp_hash, output_obj, 'p', "PREPROCESSOR MODE", debug_text_file);
+
+ object_hash = calculate_object_hash(preprocessor_args, cpp_hash, 0);
- if (!object_hash) {
- fatal("internal error: object hash from cpp returned NULL");
- }
- update_cached_result_globals(object_hash);
+ if (!object_hash) {
+ fatal("internal error: object hash from cpp returned NULL");
+ }
+ update_cached_result_globals(object_hash);
+
+ 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");
+ cc_log("Likely reason: different CCACHE_BASEDIRs used");
+ cc_log("Removing manifest as a safety measure");
+ x_unlink(manifest_path);
- 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");
- cc_log("Likely reason: different CCACHE_BASEDIRs used");
- cc_log("Removing manifest as a safety measure");
- x_unlink(manifest_path);
+ put_object_in_manifest = true;
+ }
- put_object_in_manifest = true;
+ // If we can return from cache at this point then do.
+ from_cache(FROMCACHE_CPP_MODE, put_object_in_manifest);
}
- // If we can return from cache at this point then do.
- from_cache(FROMCACHE_CPP_MODE, put_object_in_manifest);
-
if (conf->read_only) {
cc_log("Read-only mode; running real compiler");
failed();
add_prefix(compiler_args, conf->prefix_command);
- // in depend_mode, extend the direct hash
- struct mdfour * depend_mode_hash = conf->depend_mode ? &direct_hash : NULL;
++ // In depend_mode, extend the direct hash.
++ struct hash *depend_mode_hash = conf->depend_mode ? direct_hash : NULL;
+
// Run real compiler, sending output to cache.
- to_cache(compiler_args);
+ to_cache(compiler_args, depend_mode_hash);
x_exit(0);
}
--// Copyright (C) 2011-2018 Joel Rosdahl
++// Copyright (C) 2011-2019 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
conf->compression = false;
conf->compression_level = 6;
conf->cpp_extension = x_strdup("");
+ conf->debug = false;
+ conf->depend_mode = false;
conf->direct_mode = true;
conf->disable = false;
conf->extra_files_to_hash = x_strdup("");
}
bool
- conf_print_items(struct conf *conf,
- void (*printer)(const char *descr, const char *origin,
- void *context),
- void *context)
+ conf_print_value(struct conf *conf, const char *key,
+ FILE *file, char **errmsg)
{
- char *s = x_strdup("");
-
- reformat(&s, "base_dir = %s", conf->base_dir);
- printer(s, conf->item_origins[find_conf("base_dir")->number], context);
-
- reformat(&s, "cache_dir = %s", conf->cache_dir);
- printer(s, conf->item_origins[find_conf("cache_dir")->number], context);
-
- reformat(&s, "cache_dir_levels = %u", conf->cache_dir_levels);
- printer(s, conf->item_origins[find_conf("cache_dir_levels")->number],
- context);
-
- reformat(&s, "compiler = %s", conf->compiler);
- printer(s, conf->item_origins[find_conf("compiler")->number], context);
-
- reformat(&s, "compiler_check = %s", conf->compiler_check);
- printer(s, conf->item_origins[find_conf("compiler_check")->number], context);
-
- reformat(&s, "compression = %s", bool_to_string(conf->compression));
- printer(s, conf->item_origins[find_conf("compression")->number], context);
-
- reformat(&s, "compression_level = %u", conf->compression_level);
- printer(s, conf->item_origins[find_conf("compression_level")->number],
- context);
-
- reformat(&s, "cpp_extension = %s", conf->cpp_extension);
- printer(s, conf->item_origins[find_conf("cpp_extension")->number], context);
-
- reformat(&s, "depend_mode = %s", bool_to_string(conf->depend_mode));
- printer(s, conf->item_origins[find_conf("depend_mode")->number], context);
-
- reformat(&s, "direct_mode = %s", bool_to_string(conf->direct_mode));
- printer(s, conf->item_origins[find_conf("direct_mode")->number], context);
-
- reformat(&s, "disable = %s", bool_to_string(conf->disable));
- printer(s, conf->item_origins[find_conf("disable")->number], context);
-
- reformat(&s, "extra_files_to_hash = %s", conf->extra_files_to_hash);
- printer(s, conf->item_origins[find_conf("extra_files_to_hash")->number],
- context);
-
- reformat(&s, "hard_link = %s", bool_to_string(conf->hard_link));
- printer(s, conf->item_origins[find_conf("hard_link")->number], context);
-
- reformat(&s, "hash_dir = %s", bool_to_string(conf->hash_dir));
- printer(s, conf->item_origins[find_conf("hash_dir")->number], context);
-
- reformat(&s, "ignore_headers_in_manifest = %s",
- conf->ignore_headers_in_manifest);
- printer(s,
- conf->item_origins[find_conf("ignore_headers_in_manifest")->number],
- context);
-
- reformat(&s, "keep_comments_cpp = %s",
- bool_to_string(conf->keep_comments_cpp));
- printer(s, conf->item_origins[find_conf(
- "keep_comments_cpp")->number], context);
-
- reformat(&s, "limit_multiple = %.1f", (double)conf->limit_multiple);
- printer(s, conf->item_origins[find_conf("limit_multiple")->number], context);
-
- reformat(&s, "log_file = %s", conf->log_file);
- printer(s, conf->item_origins[find_conf("log_file")->number], context);
-
- reformat(&s, "max_files = %u", conf->max_files);
- printer(s, conf->item_origins[find_conf("max_files")->number], context);
-
- char *s2 = format_parsable_size_with_suffix(conf->max_size);
- reformat(&s, "max_size = %s", s2);
- printer(s, conf->item_origins[find_conf("max_size")->number], context);
- free(s2);
-
- reformat(&s, "path = %s", conf->path);
- printer(s, conf->item_origins[find_conf("path")->number], context);
-
- reformat(&s, "pch_external_checksum = %s",
- bool_to_string(conf->pch_external_checksum));
- printer(s, conf->item_origins[find_conf("pch_external_checksum")->number],
- context);
-
- reformat(&s, "prefix_command = %s", conf->prefix_command);
- printer(s, conf->item_origins[find_conf("prefix_command")->number], context);
-
- reformat(&s, "prefix_command_cpp = %s", conf->prefix_command_cpp);
- printer(s, conf->item_origins[find_conf(
- "prefix_command_cpp")->number], context);
-
- reformat(&s, "read_only = %s", bool_to_string(conf->read_only));
- printer(s, conf->item_origins[find_conf("read_only")->number], context);
-
- reformat(&s, "read_only_direct = %s", bool_to_string(conf->read_only_direct));
- printer(s, conf->item_origins[find_conf("read_only_direct")->number],
- context);
-
- reformat(&s, "recache = %s", bool_to_string(conf->recache));
- printer(s, conf->item_origins[find_conf("recache")->number], context);
-
- reformat(&s, "run_second_cpp = %s", bool_to_string(conf->run_second_cpp));
- printer(s, conf->item_origins[find_conf("run_second_cpp")->number], context);
-
- reformat(&s, "sloppiness = ");
- if (conf->sloppiness & SLOPPY_FILE_MACRO) {
- reformat(&s, "%sfile_macro, ", s);
- }
- if (conf->sloppiness & SLOPPY_INCLUDE_FILE_MTIME) {
- reformat(&s, "%sinclude_file_mtime, ", s);
- }
- if (conf->sloppiness & SLOPPY_INCLUDE_FILE_CTIME) {
- reformat(&s, "%sinclude_file_ctime, ", s);
- }
- if (conf->sloppiness & SLOPPY_TIME_MACROS) {
- reformat(&s, "%stime_macros, ", s);
- }
- if (conf->sloppiness & SLOPPY_PCH_DEFINES) {
- reformat(&s, "%spch_defines, ", s);
- }
- if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) {
- reformat(&s, "%sfile_stat_matches, ", s);
- }
- if (conf->sloppiness & SLOPPY_NO_SYSTEM_HEADERS) {
- reformat(&s, "%sno_system_headers, ", s);
- }
- if (conf->sloppiness) {
- // Strip last ", ".
- s[strlen(s) - 2] = '\0';
+ const struct conf_item *item = find_conf(key);
+ if (!item) {
+ *errmsg = format("unknown configuration option \"%s\"", key);
+ return false;
}
- printer(s, conf->item_origins[find_conf("sloppiness")->number], context);
-
- reformat(&s, "stats = %s", bool_to_string(conf->stats));
- printer(s, conf->item_origins[find_conf("stats")->number], context);
-
- reformat(&s, "temporary_dir = %s", conf->temporary_dir);
- printer(s, conf->item_origins[find_conf("temporary_dir")->number], context);
+ void *value = (char *)conf + item->offset;
+ char *str = item->formatter(value);
+ fprintf(file, "%s\n", str);
+ free(str);
+ return true;
+ }
- if (conf->umask == UINT_MAX) {
- reformat(&s, "umask = ");
- } else {
- reformat(&s, "umask = %03o", conf->umask);
+ static bool
+ print_item(struct conf *conf, const char *key,
+ void (*printer)(const char *descr, const char *origin,
+ void *context),
+ void *context)
+ {
+ const struct conf_item *item = find_conf(key);
+ if (!item) {
+ return false;
}
- printer(s, conf->item_origins[find_conf("umask")->number], context);
-
- reformat(&s, "unify = %s", bool_to_string(conf->unify));
- printer(s, conf->item_origins[find_conf("unify")->number], context);
-
- free(s);
+ void *value = (char *)conf + item->offset;
+ char *str = item->formatter(value);
+ char *buf = x_strdup("");
+ reformat(&buf, "%s = %s", key, str);
+ printer(buf, conf->item_origins[item->number], context);
+ free(buf);
+ free(str);
return true;
}
+
+ bool
+ conf_print_items(struct conf *conf,
+ void (*printer)(const char *descr, const char *origin,
+ void *context),
+ void *context)
+ {
+ bool ok = true;
+ ok &= print_item(conf, "base_dir", printer, context);
+ ok &= print_item(conf, "cache_dir", printer, context);
+ ok &= print_item(conf, "cache_dir_levels", printer, context);
+ ok &= print_item(conf, "compiler", printer, context);
+ ok &= print_item(conf, "compiler_check", printer, context);
+ ok &= print_item(conf, "compression", printer, context);
+ ok &= print_item(conf, "compression_level", printer, context);
+ ok &= print_item(conf, "cpp_extension", printer, context);
+ ok &= print_item(conf, "debug", printer, context);
++ ok &= print_item(conf, "depend_mode", printer, context);
+ ok &= print_item(conf, "direct_mode", printer, context);
+ ok &= print_item(conf, "disable", printer, context);
+ ok &= print_item(conf, "extra_files_to_hash", printer, context);
+ ok &= print_item(conf, "hard_link", printer, context);
+ ok &= print_item(conf, "hash_dir", printer, context);
+ ok &= print_item(conf, "ignore_headers_in_manifest", printer, context);
+ ok &= print_item(conf, "keep_comments_cpp", printer, context);
+ ok &= print_item(conf, "limit_multiple", printer, context);
+ ok &= print_item(conf, "log_file", printer, context);
+ ok &= print_item(conf, "max_files", printer, context);
+ ok &= print_item(conf, "max_size", printer, context);
+ ok &= print_item(conf, "path", printer, context);
+ ok &= print_item(conf, "pch_external_checksum", printer, context);
+ ok &= print_item(conf, "prefix_command", printer, context);
+ ok &= print_item(conf, "prefix_command_cpp", printer, context);
+ ok &= print_item(conf, "read_only", printer, context);
+ ok &= print_item(conf, "read_only_direct", printer, context);
+ ok &= print_item(conf, "recache", printer, context);
+ ok &= print_item(conf, "run_second_cpp", printer, context);
+ ok &= print_item(conf, "sloppiness", printer, context);
+ ok &= print_item(conf, "stats", printer, context);
+ ok &= print_item(conf, "temporary_dir", printer, context);
+ ok &= print_item(conf, "umask", printer, context);
+ ok &= print_item(conf, "unify", printer, context);
+ return ok;
+ }
bool compression;
unsigned compression_level;
char *cpp_extension;
+ bool debug;
+ bool depend_mode;
bool direct_mode;
bool disable;
char *extra_files_to_hash;
compression, 5, ITEM(compression, bool)
compression_level, 6, ITEM(compression_level, unsigned)
cpp_extension, 7, ITEM(cpp_extension, string)
- depend_mode, 8, ITEM(depend_mode, bool)
- direct_mode, 9, ITEM(direct_mode, bool)
- disable, 10, ITEM(disable, bool)
- extra_files_to_hash, 11, ITEM(extra_files_to_hash, env_string)
- hard_link, 12, ITEM(hard_link, bool)
- hash_dir, 13, ITEM(hash_dir, bool)
- ignore_headers_in_manifest, 14, ITEM(ignore_headers_in_manifest, env_string)
- keep_comments_cpp, 15, ITEM(keep_comments_cpp, bool)
- limit_multiple, 16, ITEM(limit_multiple, float)
- log_file, 17, ITEM(log_file, env_string)
- max_files, 18, ITEM(max_files, unsigned)
- max_size, 19, ITEM(max_size, size)
- path, 20, ITEM(path, env_string)
- pch_external_checksum, 21, ITEM(pch_external_checksum, bool)
- prefix_command, 22, ITEM(prefix_command, env_string)
- prefix_command_cpp, 23, ITEM(prefix_command_cpp, env_string)
- read_only, 24, ITEM(read_only, bool)
- read_only_direct, 25, ITEM(read_only_direct, bool)
- recache, 26, ITEM(recache, bool)
- run_second_cpp, 27, ITEM(run_second_cpp, bool)
- sloppiness, 28, ITEM(sloppiness, sloppiness)
- stats, 29, ITEM(stats, bool)
- temporary_dir, 30, ITEM(temporary_dir, env_string)
- umask, 31, ITEM(umask, umask)
- unify, 32, ITEM(unify, bool)
+ debug, 8, ITEM(debug, bool)
-direct_mode, 9, ITEM(direct_mode, bool)
-disable, 10, ITEM(disable, bool)
-extra_files_to_hash, 11, ITEM(extra_files_to_hash, env_string)
-hard_link, 12, ITEM(hard_link, bool)
-hash_dir, 13, ITEM(hash_dir, bool)
-ignore_headers_in_manifest, 14, ITEM(ignore_headers_in_manifest, env_string)
-keep_comments_cpp, 15, ITEM(keep_comments_cpp, bool)
-limit_multiple, 16, ITEM(limit_multiple, double)
-log_file, 17, ITEM(log_file, env_string)
-max_files, 18, ITEM(max_files, unsigned)
-max_size, 19, ITEM(max_size, size)
-path, 20, ITEM(path, env_string)
-pch_external_checksum, 21, ITEM(pch_external_checksum, bool)
-prefix_command, 22, ITEM(prefix_command, env_string)
-prefix_command_cpp, 23, ITEM(prefix_command_cpp, env_string)
-read_only, 24, ITEM(read_only, bool)
-read_only_direct, 25, ITEM(read_only_direct, bool)
-recache, 26, ITEM(recache, bool)
-run_second_cpp, 27, ITEM(run_second_cpp, bool)
-sloppiness, 28, ITEM(sloppiness, sloppiness)
-stats, 29, ITEM(stats, bool)
-temporary_dir, 30, ITEM(temporary_dir, env_string)
-umask, 31, ITEM(umask, umask)
-unify, 32, ITEM(unify, bool)
++depend_mode, 9, ITEM(depend_mode, bool)
++direct_mode, 10, ITEM(direct_mode, bool)
++disable, 11, ITEM(disable, bool)
++extra_files_to_hash, 12, ITEM(extra_files_to_hash, env_string)
++hard_link, 13, ITEM(hard_link, bool)
++hash_dir, 14, ITEM(hash_dir, bool)
++ignore_headers_in_manifest, 15, ITEM(ignore_headers_in_manifest, env_string)
++keep_comments_cpp, 16, ITEM(keep_comments_cpp, bool)
++limit_multiple, 17, ITEM(limit_multiple, double)
++log_file, 18, ITEM(log_file, env_string)
++max_files, 19, ITEM(max_files, unsigned)
++max_size, 20, ITEM(max_size, size)
++path, 21, ITEM(path, env_string)
++pch_external_checksum, 22, ITEM(pch_external_checksum, bool)
++prefix_command, 23, ITEM(prefix_command, env_string)
++prefix_command_cpp, 24, ITEM(prefix_command_cpp, env_string)
++read_only, 25, ITEM(read_only, bool)
++read_only_direct, 26, ITEM(read_only_direct, bool)
++recache, 27, ITEM(recache, bool)
++run_second_cpp, 28, ITEM(run_second_cpp, bool)
++sloppiness, 29, ITEM(sloppiness, sloppiness)
++stats, 30, ITEM(stats, bool)
++temporary_dir, 31, ITEM(temporary_dir, env_string)
++umask, 32, ITEM(umask, umask)
++unify, 33, ITEM(unify, bool)
#endif
#line 8 "src/confitems.gperf"
+
+ #include "confitems.h"
+ #include "conf.h"
+
+ #undef bool
+ #define ITEM_ENTRY(name, type, verify_fn) \
+ offsetof(struct conf, name), confitem_parse_ ## type, \
+ confitem_format_ ## type, verify_fn
+ #define ITEM(name, type) \
+ ITEM_ENTRY(name, type, NULL)
+ #define ITEM_V(name, type, verification) \
+ ITEM_ENTRY(name, type, confitem_verify_ ## verification)
+ #line 21 "src/confitems.gperf"
struct conf_item;
-/* maximum key range = 48, duplicates = 0 */
+/* maximum key range = 46, duplicates = 0 */
#ifdef __GNUC__
__inline
{
static const unsigned char asso_values[] =
{
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 0, 35, 0,
- 0, 10, 52, 0, 30, 25, 52, 0, 10, 20,
- 10, 0, 0, 52, 5, 5, 10, 15, 52, 52,
- 15, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 35, 0,
+ 5, 10, 50, 0, 30, 20, 50, 0, 10, 20,
- 5, 0, 0, 50, 5, 0, 10, 15, 50, 50,
++ 15, 0, 0, 50, 5, 10, 10, 15, 50, 50,
+ 20, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50
};
return len + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]];
}
{
enum
{
-- TOTAL_KEYWORDS = 33,
++ TOTAL_KEYWORDS = 34,
MIN_WORD_LENGTH = 4,
MAX_WORD_LENGTH = 26,
MIN_HASH_VALUE = 4,
static const struct conf_item wordlist[] =
{
- {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
- {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
- #line 30 "src/confitems.gperf"
- {"path", 20, ITEM(path, env_string)},
- {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
- {"",0,NULL,0,NULL},
- #line 13 "src/confitems.gperf"
+ {"",0,0,NULL,NULL,NULL}, {"",0,0,NULL,NULL,NULL},
+ {"",0,0,NULL,NULL,NULL}, {"",0,0,NULL,NULL,NULL},
-#line 43 "src/confitems.gperf"
- {"path", 20, ITEM(path, env_string)},
++#line 44 "src/confitems.gperf"
++ {"path", 21, ITEM(path, env_string)},
+ {"",0,0,NULL,NULL,NULL}, {"",0,0,NULL,NULL,NULL},
+ {"",0,0,NULL,NULL,NULL},
+ #line 26 "src/confitems.gperf"
{"compiler", 3, ITEM(compiler, string)},
- #line 11 "src/confitems.gperf"
+ #line 24 "src/confitems.gperf"
{"cache_dir", 1, ITEM(cache_dir, env_string)},
- {"",0,NULL,0,NULL},
- #line 15 "src/confitems.gperf"
+ {"",0,0,NULL,NULL,NULL},
+ #line 28 "src/confitems.gperf"
{"compression", 5, ITEM(compression, bool)},
- {"",0,NULL,0,NULL},
- #line 17 "src/confitems.gperf"
+ {"",0,0,NULL,NULL,NULL},
+ #line 30 "src/confitems.gperf"
{"cpp_extension", 7, ITEM(cpp_extension, string)},
- #line 14 "src/confitems.gperf"
+ #line 27 "src/confitems.gperf"
{"compiler_check", 4, ITEM(compiler_check, string)},
- #line 39 "src/confitems.gperf"
- {"stats", 29, ITEM(stats, bool)},
- #line 12 "src/confitems.gperf"
-#line 31 "src/confitems.gperf"
- {"debug", 8, ITEM(debug, bool)},
++ {"",0,0,NULL,NULL,NULL},
+ #line 25 "src/confitems.gperf"
{"cache_dir_levels", 2, ITEM_V(cache_dir_levels, unsigned, dir_levels)},
- #line 16 "src/confitems.gperf"
+ #line 29 "src/confitems.gperf"
{"compression_level", 6, ITEM(compression_level, unsigned)},
- #line 27 "src/confitems.gperf"
-#line 40 "src/confitems.gperf"
-- {"log_file", 17, ITEM(log_file, env_string)},
- #line 32 "src/confitems.gperf"
-#line 45 "src/confitems.gperf"
-- {"prefix_command", 22, ITEM(prefix_command, env_string)},
- #line 38 "src/confitems.gperf"
- {"sloppiness", 28, ITEM(sloppiness, sloppiness)},
-#line 52 "src/confitems.gperf"
- {"stats", 29, ITEM(stats, bool)},
-#line 44 "src/confitems.gperf"
- {"pch_external_checksum", 21, ITEM(pch_external_checksum, bool)},
-#line 49 "src/confitems.gperf"
- {"recache", 26, ITEM(recache, bool)},
++#line 41 "src/confitems.gperf"
++ {"log_file", 18, ITEM(log_file, env_string)},
+ #line 46 "src/confitems.gperf"
- {"prefix_command_cpp", 23, ITEM(prefix_command_cpp, env_string)},
++ {"prefix_command", 23, ITEM(prefix_command, env_string)},
+#line 31 "src/confitems.gperf"
- {"pch_external_checksum", 21, ITEM(pch_external_checksum, bool)},
- #line 36 "src/confitems.gperf"
- {"recache", 26, ITEM(recache, bool)},
- #line 33 "src/confitems.gperf"
- {"prefix_command_cpp", 23, ITEM(prefix_command_cpp, env_string)},
- #line 34 "src/confitems.gperf"
- {"read_only", 24, ITEM(read_only, bool)},
++ {"debug", 8, ITEM(debug, bool)},
++#line 45 "src/confitems.gperf"
++ {"pch_external_checksum", 22, ITEM(pch_external_checksum, bool)},
++#line 50 "src/confitems.gperf"
++ {"recache", 27, ITEM(recache, bool)},
+ #line 47 "src/confitems.gperf"
- {"read_only", 24, ITEM(read_only, bool)},
-#line 51 "src/confitems.gperf"
- {"sloppiness", 28, ITEM(sloppiness, sloppiness)},
- {"",0,0,NULL,NULL,NULL},
-#line 38 "src/confitems.gperf"
- {"keep_comments_cpp", 15, ITEM(keep_comments_cpp, bool)},
-#line 42 "src/confitems.gperf"
- {"max_size", 19, ITEM(max_size, size)},
-#line 41 "src/confitems.gperf"
- {"max_files", 18, ITEM(max_files, unsigned)},
-#line 55 "src/confitems.gperf"
- {"unify", 32, ITEM(unify, bool)},
++ {"prefix_command_cpp", 24, ITEM(prefix_command_cpp, env_string)},
+ #line 48 "src/confitems.gperf"
- {"read_only_direct", 25, ITEM(read_only_direct, bool)},
-#line 33 "src/confitems.gperf"
- {"disable", 10, ITEM(disable, bool)},
++ {"read_only", 25, ITEM(read_only, bool)},
+ #line 53 "src/confitems.gperf"
- {"temporary_dir", 30, ITEM(temporary_dir, env_string)},
-#line 50 "src/confitems.gperf"
- {"run_second_cpp", 27, ITEM(run_second_cpp, bool)},
- {"",0,0,NULL,NULL,NULL},
++ {"stats", 30, ITEM(stats, bool)},
+ #line 32 "src/confitems.gperf"
- {"direct_mode", 9, ITEM(direct_mode, bool)},
++ {"depend_mode", 9, ITEM(depend_mode, bool)},
++#line 39 "src/confitems.gperf"
++ {"keep_comments_cpp", 16, ITEM(keep_comments_cpp, bool)},
++#line 43 "src/confitems.gperf"
++ {"max_size", 20, ITEM(max_size, size)},
+#line 42 "src/confitems.gperf"
- {"unify", 32, ITEM(unify, bool)},
- #line 18 "src/confitems.gperf"
- {"depend_mode", 8, ITEM(depend_mode, bool)},
- #line 25 "src/confitems.gperf"
- {"keep_comments_cpp", 15, ITEM(keep_comments_cpp, bool)},
- #line 29 "src/confitems.gperf"
- {"max_size", 19, ITEM(max_size, size)},
- #line 28 "src/confitems.gperf"
- {"max_files", 18, ITEM(max_files, unsigned)},
- {"",0,NULL,0,NULL},
- #line 35 "src/confitems.gperf"
- {"read_only_direct", 25, ITEM(read_only_direct, bool)},
- #line 20 "src/confitems.gperf"
- {"disable", 10, ITEM(disable, bool)},
- #line 40 "src/confitems.gperf"
- {"temporary_dir", 30, ITEM(temporary_dir, env_string)},
++ {"max_files", 19, ITEM(max_files, unsigned)},
++#line 52 "src/confitems.gperf"
++ {"sloppiness", 29, ITEM(sloppiness, sloppiness)},
++#line 49 "src/confitems.gperf"
++ {"read_only_direct", 26, ITEM(read_only_direct, bool)},
++#line 34 "src/confitems.gperf"
++ {"disable", 11, ITEM(disable, bool)},
++#line 54 "src/confitems.gperf"
++ {"temporary_dir", 31, ITEM(temporary_dir, env_string)},
++#line 51 "src/confitems.gperf"
++ {"run_second_cpp", 28, ITEM(run_second_cpp, bool)},
++#line 56 "src/confitems.gperf"
++ {"unify", 33, ITEM(unify, bool)},
++#line 33 "src/confitems.gperf"
++ {"direct_mode", 10, ITEM(direct_mode, bool)},
+ {"",0,0,NULL,NULL,NULL},
+#line 37 "src/confitems.gperf"
- {"run_second_cpp", 27, ITEM(run_second_cpp, bool)},
- {"",0,NULL,0,NULL},
- #line 19 "src/confitems.gperf"
- {"direct_mode", 9, ITEM(direct_mode, bool)},
- {"",0,NULL,0,NULL},
++ {"hash_dir", 14, ITEM(hash_dir, bool)},
+ #line 36 "src/confitems.gperf"
- {"hash_dir", 13, ITEM(hash_dir, bool)},
-#line 35 "src/confitems.gperf"
- {"hard_link", 12, ITEM(hard_link, bool)},
-#line 54 "src/confitems.gperf"
- {"umask", 31, ITEM(umask, umask)},
++ {"hard_link", 13, ITEM(hard_link, bool)},
++#line 55 "src/confitems.gperf"
++ {"umask", 32, ITEM(umask, umask)},
+ {"",0,0,NULL,NULL,NULL}, {"",0,0,NULL,NULL,NULL},
#line 23 "src/confitems.gperf"
- {"hash_dir", 13, ITEM(hash_dir, bool)},
- #line 22 "src/confitems.gperf"
- {"hard_link", 12, ITEM(hard_link, bool)},
- #line 41 "src/confitems.gperf"
- {"umask", 31, ITEM(umask, umask)},
- {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
- #line 10 "src/confitems.gperf"
{"base_dir", 0, ITEM_V(base_dir, env_string, absolute_path)},
- #line 26 "src/confitems.gperf"
- {"limit_multiple", 16, ITEM(limit_multiple, float)},
- {"",0,NULL,0,NULL},
- #line 24 "src/confitems.gperf"
- {"ignore_headers_in_manifest", 14, ITEM(ignore_headers_in_manifest, env_string)},
- {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
- #line 21 "src/confitems.gperf"
- {"extra_files_to_hash", 11, ITEM(extra_files_to_hash, env_string)}
-#line 34 "src/confitems.gperf"
- {"extra_files_to_hash", 11, ITEM(extra_files_to_hash, env_string)},
- {"",0,0,NULL,NULL,NULL}, {"",0,0,NULL,NULL,NULL},
- {"",0,0,NULL,NULL,NULL}, {"",0,0,NULL,NULL,NULL},
-#line 39 "src/confitems.gperf"
- {"limit_multiple", 16, ITEM(limit_multiple, double)},
++#line 40 "src/confitems.gperf"
++ {"limit_multiple", 17, ITEM(limit_multiple, double)},
+ {"",0,0,NULL,NULL,NULL},
-#line 37 "src/confitems.gperf"
- {"ignore_headers_in_manifest", 14, ITEM(ignore_headers_in_manifest, env_string)}
++#line 38 "src/confitems.gperf"
++ {"ignore_headers_in_manifest", 15, ITEM(ignore_headers_in_manifest, env_string)},
++ {"",0,0,NULL,NULL,NULL}, {"",0,0,NULL,NULL,NULL},
++#line 35 "src/confitems.gperf"
++ {"extra_files_to_hash", 12, ITEM(extra_files_to_hash, env_string)}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
}
return 0;
}
- static const size_t CONFITEMS_TOTAL_KEYWORDS = 33;
-size_t confitems_count(void) { return 33; }
++size_t confitems_count(void) { return 34; }
COMPRESSLEVEL, "compression_level"
CPP2, "run_second_cpp"
COMMENTS, "keep_comments_cpp"
+DEPEND, "depend_mode"
DIR, "cache_dir"
+ DEBUG, "debug"
DIRECT, "direct_mode"
DISABLE, "disable"
EXTENSION, "cpp_extension"
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
0, 54, 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 25, 10, 0, 0, 15,
- 10, 0, 5, 0, 54, 10, 35, 15, 0, 25,
- 0, 54, 15, 20, 0, 0, 15, 54, 54, 0,
- 54, 54, 54, 54, 54, 5, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 25, 10, 0, 0, 5,
- 10, 54, 15, 0, 54, 10, 35, 25, 10, 25,
- 0, 54, 15, 20, 0, 54, 25, 54, 54, 15,
++ 10, 0, 15, 0, 54, 10, 35, 25, 10, 25,
++ 0, 54, 15, 20, 0, 0, 25, 54, 54, 15,
+ 54, 54, 54, 54, 54, 0, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
{
enum
{
-- TOTAL_KEYWORDS = 34,
++ TOTAL_KEYWORDS = 35,
MIN_WORD_LENGTH = 2,
MAX_WORD_LENGTH = 15,
MIN_HASH_VALUE = 2,
static const struct env_to_conf_item wordlist[] =
{
{"",""}, {"",""},
- #line 12 "src/envtoconfitems.gperf"
+ #line 15 "src/envtoconfitems.gperf"
{"CC", "compiler"},
- #line 20 "src/envtoconfitems.gperf"
-#line 22 "src/envtoconfitems.gperf"
++#line 23 "src/envtoconfitems.gperf"
{"DIR", "cache_dir"},
- #line 17 "src/envtoconfitems.gperf"
+ #line 20 "src/envtoconfitems.gperf"
{"CPP2", "run_second_cpp"},
- {"",""}, {"",""},
- #line 42 "src/envtoconfitems.gperf"
-#line 23 "src/envtoconfitems.gperf"
++#line 24 "src/envtoconfitems.gperf"
+ {"DEBUG", "debug"},
+ {"",""},
-#line 45 "src/envtoconfitems.gperf"
++#line 46 "src/envtoconfitems.gperf"
{"TEMPDIR", "temporary_dir"},
- #line 13 "src/envtoconfitems.gperf"
+ #line 16 "src/envtoconfitems.gperf"
{"COMPILER", "compiler"},
-#line 36 "src/envtoconfitems.gperf"
- {"PATH", "path"},
-#line 43 "src/envtoconfitems.gperf"
- {"SLOPPINESS", "sloppiness"},
{"",""},
- #line 40 "src/envtoconfitems.gperf"
-#line 29 "src/envtoconfitems.gperf"
- {"HASHDIR", "hash_dir"},
++#line 44 "src/envtoconfitems.gperf"
+ {"SLOPPINESS", "sloppiness"},
- #line 21 "src/envtoconfitems.gperf"
++#line 25 "src/envtoconfitems.gperf"
+ {"DIRECT", "direct_mode"},
- #line 11 "src/envtoconfitems.gperf"
- {"BASEDIR", "base_dir"},
+#line 14 "src/envtoconfitems.gperf"
++ {"BASEDIR", "base_dir"},
+ #line 17 "src/envtoconfitems.gperf"
{"COMPILERCHECK", "compiler_check"},
- #line 28 "src/envtoconfitems.gperf"
-#line 31 "src/envtoconfitems.gperf"
++#line 32 "src/envtoconfitems.gperf"
{"LIMIT_MULTIPLE", "limit_multiple"},
- #line 34 "src/envtoconfitems.gperf"
-#line 47 "src/envtoconfitems.gperf"
- {"UNIFY", "unify"},
+ #line 38 "src/envtoconfitems.gperf"
+ {"PCH_EXTSUM", "pch_external_checksum"},
- #line 35 "src/envtoconfitems.gperf"
++#line 39 "src/envtoconfitems.gperf"
{"PREFIX", "prefix_command"},
- #line 29 "src/envtoconfitems.gperf"
-#line 32 "src/envtoconfitems.gperf"
- {"LOGFILE", "log_file"},
+ #line 33 "src/envtoconfitems.gperf"
+ {"LOGFILE", "log_file"},
- #line 30 "src/envtoconfitems.gperf"
++#line 34 "src/envtoconfitems.gperf"
{"MAXFILES", "max_files"},
- #line 33 "src/envtoconfitems.gperf"
- {"",""},
-#line 39 "src/envtoconfitems.gperf"
++#line 37 "src/envtoconfitems.gperf"
+ {"PATH", "path"},
- #line 36 "src/envtoconfitems.gperf"
++#line 40 "src/envtoconfitems.gperf"
{"PREFIX_CPP", "prefix_command_cpp"},
- #line 19 "src/envtoconfitems.gperf"
-#line 24 "src/envtoconfitems.gperf"
- {"DIRECT", "direct_mode"},
-#line 14 "src/envtoconfitems.gperf"
- {"BASEDIR", "base_dir"},
++#line 22 "src/envtoconfitems.gperf"
+ {"DEPEND", "depend_mode"},
- #line 26 "src/envtoconfitems.gperf"
++#line 30 "src/envtoconfitems.gperf"
+ {"HASHDIR", "hash_dir"},
- #line 15 "src/envtoconfitems.gperf"
+ #line 18 "src/envtoconfitems.gperf"
{"COMPRESS", "compression"},
- #line 23 "src/envtoconfitems.gperf"
-#line 26 "src/envtoconfitems.gperf"
++#line 27 "src/envtoconfitems.gperf"
{"EXTENSION", "cpp_extension"},
- #line 41 "src/envtoconfitems.gperf"
-#line 44 "src/envtoconfitems.gperf"
++#line 45 "src/envtoconfitems.gperf"
{"STATS", "stats"},
{"",""},
- #line 31 "src/envtoconfitems.gperf"
-#line 34 "src/envtoconfitems.gperf"
++#line 35 "src/envtoconfitems.gperf"
{"MAXSIZE", "max_size"},
- #line 16 "src/envtoconfitems.gperf"
+ #line 19 "src/envtoconfitems.gperf"
{"COMPRESSLEVEL", "compression_level"},
{"",""},
- #line 44 "src/envtoconfitems.gperf"
-#line 37 "src/envtoconfitems.gperf"
- {"PCH_EXTSUM", "pch_external_checksum"},
++#line 48 "src/envtoconfitems.gperf"
+ {"UNIFY", "unify"},
{"",""},
- #line 39 "src/envtoconfitems.gperf"
-#line 42 "src/envtoconfitems.gperf"
++#line 43 "src/envtoconfitems.gperf"
{"RECACHE", "recache"},
- #line 37 "src/envtoconfitems.gperf"
-#line 40 "src/envtoconfitems.gperf"
++#line 41 "src/envtoconfitems.gperf"
{"READONLY", "read_only"},
{"",""},
- #line 43 "src/envtoconfitems.gperf"
-#line 46 "src/envtoconfitems.gperf"
++#line 47 "src/envtoconfitems.gperf"
{"UMASK", "umask"},
{"",""},
- #line 32 "src/envtoconfitems.gperf"
-#line 35 "src/envtoconfitems.gperf"
++#line 36 "src/envtoconfitems.gperf"
{"NLEVELS", "cache_dir_levels"},
- #line 18 "src/envtoconfitems.gperf"
+ #line 21 "src/envtoconfitems.gperf"
{"COMMENTS", "keep_comments_cpp"},
{"",""},
- #line 38 "src/envtoconfitems.gperf"
-#line 41 "src/envtoconfitems.gperf"
++#line 42 "src/envtoconfitems.gperf"
{"READONLY_DIRECT", "read_only_direct"},
{"",""},
- #line 22 "src/envtoconfitems.gperf"
-#line 25 "src/envtoconfitems.gperf"
++#line 26 "src/envtoconfitems.gperf"
{"DISABLE", "disable"},
- #line 25 "src/envtoconfitems.gperf"
-#line 28 "src/envtoconfitems.gperf"
++#line 29 "src/envtoconfitems.gperf"
{"HARDLINK", "hard_link"},
{"",""}, {"",""}, {"",""}, {"",""}, {"",""}, {"",""},
- #line 24 "src/envtoconfitems.gperf"
-#line 27 "src/envtoconfitems.gperf"
++#line 28 "src/envtoconfitems.gperf"
{"EXTRAFILES", "extra_files_to_hash"},
{"",""}, {"",""},
- #line 27 "src/envtoconfitems.gperf"
-#line 30 "src/envtoconfitems.gperf"
++#line 31 "src/envtoconfitems.gperf"
{"IGNOREHEADERS", "ignore_headers_in_manifest"}
};
}
return 0;
}
- static const size_t ENVTOCONFITEMS_TOTAL_KEYWORDS = 34;
-size_t envtoconfitems_count(void) { return 34; }
++size_t envtoconfitems_count(void) { return 35; }
--- /dev/null
-
+SUITE_depend_SETUP() {
+ unset CCACHE_NODIRECT
+
+ cat <<EOF >test.c
+// test.c
+#include "test1.h"
+#include "test2.h"
+EOF
+ cat <<EOF >test1.h
+#include "test3.h"
+int test1;
+EOF
+ cat <<EOF >test2.h
+int test2;
+EOF
+ cat <<EOF >test3.h
+int test3;
+EOF
+ backdate test1.h test2.h test3.h
+
+ $REAL_COMPILER -c -Wp,-MD,expected.d test.c
+ $REAL_COMPILER -c -Wp,-MMD,expected_mmd.d test.c
+ rm test.o
+
+ DEPSFLAGS_REAL="-MP -MMD -MF reference_test.d"
+ DEPSFLAGS_CCACHE="-MP -MMD -MF test.d"
+}
+
+SUITE_depend() {
+ # -------------------------------------------------------------------------
+ TEST "Base case"
+
+ $REAL_COMPILER $DEPSFLAGS_REAL -c -o reference_test.o test.c
+
+ CCACHE_DEPEND=1 $CCACHE_COMPILE $DEPSFLAGS_CCACHE -c test.c
+ expect_equal_object_files reference_test.o test.o
+ expect_stat 'cache hit (direct)' 0
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 3 # .o + .manifest + .d
+
+
+ CCACHE_DEPEND=1 $CCACHE_COMPILE $DEPSFLAGS_CCACHE -c test.c
+ expect_equal_object_files reference_test.o test.o
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 3
+
+ # -------------------------------------------------------------------------
+ TEST "No explicit dependency file"
+
+ $REAL_COMPILER $DEPSFLAGS_REAL -c -o reference_test.o test.c
+
+ CCACHE_DEPEND=1 $CCACHE_COMPILE -MD -c test.c
+ expect_equal_object_files reference_test.o test.o
+ expect_stat 'cache hit (direct)' 0
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 3 # .o + .manifest + .d
+
+ CCACHE_DEPEND=1 $CCACHE_COMPILE -MD -c test.c
+ expect_equal_object_files reference_test.o test.o
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 3
+
+ # -------------------------------------------------------------------------
+ TEST "stderr from both preprocessor and compiler"
+
+ cat <<EOF >cpp-warning.c
+#if FOO
+// Trigger preprocessor warning about extra token after #endif.
+#endif FOO
+int stderr(void)
+{
+ // Trigger compiler warning by having no return statement.
+}
+EOF
+ $COMPILER -MD -Wall -W -c cpp-warning.c 2>stderr-baseline.txt
+
+ CCACHE_DEPEND=1 $CCACHE_COMPILE -MD -Wall -W -c cpp-warning.c 2>stderr-orig.txt
+ expect_stat 'cache hit (direct)' 0
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 1
+ expect_file_content stderr-orig.txt "`cat stderr-baseline.txt`"
+
+ CCACHE_DEPEND=1 $CCACHE_COMPILE -MD -Wall -W -c cpp-warning.c 2>stderr-mf.txt
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 1
+ expect_file_content stderr-mf.txt "`cat stderr-baseline.txt`"
+
-
+ # FIXME: add more test cases (see direct.bash for inspiration)
+}
--// Copyright (C) 2011-2018 Joel Rosdahl
++// Copyright (C) 2011-2019 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
#include "framework.h"
#include "util.h"
--#define N_CONFIG_ITEMS 33
++#define N_CONFIG_ITEMS 34
static struct {
char *descr;
- const char *origin;
+ char *origin;
} received_conf_items[N_CONFIG_ITEMS];
static size_t n_received_conf_items = 0;
CHECK(!conf->compression);
CHECK_INT_EQ(6, conf->compression_level);
CHECK_STR_EQ("", conf->cpp_extension);
+ CHECK(!conf->debug);
+ CHECK(!conf->depend_mode);
CHECK(conf->direct_mode);
CHECK(!conf->disable);
CHECK_STR_EQ("", conf->extra_files_to_hash);
user = getenv("USER");
CHECK_STR_EQ("rabbit", user);
create_file(
- "ccache.conf",
+ "ccache.conf",
#ifndef _WIN32
- "base_dir = /$USER/foo/${USER} \n"
+ "base_dir = /$USER/foo/${USER} \n"
#else
- "base_dir = C:/$USER/foo/${USER}\n"
+ "base_dir = C:/$USER/foo/${USER}\n"
#endif
- "cache_dir=\n"
- "cache_dir = $USER$/${USER}/.ccache\n"
- "\n"
- "\n"
- " #A comment\n"
- " cache_dir_levels = 4\n"
- "\t compiler = foo\n"
- "compiler_check = none\n"
- "compression=true\n"
- "compression_level= 2\n"
- "cpp_extension = .foo\n"
+ "cache_dir=\n"
+ "cache_dir = $USER$/${USER}/.ccache\n"
+ "\n"
+ "\n"
+ " #A comment\n"
+ " cache_dir_levels = 4\n"
+ "\t compiler = foo\n"
+ "compiler_check = none\n"
+ "compression=true\n"
+ "compression_level= 2\n"
+ "cpp_extension = .foo\n"
+ "depend_mode = true\n"
- "direct_mode = false\n"
- "disable = true\n"
- "extra_files_to_hash = a:b c:$USER\n"
- "hard_link = true\n"
- "hash_dir = false\n"
- "ignore_headers_in_manifest = a:b/c\n"
- "keep_comments_cpp = true\n"
- "limit_multiple = 1.0\n"
- "log_file = $USER${USER} \n"
- "max_files = 17\n"
- "max_size = 123M\n"
- "path = $USER.x\n"
- "pch_external_checksum = true\n"
- "prefix_command = x$USER\n"
- "prefix_command_cpp = y\n"
- "read_only = true\n"
- "read_only_direct = true\n"
- "recache = true\n"
- "run_second_cpp = false\n"
- "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches,pch_defines , no_system_headers \n"
- "stats = false\n"
- "temporary_dir = ${USER}_foo\n"
- "umask = 777\n"
- "unify = true"); // Note: no newline.
+ "direct_mode = false\n"
+ "disable = true\n"
+ "extra_files_to_hash = a:b c:$USER\n"
+ "hard_link = true\n"
+ "hash_dir = false\n"
+ "ignore_headers_in_manifest = a:b/c\n"
+ "keep_comments_cpp = true\n"
+ "limit_multiple = 1.0\n"
+ "log_file = $USER${USER} \n"
+ "max_files = 17\n"
+ "max_size = 123M\n"
+ "path = $USER.x\n"
+ "pch_external_checksum = true\n"
+ "prefix_command = x$USER\n"
+ "prefix_command_cpp = y\n"
+ "read_only = true\n"
+ "read_only_direct = true\n"
+ "recache = true\n"
+ "run_second_cpp = false\n"
+ "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches,file_stat_matches_ctime,pch_defines , no_system_headers,clang_index_store\n"
+ "stats = false\n"
+ "temporary_dir = ${USER}_foo\n"
+ "umask = 777\n"
+ "unify = true"); // Note: no newline.
CHECK(conf_read(conf, "ccache.conf", &errmsg));
CHECK(!errmsg);
true,
8,
"ce",
+ false,
+ true,
false,
true,
"efth",
CHECK_STR_EQ("compression = true", received_conf_items[n++].descr);
CHECK_STR_EQ("compression_level = 8", received_conf_items[n++].descr);
CHECK_STR_EQ("cpp_extension = ce", received_conf_items[n++].descr);
+ CHECK_STR_EQ("debug = false", received_conf_items[n++].descr);
+ CHECK_STR_EQ("depend_mode = true", received_conf_items[n++].descr);
CHECK_STR_EQ("direct_mode = false", received_conf_items[n++].descr);
CHECK_STR_EQ("disable = true", received_conf_items[n++].descr);
CHECK_STR_EQ("extra_files_to_hash = efth", received_conf_items[n++].descr);