]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Hash environment variables related to locale
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 9 Jan 2019 19:06:43 +0000 (20:06 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 9 Jan 2019 19:06:43 +0000 (20:06 +0100)
This avoids emitting incorrect compiler warning messages when switching
locale settings.

Fixes #327.

doc/MANUAL.adoc
doc/NEWS.adoc
src/ccache.c
src/ccache.h
src/confitems.c
test/suites/base.bash
unittest/test_conf.c

index 4724120bc83aa205a19ae4cc516ca1800ba4a29f..73d71759b511639c75078fb1023e8253b63d4f3d 100644 (file)
@@ -556,6 +556,10 @@ still has to do _some_ preprocessing (like macros).
 *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
index 13b7fc7cd75b85e190201b14325a0bf1966cb956..36e360813e1b56864852f651874bd757afe8387c 100644 (file)
@@ -19,6 +19,10 @@ Changes
 - 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.
 
index 4a308a324d8faf4632df969ab874e6df1bc93561..c2aa9cd6cbbb1cb7dc8c57ddaf0cdd46a595343f 100644 (file)
@@ -1786,6 +1786,25 @@ calculate_common_hash(struct args *args, struct hash *hash)
        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();
index 590cfc46f060f8f02cb2a0a77aaee1d7a5eff6df..170fdb567fc878ccac0f2f59fea8c2c51a607c37 100644 (file)
@@ -100,6 +100,8 @@ extern enum guessed_compiler guessed_compiler;
 #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) \
index 639f5cb6dfa3f139126dca06aaa933799a9288a4..0ef121bd0a9ae72d93a6d93dc12522bb9f435654 100644 (file)
@@ -1,4 +1,4 @@
-// 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
@@ -138,6 +138,8 @@ confitem_parse_sloppiness(const char *str, void *result, char **errmsg)
                        *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);
@@ -181,6 +183,9 @@ confitem_format_sloppiness(void *value)
        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';
index 63ef9e7145da5d46b4cd69e686848e2cab7a3084..212e148ff2b821e1d0218435fbeddae2c8777dc9 100644 (file)
@@ -138,6 +138,47 @@ base_tests() {
     $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"
 
index 61f38166721fcfbe02816b5d423cb7d379026f49..e90435e75e8634bd76b965280aa72ef5917a3ce4 100644 (file)
@@ -132,7 +132,7 @@ TEST(conf_read_valid_config)
                "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"
@@ -172,11 +172,18 @@ TEST(conf_read_valid_config)
        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);
@@ -463,10 +470,16 @@ TEST(conf_print_items)
                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,
@@ -518,7 +531,7 @@ TEST(conf_print_items)
        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);