*include_file_mtime*::
By default, ccache will not cache a file if it includes a header whose
mtime is too new. This option disables that check.
+*locale*::
+ ccache includes the environment variables *LANG*, *LC_ALL*, *LC_CTYPE* and
+ *LC_MESSAGES* in the hash by default since they may affect localization of
+ compiler warning messages. Set this option to tell ccache not to do that.
*no_system_headers*::
By default, ccache will also include all system headers in the manifest.
With this option set, ccache will only include system headers in the hash
- Added support for multiple `-fsanitize-blacklist` arguments, thus preventing
ccache from
+- ccache now includes the environment variables *LANG*, *LC_ALL*, *LC_CTYPE*
+ and *LC_MESSAGES* in the hash since they may affect localization of compiler
+ warning messages. Set sloppiness to ``locale'' to opt out of this.
+
- Fixed a problem due to Clang overwriting the output file when compiling an
assembler file.
hash_string(hash, base);
free(base);
+ if (!(conf->sloppiness & SLOPPY_LOCALE)) {
+ // Hash environment variables that may affect localization of compiler
+ // warning messages.
+ const char *envvars[] = {
+ "LANG",
+ "LC_ALL",
+ "LC_CTYPE",
+ "LC_MESSAGES",
+ NULL
+ };
+ for (const char **p = envvars; *p; ++p) {
+ char *v = getenv(*p);
+ if (v) {
+ hash_delimiter(hash, *p);
+ hash_string(hash, v);
+ }
+ }
+ }
+
// Possibly hash the current working directory.
if (generating_debuginfo && conf->hash_dir) {
char *cwd = gnu_getcwd();
#define SLOPPY_FILE_STAT_MATCHES_CTIME (1U << 7)
// Allow us to not include the -index-store-path option in the manifest hash.
#define SLOPPY_CLANG_INDEX_STORE (1U << 8)
+// Ignore locale settings.
+#define SLOPPY_LOCALE (1U << 9)
#define str_eq(s1, s2) (strcmp((s1), (s2)) == 0)
#define str_startswith(s, prefix) \
-// Copyright (C) 2018 Joel Rosdahl
+// Copyright (C) 2018-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
*value |= SLOPPY_TIME_MACROS;
} else if (str_eq(word, "clang_index_store")) {
*value |= SLOPPY_CLANG_INDEX_STORE;
+ } else if (str_eq(word, "locale")) {
+ *value |= SLOPPY_LOCALE;
} else {
*errmsg = format("unknown sloppiness: \"%s\"", word);
free(p);
if (*sloppiness & SLOPPY_CLANG_INDEX_STORE) {
reformat(&s, "%sclang_index_store, ", s);
}
+ if (*sloppiness & SLOPPY_LOCALE) {
+ reformat(&s, "%slocale, ", s);
+ }
if (*sloppiness) {
// Strip last ", ".
s[strlen(s) - 2] = '\0';
$CCACHE_COMPILE -c -O2 2>/dev/null
expect_stat 'no input file' 1
+ # -------------------------------------------------------------------------
+ TEST "LANG"
+
+ $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 1
+
+ $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (preprocessed)' 1
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 1
+
+ LANG=foo $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (preprocessed)' 1
+ expect_stat 'cache miss' 2
+ expect_stat 'files in cache' 2
+
+ LANG=foo $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (preprocessed)' 2
+ expect_stat 'cache miss' 2
+ expect_stat 'files in cache' 2
+
+ # -------------------------------------------------------------------------
+ TEST "LANG with sloppiness"
+
+ CCACHE_SLOPPINESS=locale LANG=foo $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 1
+
+ CCACHE_SLOPPINESS=locale LANG=foo $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (preprocessed)' 1
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 1
+
+ CCACHE_SLOPPINESS=locale LANG=bar $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (preprocessed)' 2
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 1
+
# -------------------------------------------------------------------------
TEST "CCACHE_DISABLE"
"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"
+ "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,locale\n"
"stats = false\n"
"temporary_dir = ${USER}_foo\n"
"umask = 777\n"
CHECK(conf->read_only_direct);
CHECK(conf->recache);
CHECK(!conf->run_second_cpp);
- CHECK_INT_EQ(SLOPPY_INCLUDE_FILE_MTIME|SLOPPY_INCLUDE_FILE_CTIME|
- SLOPPY_FILE_MACRO|SLOPPY_TIME_MACROS|
- SLOPPY_FILE_STAT_MATCHES|SLOPPY_FILE_STAT_MATCHES_CTIME|
- SLOPPY_NO_SYSTEM_HEADERS|SLOPPY_PCH_DEFINES|SLOPPY_CLANG_INDEX_STORE,
- conf->sloppiness);
+ CHECK_INT_EQ(
+ SLOPPY_INCLUDE_FILE_MTIME
+ |SLOPPY_INCLUDE_FILE_CTIME
+ |SLOPPY_FILE_MACRO
+ |SLOPPY_TIME_MACROS
+ |SLOPPY_FILE_STAT_MATCHES
+ |SLOPPY_FILE_STAT_MATCHES_CTIME
+ |SLOPPY_NO_SYSTEM_HEADERS
+ |SLOPPY_PCH_DEFINES
+ |SLOPPY_CLANG_INDEX_STORE
+ |SLOPPY_LOCALE,
+ conf->sloppiness);
CHECK(!conf->stats);
CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
CHECK_INT_EQ(0777, conf->umask);
true,
true,
.run_second_cpp = false,
- SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
- SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
- SLOPPY_FILE_STAT_MATCHES|SLOPPY_FILE_STAT_MATCHES_CTIME|
- SLOPPY_PCH_DEFINES|SLOPPY_NO_SYSTEM_HEADERS|SLOPPY_CLANG_INDEX_STORE,
+ SLOPPY_FILE_MACRO
+ |SLOPPY_INCLUDE_FILE_MTIME
+ |SLOPPY_INCLUDE_FILE_CTIME
+ |SLOPPY_TIME_MACROS
+ |SLOPPY_FILE_STAT_MATCHES
+ |SLOPPY_FILE_STAT_MATCHES_CTIME
+ |SLOPPY_PCH_DEFINES
+ |SLOPPY_NO_SYSTEM_HEADERS
+ |SLOPPY_CLANG_INDEX_STORE
+ |SLOPPY_LOCALE,
false,
"td",
022,
CHECK_STR_EQ("run_second_cpp = false", received_conf_items[n++].descr);
CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
" include_file_ctime, time_macros, pch_defines,"
- " file_stat_matches, file_stat_matches_ctime, no_system_headers, clang_index_store",
+ " file_stat_matches, file_stat_matches_ctime, no_system_headers, clang_index_store, locale",
received_conf_items[n++].descr);
CHECK_STR_EQ("stats = false", received_conf_items[n++].descr);
CHECK_STR_EQ("temporary_dir = td", received_conf_items[n++].descr);