From: Joel Rosdahl Date: Wed, 2 Jan 2019 18:48:42 +0000 (+0100) Subject: Merge branch 'master' into depend_mode X-Git-Tag: v3.6~31^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F301%2Fhead;p=thirdparty%2Fccache.git Merge branch 'master' into depend_mode --- 028ffae97eaa4878f617389d0770fbd02a115b50 diff --cc doc/MANUAL.adoc index e48ea5fe9,a10fe9500..dbbd309fb --- a/doc/MANUAL.adoc +++ b/doc/MANUAL.adoc @@@ -350,11 -350,13 +350,18 @@@ WRAPPERS>> 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 @@@ -857,33 -872,58 +877,84 @@@ In the preprocessor mode, the hash is f 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 + | *.ccache-input-c* | + Binary input hashed by both the direct mode and the preprocessor mode. + + | *.ccache-input-d* | + Binary input only hashed by the direct mode. + + | *.ccache-input-p* | + Binary input only hashed by the preprocessor mode. + + | *.ccache-input-text* | + Human-readable combined diffable text version of the three files above. + + | *.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 *.ccache-** files. + 3. Build again with debug mode enabled. + 4. Compare *.ccache-input-text* for the two builds. This together + with the *.ccache-log* files should give you some clues about + what is happening. + + Compiling in different directories ---------------------------------- diff --cc src/ccache.c index 90c7213cc,3ffc45a6d..d48a2bf12 --- a/src/ccache.c +++ b/src/ccache.c @@@ -534,9 -584,10 +584,11 @@@ get_path_in_cache(const char *name, con // 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 or . @@@ -672,19 -721,13 +722,18 @@@ } 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); + 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)); + } - } else { - free(path); } - return; + goto out; failure: if (conf->direct_mode) { @@@ -911,10 -951,10 +967,10 @@@ process_preprocessed_file(struct hash * } } 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') { @@@ -950,15 -990,10 +1006,15 @@@ // 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; @@@ -1044,46 -1079,6 +1100,46 @@@ out free(tmp_file); } +// extract the used includes from the dependency file +// note we cannot distinguish system headers from other includes here +static struct file_hash * - object_hash_from_depfile(const char *depfile, struct mdfour *hash) { ++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->totalN; ++ 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) @@@ -1244,27 -1239,15 +1300,27 @@@ update_manifest_file(void } } -// 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); +} +// Run the real compiler and put the result in cache. +static void - to_cache(struct args *args, struct mdfour *depend_mode_hash) ++to_cache(struct args *args, struct hash *depend_mode_hash) +{ args_add(args, "-o"); args_add(args, output_obj); @@@ -1286,37 -1273,9 +1346,38 @@@ } 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) { @@@ -3518,41 -3519,42 +3627,44 @@@ ccache(int argc, char *argv[] 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(); @@@ -3560,11 -3562,8 +3672,11 @@@ 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); } diff --cc src/conf.c index b08c9e318,b9ca0a240..61b76d480 --- a/src/conf.c +++ b/src/conf.c @@@ -1,4 -1,4 +1,4 @@@ --// 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 @@@ -328,7 -130,7 +130,8 @@@ conf_create(void 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(""); @@@ -536,155 -339,80 +340,81 @@@ conf_set_value_in_file(const char *path } 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; + } diff --cc src/conf.h index 0109665e7,f45d09b58..52a48c8e7 --- a/src/conf.h +++ b/src/conf.h @@@ -12,7 -12,7 +12,8 @@@ struct conf bool compression; unsigned compression_level; char *cpp_extension; + bool debug; + bool depend_mode; bool direct_mode; bool disable; char *extra_files_to_hash; diff --cc src/confitems.gperf index e324e544f,8d6a76756..46cfd3772 --- a/src/confitems.gperf +++ b/src/confitems.gperf @@@ -15,28 -28,28 +28,29 @@@ compiler_check, 4, ITEM(compiler_ 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) diff --cc src/confitems_lookup.c index f40ed264e,02a6efd7b..9ab7fc34f --- a/src/confitems_lookup.c +++ b/src/confitems_lookup.c @@@ -30,8 -30,21 +30,21 @@@ #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 @@@ -45,32 -58,32 +58,32 @@@ confitems_hash (register const char *st { 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]]; } @@@ -87,7 -93,7 +93,7 @@@ confitems_get (register const char *str { enum { -- TOTAL_KEYWORDS = 33, ++ TOTAL_KEYWORDS = 34, MIN_WORD_LENGTH = 4, MAX_WORD_LENGTH = 26, MIN_HASH_VALUE = 4, @@@ -96,84 -102,85 +102,85 @@@ 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) @@@ -190,4 -197,4 +197,4 @@@ } return 0; } - static const size_t CONFITEMS_TOTAL_KEYWORDS = 33; -size_t confitems_count(void) { return 33; } ++size_t confitems_count(void) { return 34; } diff --cc src/envtoconfitems.gperf index af537dd03,ffd354b2b..374d19c5d --- a/src/envtoconfitems.gperf +++ b/src/envtoconfitems.gperf @@@ -16,8 -19,8 +19,9 @@@ COMPRESS, "compression 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" diff --cc src/envtoconfitems_lookup.c index 84acb92fb,30432af4b..5ab97edfd --- a/src/envtoconfitems_lookup.c +++ b/src/envtoconfitems_lookup.c @@@ -51,10 -54,10 +54,10 @@@ envtoconfitems_hash (register const cha 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, @@@ -101,7 -97,7 +97,7 @@@ envtoconfitems_get (register const cha { enum { -- TOTAL_KEYWORDS = 34, ++ TOTAL_KEYWORDS = 35, MIN_WORD_LENGTH = 2, MAX_WORD_LENGTH = 15, MIN_HASH_VALUE = 2, @@@ -111,84 -107,85 +107,86 @@@ 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"} }; @@@ -206,4 -203,4 +204,4 @@@ } return 0; } - static const size_t ENVTOCONFITEMS_TOTAL_KEYWORDS = 34; -size_t envtoconfitems_count(void) { return 34; } ++size_t envtoconfitems_count(void) { return 35; } diff --cc test/suites/depend.bash index d29196689,000000000..598e1e6a2 mode 100644,000000..100644 --- a/test/suites/depend.bash +++ b/test/suites/depend.bash @@@ -1,98 -1,0 +1,96 @@@ +SUITE_depend_SETUP() { + unset CCACHE_NODIRECT + + cat <test.c +// test.c +#include "test1.h" +#include "test2.h" +EOF + cat <test1.h +#include "test3.h" +int test1; +EOF + cat <test2.h +int test2; +EOF + cat <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 <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) - +} diff --cc unittest/test_conf.c index 4079af695,9b58c3f8c..36b0e723a --- a/unittest/test_conf.c +++ b/unittest/test_conf.c @@@ -1,4 -1,4 +1,4 @@@ --// 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 @@@ -18,10 -18,10 +18,10 @@@ #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; @@@ -57,7 -58,7 +58,8 @@@ TEST(conf_create 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); @@@ -93,48 -94,47 +95,48 @@@ TEST(conf_read_valid_config 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); @@@ -396,7 -439,7 +442,8 @@@ TEST(conf_print_items true, 8, "ce", + false, + true, false, true, "efth", @@@ -447,7 -490,7 +494,8 @@@ 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);