]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix: Apply base_dir to include paths in preprocessor mode master
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 1 Aug 2026 17:14:53 +0000 (19:14 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 1 Aug 2026 17:26:47 +0000 (19:26 +0200)
Fix a regression introduced in 81f0eecdaea4 ("fix: Be robust against
filesystem path encoding problems on Windows") that caused absolute
include paths to be hashed despite base_dir being set.

src/ccache/ccache.cpp
test/suites/basedir.bash

index 0c6390ecf233d963236eeef7141c6ef2ff2ac7fd..6382ea5ef8ce03e82865630a3d42b717f3faa47a 100644 (file)
@@ -526,7 +526,7 @@ do_process_preprocessed_data(Context& ctx, Hash& hash, util::Bytes&& data)
 {
   ASSERT(!data.empty());
 
 {
   ASSERT(!data.empty());
 
-  std::unordered_map<std::string, std::string> relative_inc_path_cache;
+  std::unordered_map<std::string, fs::path> relative_inc_path_cache;
 
   // Bytes between p and q are pending to be hashed.
   char* q = reinterpret_cast<char*>(data.data());
 
   // Bytes between p and q are pending to be hashed.
   char* q = reinterpret_cast<char*>(data.data());
@@ -633,33 +633,35 @@ do_process_preprocessed_data(Context& ctx, Hash& hash, util::Bytes&& data)
       }
 
       // p and q span the include file path.
       }
 
       // p and q span the include file path.
-      std::string inc_path(p, q - p);
-      while (!inc_path.empty() && inc_path.back() == '/') {
-        inc_path.pop_back();
+      std::string inc_path_str(p, q - p);
+      while (!inc_path_str.empty() && inc_path_str.back() == '/') {
+        inc_path_str.pop_back();
       }
       }
-      fs::path inc_fs_path;
+
+      fs::path inc_path;
       try {
       try {
-        inc_fs_path = inc_path;
+        inc_path = inc_path_str;
       } catch (const std::filesystem::filesystem_error&) {
         return tl::unexpected(Failure(Statistic::unsupported_source_encoding));
       }
       } catch (const std::filesystem::filesystem_error&) {
         return tl::unexpected(Failure(Statistic::unsupported_source_encoding));
       }
+
       if (!ctx.config.base_dirs().empty()) {
       if (!ctx.config.base_dirs().empty()) {
-        auto it = relative_inc_path_cache.find(inc_path);
+        auto it = relative_inc_path_cache.find(inc_path_str);
         if (it == relative_inc_path_cache.end()) {
         if (it == relative_inc_path_cache.end()) {
-          std::string rel_inc_path =
-            util::pstr(core::make_relative_path(ctx, inc_fs_path));
-          relative_inc_path_cache.emplace(inc_path, rel_inc_path);
-          inc_path = util::pstr(rel_inc_path);
+          fs::path rel_inc_path = core::make_relative_path(ctx, inc_path);
+          relative_inc_path_cache.emplace(inc_path_str, rel_inc_path);
+          inc_path = rel_inc_path;
         } else {
           inc_path = it->second;
         }
       }
         } else {
           inc_path = it->second;
         }
       }
+      inc_path_str.clear(); // inc_path is used from now on
 
 
-      if (inc_fs_path != ctx.apparent_cwd || ctx.config.hash_dir()) {
-        hash.hash(inc_fs_path);
+      if (inc_path != ctx.apparent_cwd || ctx.config.hash_dir()) {
+        hash.hash(inc_path);
       }
 
       }
 
-      TRY(remember_include_file(ctx, inc_fs_path, hash, system, nullptr));
+      TRY(remember_include_file(ctx, inc_path, hash, system, nullptr));
       p = q; // Everything of interest between p and q has been hashed now.
     } else if (strncmp(q, incbin_directive, sizeof(incbin_directive)) == 0
                && ((q[7] == ' '
       p = q; // Everything of interest between p and q has been hashed now.
     } else if (strncmp(q, incbin_directive, sizeof(incbin_directive)) == 0
                && ((q[7] == ' '
index 122e1c66b78a2cc643921a70f9ef07d962eb01fc..059018b9d641941ac6834c1ec7c35f763a3bce1a 100644 (file)
@@ -40,6 +40,25 @@ SUITE_basedir() {
     expect_stat preprocessed_cache_hit 0
     expect_stat cache_miss 1
 
     expect_stat preprocessed_cache_hit 0
     expect_stat cache_miss 1
 
+    # -------------------------------------------------------------------------
+    TEST "Enabled CCACHE_BASEDIR in preprocessor mode"
+
+    cat <<EOF >compiler
+#!/bin/sh
+exec "$COMPILER" -I"\$PWD/include" "\$@"
+EOF
+    chmod +x compiler
+
+    cd dir1
+    CCACHE_COMPILERCHECK=none CCACHE_COMPILERTYPE=gcc CCACHE_NODIRECT=1 CCACHE_BASEDIR="`pwd`" $CCACHE ../compiler -c src/test.c
+    expect_stat preprocessed_cache_hit 0
+    expect_stat cache_miss 1
+
+    cd ../dir2
+    CCACHE_COMPILERCHECK=none CCACHE_COMPILERTYPE=gcc CCACHE_NODIRECT=1 CCACHE_BASEDIR="`pwd`" $CCACHE ../compiler -c src/test.c
+    expect_stat preprocessed_cache_hit 1
+    expect_stat cache_miss 1
+
     # -------------------------------------------------------------------------
     TEST "Disabled (default) CCACHE_BASEDIR"
 
     # -------------------------------------------------------------------------
     TEST "Disabled (default) CCACHE_BASEDIR"