]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Add support for -f(debug|file)-compilation-dir (#1535)
authorHenrique Ferreiro <hferreiro@igalia.com>
Fri, 10 Jan 2025 13:38:11 +0000 (14:38 +0100)
committerGitHub <noreply@github.com>
Fri, 10 Jan 2025 13:38:11 +0000 (14:38 +0100)
doc/MANUAL.adoc
src/ccache/argprocessing.cpp
src/ccache/argsinfo.hpp
src/ccache/ccache.cpp
test/CMakeLists.txt
test/suites/debug_compilation_dir.bash [new file with mode: 0644]
test/suites/debug_prefix_map.bash

index 339296dbcc1ca19a698858442302d4bbadef61b7..72ab2d787dfbf7800315389fec16ddf1683d7884 100644 (file)
@@ -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
-    <<config_base_dir,*base_dir*>> 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
     _<<Compiling in different directories>>_.
 +
 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=<old>=<new>` for relocating
-   debug info to a common prefix (e.g. `-fdebug-prefix-map=$PWD=.`); or
+** use the compiler options `-fdebug-prefix-map=<old>=<new>` 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
index f7562c0e6f3024018849667a54231c4920c32f20..c10c0278d716c3930c4fb0443aaec08155043d26 100644 (file)
@@ -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")) {
index fec843cabf48ca4338da304a59c322544422f9b6..9e6c37d9ad04add83b99f09a82e0a85b7506e752 100644 (file)
@@ -160,4 +160,8 @@ struct ArgsInfo
 
   // Relocating debuginfo in the format old=new.
   std::vector<std::string> debug_prefix_maps;
+
+  // Compilation directory as passed in -ffile-compilation-dir or
+  // -fdebug-compilation-dir.
+  std::string compilation_dir;
 };
index 465b85e1dc4f70d70644079dc59e01c57736f5b9..4608f92b64d641646600e4f8f791f8112e7572cc 100644 (file)
@@ -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());
+          }
         }
       }
     }
index 141e91d1036400347bfd97fa453412222eef0cf6..bcdddfecd81145566015f011036709502b7da1fb 100644 (file)
@@ -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 (file)
index 0000000..c0b85f5
--- /dev/null
@@ -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 <<EOF >dir1/src/test.c
+#include <stdarg.h>
+#include <test.h>
+EOF
+    cat <<EOF >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
+}
index af0cdaa0f23cd6bc1c41fec29af53afc4e7e35c2..e6823f10f9a9fa213e6a35146f5ffb473e79e921 100644 (file)
@@ -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"