From: Henrique Ferreiro Date: Fri, 10 Jan 2025 13:38:11 +0000 (+0100) Subject: feat: Add support for -f(debug|file)-compilation-dir (#1535) X-Git-Tag: v4.11~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8833707ceab66fae9a930580d07eec72bbef0db9;p=thirdparty%2Fccache.git feat: Add support for -f(debug|file)-compilation-dir (#1535) --- diff --git a/doc/MANUAL.adoc b/doc/MANUAL.adoc index 339296db..72ab2d78 100644 --- a/doc/MANUAL.adoc +++ b/doc/MANUAL.adoc @@ -796,9 +796,9 @@ WARNING: Do not enable this option unless you are aware of these caveats: If true (which is the default), ccache will include the current working directory (CWD) in the hash that is used to distinguish two compilations when generating debug info (compiler option `-g` with variations). - Exception: The CWD will not be included in the hash if - <> is set (and matches the CWD) and the - compiler option `-fdebug-prefix-map` is used. See also the discussion under + Exception: The CWD will not be included in the hash if the + compiler options `-fdebug-prefix-map` or `-fdebug-compilation-dir` are used + appropriately. See also the discussion under _<>_. + The reason for including the CWD in the hash by default is to prevent a problem @@ -1812,8 +1812,10 @@ directories: * If you build with `-g` (or similar) to add debug information to the object file, you must either: -** use the compiler option `-fdebug-prefix-map==` for relocating - debug info to a common prefix (e.g. `-fdebug-prefix-map=$PWD=.`); or +** use the compiler options `-fdebug-prefix-map==` or + `-fdebug-compilation-dir` for relocating + debug info to a common prefix (e.g. `-fdebug-prefix-map=$PWD=.` or + `-fdebug-compilation-dir=.`); or ** set *hash_dir = false*. * If you use absolute paths anywhere on the command line (e.g. the source code file path or an argument to compiler options like `-I` and `-MF`), you must diff --git a/src/ccache/argprocessing.cpp b/src/ccache/argprocessing.cpp index f7562c0e..c10c0278 100644 --- a/src/ccache/argprocessing.cpp +++ b/src/ccache/argprocessing.cpp @@ -709,6 +709,29 @@ process_option_arg(const Context& ctx, return Statistic::none; } + if (util::starts_with(arg, "-fdebug-compilation-dir") + || util::starts_with(arg, "-ffile-compilation-dir")) { + std::string compilation_dir; + // -ffile-compilation-dir cannot be followed by a space. + if (arg == "-fdebug-compilation-dir") { + if (i == args.size() - 1) { + LOG("Missing argument to {}", args[i]); + return Statistic::bad_compiler_arguments; + } + state.common_args.push_back(args[i]); + compilation_dir = args[i + 1]; + i++; + } else { + const auto eq_pos = arg.find('='); + if (eq_pos != std::string_view::npos) { + compilation_dir = arg.substr(eq_pos + 1); + } + } + args_info.compilation_dir = std::move(compilation_dir); + state.common_args.push_back(args[i]); + return Statistic::none; + } + // Debugging is handled specially, so that we know if we can strip line // number info. if (util::starts_with(arg, "-g")) { diff --git a/src/ccache/argsinfo.hpp b/src/ccache/argsinfo.hpp index fec843ca..9e6c37d9 100644 --- a/src/ccache/argsinfo.hpp +++ b/src/ccache/argsinfo.hpp @@ -160,4 +160,8 @@ struct ArgsInfo // Relocating debuginfo in the format old=new. std::vector debug_prefix_maps; + + // Compilation directory as passed in -ffile-compilation-dir or + // -fdebug-compilation-dir. + std::string compilation_dir; }; diff --git a/src/ccache/ccache.cpp b/src/ccache/ccache.cpp index 465b85e1..4608f92b 100644 --- a/src/ccache/ccache.cpp +++ b/src/ccache/ccache.cpp @@ -1572,19 +1572,23 @@ hash_common_info(const Context& ctx, // Possibly hash the current working directory. if (args_info.generating_debuginfo && ctx.config.hash_dir()) { std::string dir_to_hash = util::pstr(ctx.apparent_cwd); - for (const auto& map : args_info.debug_prefix_maps) { - size_t sep_pos = map.find('='); - if (sep_pos != std::string::npos) { - std::string old_path = map.substr(0, sep_pos); - std::string new_path = map.substr(sep_pos + 1); - LOG("Relocating debuginfo from {} to {} (CWD: {})", - old_path, - new_path, - ctx.apparent_cwd); - if (util::starts_with(util::pstr(ctx.apparent_cwd).str(), old_path)) { - dir_to_hash = - new_path - + util::pstr(ctx.apparent_cwd).str().substr(old_path.size()); + if (!args_info.compilation_dir.empty()) { + dir_to_hash = args_info.compilation_dir; + } else { + for (const auto& map : args_info.debug_prefix_maps) { + size_t sep_pos = map.find('='); + if (sep_pos != std::string::npos) { + std::string old_path = map.substr(0, sep_pos); + std::string new_path = map.substr(sep_pos + 1); + LOG("Relocating debuginfo from {} to {} (CWD: {})", + old_path, + new_path, + ctx.apparent_cwd); + if (util::starts_with(util::pstr(ctx.apparent_cwd).str(), old_path)) { + dir_to_hash = + new_path + + util::pstr(ctx.apparent_cwd).str().substr(old_path.size()); + } } } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 141e91d1..bcdddfec 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,6 +27,7 @@ addtest(cleanup) addtest(color_diagnostics) addtest(config) addtest(cpp1) +addtest(debug_compilation_dir) addtest(debug_prefix_map) addtest(depend) addtest(direct) diff --git a/test/suites/debug_compilation_dir.bash b/test/suites/debug_compilation_dir.bash new file mode 100644 index 00000000..c0b85f55 --- /dev/null +++ b/test/suites/debug_compilation_dir.bash @@ -0,0 +1,49 @@ +SUITE_debug_compilation_dir_PROBE() { + touch test.c + if ! $COMPILER -c -fdebug-compilation-dir=dir test.c 2>/dev/null; then + echo "-fdebug-compilation-dir not supported by compiler" + fi + + if ! $RUN_WIN_XFAIL; then + echo "debug-compilation-dir tests are broken on Windows." + return + fi +} + +SUITE_debug_compilation_dir_SETUP() { + unset CCACHE_NODIRECT + + mkdir -p dir1/src dir1/include + cat <dir1/src/test.c +#include +#include +EOF + cat <dir1/include/test.h +int test; +EOF + cp -r dir1 dir2 + backdate dir1/include/test.h dir2/include/test.h +} + +SUITE_debug_compilation_dir() { + # ------------------------------------------------------------------------- + TEST "Setting compilation directory" + + cd dir1 + CCACHE_BASEDIR=$(pwd) $CCACHE_COMPILE -I$(pwd)/include -g -fdebug-compilation-dir=some_name_not_likely_to_exist_in_path -c $(pwd)/src/test.c -o $(pwd)/test.o + expect_stat direct_cache_hit 0 + expect_stat preprocessed_cache_hit 0 + expect_stat cache_miss 1 + expect_stat files_in_cache 2 + expect_objdump_not_contains test.o "$(pwd)" + expect_objdump_contains test.o some_name_not_likely_to_exist_in_path + + cd ../dir2 + CCACHE_BASEDIR=$(pwd) $CCACHE_COMPILE -I$(pwd)/include -g -fdebug-compilation-dir=some_name_not_likely_to_exist_in_path -c $(pwd)/src/test.c -o $(pwd)/test.o + expect_stat direct_cache_hit 1 + expect_stat preprocessed_cache_hit 0 + expect_stat cache_miss 1 + expect_stat files_in_cache 2 + expect_objdump_not_contains test.o "$(pwd)" + expect_objdump_contains test.o some_name_not_likely_to_exist_in_path +} diff --git a/test/suites/debug_prefix_map.bash b/test/suites/debug_prefix_map.bash index af0cdaa0..e6823f10 100644 --- a/test/suites/debug_prefix_map.bash +++ b/test/suites/debug_prefix_map.bash @@ -45,6 +45,7 @@ SUITE_debug_prefix_map() { expect_stat cache_miss 1 expect_stat files_in_cache 2 expect_objdump_not_contains test.o "$(pwd)" + expect_objdump_contains test.o some_name_not_likely_to_exist_in_path # ------------------------------------------------------------------------- TEST "Multiple -fdebug-prefix-map"