From b3c3e7998c6497f8d354da77c7ed6184381c6247 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Mon, 6 Mar 2023 21:22:25 +0100 Subject: feat: Make it possible to disable ccache for a certain source code file --- doc/MANUAL.adoc | 15 +++++++++++++++ src/ccache.cpp | 23 +++++++++++++++++++++++ src/core/Statistic.hpp | 5 +++-- src/core/Statistics.cpp | 1 + test/suites/base.bash | 8 ++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/doc/MANUAL.adoc b/doc/MANUAL.adoc index 76a5663b..dc7c75f3 100644 --- a/doc/MANUAL.adoc +++ b/doc/MANUAL.adoc @@ -687,6 +687,9 @@ _<>_. When true, ccache will just call the real compiler, bypassing the cache completely. The default is false. ++ +It is also possible to disable ccache for a specific source code file by adding +the string `ccache:disable` in a comment in the first 4096 bytes of the file. [#config_extra_files_to_hash] *extra_files_to_hash* (*CCACHE_EXTRAFILES*):: @@ -1077,6 +1080,15 @@ filesystem as the `CCACHE_DIR` path, but this requirement has been relaxed. cache with other users. +=== Disabling ccache + +To disable ccache completely for all invocations, set <> (`CCACHE_DISABLE=1`). You can also disable ccache for a certain source +code file by adding the string `ccache:disable` in a comment in the first 4096 +bytes of the file. In the latter case the `Ccache disabled` statistics counter +will be increased. + + == Remote storage backends The <> option lets you configure ccache @@ -1379,6 +1391,9 @@ produce a single object file from a single source file. | Called for preprocessing | The compiler was called for preprocessing, not compiling. +| Ccache disabled | +Ccache was disabled by a `ccache:disable` string in the source code file. + | Could not use modules | Preconditions for using <> were not fulfilled. diff --git a/src/ccache.cpp b/src/ccache.cpp index 9efbd563..9547f538 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -86,6 +86,14 @@ using core::Statistic; // stored in the cache changes in a backwards-incompatible way. const char HASH_PREFIX[] = "4"; +// Search for k_ccache_disable_token within the first +// k_ccache_disable_search_limit bytes of the input file. +const size_t k_ccache_disable_search_limit = 4096; + +// String to look for when checking whether to disable ccache for the input +// file. +const char k_ccache_disable_token[] = "ccache:disable"; + namespace { // Return nonstd::make_unexpected if ccache did not succeed in getting @@ -136,6 +144,14 @@ Failure::set_exit_code(const int exit_code) } // namespace +static bool +should_disable_ccache_for_input_file(const std::string& path) +{ + auto content = + util::read_file_part(path, 0, k_ccache_disable_search_limit); + return content && content->find(k_ccache_disable_token) != std::string::npos; +} + static void add_prefix(const Context& ctx, Args& args, const std::string& prefix_command) { @@ -2488,6 +2504,13 @@ do_cache_compilation(Context& ctx) Hash common_hash; init_hash_debug(ctx, common_hash, 'c', "COMMON", debug_text_file); + if (should_disable_ccache_for_input_file(ctx.args_info.input_file)) { + LOG("{} found in {}, disabling ccache", + k_ccache_disable_token, + ctx.args_info.input_file); + return nonstd::make_unexpected(Statistic::disabled); + } + { MTR_SCOPE("hash", "common_hash"); TRY(hash_common_info( diff --git a/src/core/Statistic.hpp b/src/core/Statistic.hpp index ba39cfea..fb0e3790 100644 --- a/src/core/Statistic.hpp +++ b/src/core/Statistic.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Joel Rosdahl and other contributors +// Copyright (C) 2021-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -78,7 +78,8 @@ enum class Statistic { // 65-80: size (KiB) in level 2 subdirs 0-f subdir_size_kibibyte_base = 65, - END = 81 + disabled = 81, + END = 82 }; } // namespace core diff --git a/src/core/Statistics.cpp b/src/core/Statistics.cpp index aa928a72..f00f40c8 100644 --- a/src/core/Statistics.cpp +++ b/src/core/Statistics.cpp @@ -90,6 +90,7 @@ const StatisticsField k_statistics_fields[] = { FLAG_UNCACHEABLE), FIELD(direct_cache_hit, nullptr), FIELD(direct_cache_miss, nullptr), + FIELD(disabled, "Ccache disabled", FLAG_UNCACHEABLE), FIELD(error_hashing_extra_file, "Error hashing extra file", FLAG_ERROR), FIELD(files_in_cache, nullptr, FLAG_NOZERO), FIELD(internal_error, "Internal error", FLAG_ERROR), diff --git a/test/suites/base.bash b/test/suites/base.bash index ff905942..7c54ec0e 100644 --- a/test/suites/base.bash +++ b/test/suites/base.bash @@ -393,6 +393,7 @@ if $RUN_WIN_XFAIL;then CCACHE_DEBUG=1 CCACHE_DEBUGDIR=debugdir $CCACHE_COMPILE -c test1.c expect_contains debugdir"$(pwd -P)"/test1.o.*.ccache-log "Result: cache_miss" fi + # ------------------------------------------------------------------------- TEST "CCACHE_DISABLE" @@ -401,6 +402,13 @@ fi test_failed "$CCACHE_DIR created despite CCACHE_DISABLE being set" fi + # ------------------------------------------------------------------------- + TEST "ccache:disable" + + echo '// ccache:disable' >>test1.c + $CCACHE_COMPILE -c test1.c 2>/dev/null + expect_stat disabled 1 + # ------------------------------------------------------------------------- TEST "CCACHE_COMMENTS" -- cgit v1.2.1