From 45dbe4d922e56e3e8a62ca1da577c75078d947a5 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Sat, 1 Aug 2026 19:14:53 +0200 Subject: [PATCH] fix: Apply base_dir to include paths in preprocessor mode 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 | 30 ++++++++++++++++-------------- test/suites/basedir.bash | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/ccache/ccache.cpp b/src/ccache/ccache.cpp index 0c6390ecf..6382ea5ef 100644 --- a/src/ccache/ccache.cpp +++ b/src/ccache/ccache.cpp @@ -526,7 +526,7 @@ do_process_preprocessed_data(Context& ctx, Hash& hash, util::Bytes&& data) { ASSERT(!data.empty()); - std::unordered_map relative_inc_path_cache; + std::unordered_map relative_inc_path_cache; // Bytes between p and q are pending to be hashed. char* q = reinterpret_cast(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. - 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 { - inc_fs_path = inc_path; + inc_path = inc_path_str; } catch (const std::filesystem::filesystem_error&) { return tl::unexpected(Failure(Statistic::unsupported_source_encoding)); } + 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()) { - 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; } } + 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] == ' ' diff --git a/test/suites/basedir.bash b/test/suites/basedir.bash index 122e1c66b..059018b9d 100644 --- a/test/suites/basedir.bash +++ b/test/suites/basedir.bash @@ -40,6 +40,25 @@ SUITE_basedir() { expect_stat preprocessed_cache_hit 0 expect_stat cache_miss 1 + # ------------------------------------------------------------------------- + TEST "Enabled CCACHE_BASEDIR in preprocessor mode" + + cat <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" -- 2.47.3