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
* 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
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")) {
// 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;
};
// 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());
+ }
}
}
}
addtest(color_diagnostics)
addtest(config)
addtest(cpp1)
+addtest(debug_compilation_dir)
addtest(debug_prefix_map)
addtest(depend)
addtest(direct)
--- /dev/null
+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
+}
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"