Skip to content

Conversation

hebasto
Copy link
Member

@hebasto hebasto commented Sep 10, 2024

To maximize performance, it is essential to follow the recommendations in the Productivity Notes: set the base_dir Ccache configuration option or use the CCACHE_BASEDIR environment variable:

$ export CCACHE_BASEDIR=$HOME

Here are examples of usage on Ubuntu 24.04:

  1. Across different worktrees:
$ export CCACHE_DIR=$(mktemp -d)
$ git worktree add ../wt_1 4d3f360e2af94f4ed46dc0943196d548da82003e
$ pushd ../wt_1
$ cmake -B build -DWITH_CCACHE=ON
$ cmake --build build -t bitcoind -j $(nproc)
$ popd
$ git worktree add ../wt_2 4d3f360e2af94f4ed46dc0943196d548da82003e
$ pushd ../wt_2
$ cmake -B build -DWITH_CCACHE=ON
$ ccache --zero-stats
$ cmake --build build -t bitcoind -j $(nproc)
$ popd
$ ccache --show-stats
Cacheable calls:    302 / 302 (100.0%)
  Hits:             302 / 302 (100.0%)
    Direct:         302 / 302 (100.0%)
    Preprocessed:     0 / 302 ( 0.00%)
  Misses:             0 / 302 ( 0.00%)
Local storage:
  Cache size (GiB): 0.2 / 5.0 ( 3.31%)
  Hits:             302 / 302 (100.0%)
  Misses:             0 / 302 ( 0.00%)
  1. Across different build trees:
$ export CCACHE_DIR=$(mktemp -d)
$ cmake -B build_1 -DWITH_CCACHE=ON
$ cmake --build build_1 -t bitcoind -j $(nproc)
$ cmake -B build_2 -DWITH_CCACHE=ON
$ ccache --zero-stats
$ cmake --build build_2 -t bitcoind -j $(nproc)
$ ccache --show-stats
Cacheable calls:    302 / 302 (100.0%)
  Hits:             302 / 302 (100.0%)
    Direct:         302 / 302 (100.0%)
    Preprocessed:     0 / 302 ( 0.00%)
  Misses:             0 / 302 ( 0.00%)
Local storage:
  Cache size (GiB): 0.2 / 5.0 ( 3.31%)
  Hits:             302 / 302 (100.0%)
  Misses:             0 / 302 ( 0.00%)

This PR addresses this comment:

However, ccache does not hit across two different build dirs, compiling the same commit.


Fixes #31771.

Form https://github.com/bitcoin/bitcoin/actions/runs/13215680798/job/36894673006:

...
Treat compiler warnings as errors ..... ON
Use ccache for compiling .............. Built-in ccache support for the 'Visual Studio 17 2022' generator is not available.


-- Configuring done (300.1s)
-- Generating done (1.2s)
-- Build files have been written to: D:/a/bitcoin/bitcoin/build

@DrahtBot
Copy link
Contributor

DrahtBot commented Sep 10, 2024

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/30861.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK ryanofsky
Concept ACK maflcko
Stale ACK l0rinc, TheCharlatan, davidgumberg

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

No conflicts as of last run.

@fanquake
Copy link
Member

100% cache hit rate is expected.

I tested this, and got about 90%:

ccache -C
ccache --zero-stats

cmake -B some_build_dir -DWITH_CCACHE=ON
cmake --build some_build_dir -j17

ccache --show-stats
Cacheable calls:    445 /  445 (100.0%)
  Hits:               0 /  445 ( 0.00%)
    Direct:           0
    Preprocessed:     0
  Misses:           445 /  445 (100.0%)
Local storage:
  Cache size (GiB): 0.2 / 30.0 ( 0.75%)
  Hits:               0 /  445 ( 0.00%)
  Misses:           445 /  445 (100.0%)

ccache --zero-stats

cmake -B /tmp/some_other_build_dir -DWITH_CCACHE=ON
cmake --build /tmp/some_other_build_dir -j17

ccache --show-stats
Cacheable calls:    445 /  445 (100.0%)
  Hits:             394 /  445 (88.54%)
    Direct:         394 /  394 (100.0%)
    Preprocessed:     0 /  394 ( 0.00%)
  Misses:            51 /  445 (11.46%)
Local storage:
  Cache size (GiB): 0.2 / 30.0 ( 0.76%)
  Hits:             394 /  445 (88.54%)
  Misses:            51 /  445 (11.46%)

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK 66b73bb. This seems like a really helpful improvement, but did have some questions about it below.

list(APPEND CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE})
foreach(lang IN ITEMS C CXX OBJCXX)
set(CMAKE_${lang}_COMPILER_LAUNCHER
${CCACHE_EXECUTABLE} base_dir=${CMAKE_BINARY_DIR}
Copy link
Contributor

@ryanofsky ryanofsky Sep 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In commit "build: Improve ccache performance for different build directories" (66b73bb)

Reading https://ccache.dev/manual/latest.html#_configuration_options it seems like it would make sense in most cases to set base_dir to CMAKE_SOURCE_DIR not CMAKE_BINARY_DIR.

For example if CMAKE_SOURCE_DIR is /home/bitcoin and CMAKE_BINARY_DIR is /home/bitcoin/build, it sounds like ccmake will not rewrite the include path -I/home/bitcoin/src to -I../src for greater cache reuse if base_dir=CMAKE_BINARY_DIR is used, because /home/bitcoin/src is not a subdirectory of /home/bitcoin/build

But it would rewrite the include path if CMAKE_SOURCE_DIR were used, because /home/bitcoin/src is a subdirectory of /home/bitcoin.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CCACHE_BASEDIR=${CMAKE_BINARY_DIR} is effective when building in different build directories from the same source directory.

CCACHE_BASEDIR=${CMAKE_SOURCE_DIR} works for building from different source directories.

We need to choose one of these two options.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CCACHE_BASEDIR=${CMAKE_BINARY_DIR} is effective when building in different build directories from the same source directory.

CCACHE_BASEDIR=${CMAKE_SOURCE_DIR} works for building from different source directories.

We need to choose one of these two options.

Thanks, that clarifies a lot. I only do the second not the first, because I use git worktrees, and I assumed this PR was trying to make git worktrees and multiple checkouts work better. Maybe people who work on build systems are likely to have many different build directories inside the same source directory, but that would seem like an unusual thing for most other developers. Especially to have multiple build directories building with the same compilation options, because if compile options are different ccache command lines wouldn't match anyway.

Is there a real use-case for having multiple different build directories with the same compilation options in the same source directory? And optimizing to have cache hits in that case?

Also maybe I need to think about it more, but I'm not sure why choosing CMAKE_BINARY_DIR would be better than CMAKE_SOURCE_DIR in either case as long a CMAKE_BINARY_DIR is a subdirectory of CMAKE_SOURCE_DIR. Are we trying to optimize for cases where CMAKE_BINARY_DIR is not a subdirectory?

Copy link
Member Author

@hebasto hebasto Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe I need to think about it more, but I'm not sure why choosing CMAKE_BINARY_DIR would be better than CMAKE_SOURCE_DIR in either case as long a CMAKE_BINARY_DIR is a subdirectory of CMAKE_SOURCE_DIR. Are we trying to optimize for cases where CMAKE_BINARY_DIR is not a subdirectory?

I don't think it is related to whether CMAKE_BINARY_DIR is a subdirectory of CMAKE_SOURCE_DIR or not.

Due to

include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})

all objects are compiled with the -I/absolute/path/to/build/dir and -I/absolute/path/to/source/dir flags, and any difference in either will trigger a cache miss.

The "Cache compilations with ccache" section of the Productivity Notes still applicable for this PR branch except for the last commit, which was mostly motivated by #30811 (comment).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is related to whether CMAKE_BINARY_DIR is a subdirectory of CMAKE_SOURCE_DIR or not.

Ccache documentation describes behavior of base_dir: "ccache will rewrite absolute paths into paths relative to the current working directory, but only absolute paths that begin with base_dir"

So if CMAKE_BINARY_DIR is a subdirectory of CMAKE_SOURCE_DIR, and base_dir is specified as CMAKE_SOURCE_DIR, then that should be a strict improvement because it will allow cache hits across multiple source directories, and multiple build directories, as long as build directories are not outside the source directories.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

last commit, which was mostly motivated by #30811 (comment).

Sorry, I was just testing, not trying to imply that this is the common case. Using worktrees (different source dirs) seems more common than different build dirs for the same cmake config.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if CMAKE_BINARY_DIR is a subdirectory of CMAKE_SOURCE_DIR, and base_dir is specified as CMAKE_SOURCE_DIR, then that should be a strict improvement because it will allow cache hits across multiple source directories, and multiple build directories, as long as build directories are not outside the source directories.

For the latter case, using different build directories will result in cache misses anyway, right?

Anyway, I agree with @maflcko and @ryanofsky that using git worktrees should be prioritised.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if CMAKE_BINARY_DIR is a subdirectory of CMAKE_SOURCE_DIR, and base_dir is specified as CMAKE_SOURCE_DIR, then that should be a strict improvement because it will allow cache hits across multiple source directories, and multiple build directories, as long as build directories are not outside the source directories.

For the latter case, using different build directories will result in cache misses anyway, right?

It seems like that should be true but I haven't experimented or thought about this much and am just going off of the documentation. If cmake adds include paths inside the build directory, maybe for generated headers, or for headers are copied or linked to from there, I could see imagine CMAKE_BINARY_DIR being better to use than CMAKE_SOURCE_DIR in some cases. But naively I would expect CMAKE_SOURCE_DIR being better in most cases, so that led me to ask the question.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryanofsky

I only do the second not the first, because I use git worktrees...

Thanks for your feedback. Your concerns should be addressed in the recent push.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked to work equally well across both Git's wortktrees and build trees.

@DrahtBot
Copy link
Contributor

🚧 At least one of the CI tasks failed.
Debug: https://github.com/bitcoin/bitcoin/runs/29930405099

Hints

Make sure to run all tests locally, according to the documentation.

The failure may happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

list(APPEND CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE})
foreach(lang IN ITEMS C CXX OBJCXX)
set(CMAKE_${lang}_COMPILER_LAUNCHER
${CCACHE_EXECUTABLE} base_dir=${CMAKE_BINARY_DIR}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In commit "build: Improve ccache performance for different build directories" (66b73bb)

Now that base_dir is set by the build system, would it be fine to remove this from the prod notes?

$ git grep --line-number base_dir doc/productivity.md 
doc/productivity.md:42:base_dir = /home/yourname  # or wherever you keep your source files
doc/productivity.md:45:Note: base_dir is required for ccache to share cached compiles of the same file across different repositories / paths; it will only do this for paths under base_dir. So this option is required for effective use of ccache with git worktrees (described below).
doc/productivity.md:47:You _must not_ set base_dir to "/", or anywhere that contains system headers (according to the ccache docs).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the recent push, this branch relies on setting the base_dir option by the user because the required value depends on actual user's build environment.

@hebasto
Copy link
Member Author

hebasto commented Sep 11, 2024

100% cache hit rate is expected.

I tested this, and got about 90%:

ccache -C
ccache --zero-stats

cmake -B some_build_dir -DWITH_CCACHE=ON
cmake --build some_build_dir -j17

ccache --show-stats
Cacheable calls:    445 /  445 (100.0%)
  Hits:               0 /  445 ( 0.00%)
    Direct:           0
    Preprocessed:     0
  Misses:           445 /  445 (100.0%)
Local storage:
  Cache size (GiB): 0.2 / 30.0 ( 0.75%)
  Hits:               0 /  445 ( 0.00%)
  Misses:           445 /  445 (100.0%)

ccache --zero-stats

cmake -B /tmp/some_other_build_dir -DWITH_CCACHE=ON
cmake --build /tmp/some_other_build_dir -j17

ccache --show-stats
Cacheable calls:    445 /  445 (100.0%)
  Hits:             394 /  445 (88.54%)
    Direct:         394 /  394 (100.0%)
    Preprocessed:     0 /  394 ( 0.00%)
  Misses:            51 /  445 (11.46%)
Local storage:
  Cache size (GiB): 0.2 / 30.0 ( 0.76%)
  Hits:             394 /  445 (88.54%)
  Misses:            51 /  445 (11.46%)

On Ubuntu 24.04, I've got:

$ ccache --show-stats 
Cacheable calls:    456 / 456 (100.0%)
  Hits:             456 / 456 (100.0%)
    Direct:         456 / 456 (100.0%)
    Preprocessed:     0 / 456 ( 0.00%)
  Misses:             0 / 456 ( 0.00%)
Local storage:
  Cache size (GiB): 5.0 / 5.0 (100.0%)
  Hits:             456 / 456 (100.0%)
  Misses:             0 / 456 ( 0.00%)

for the build in the second directory.

@fanquake What is your system and Ccache version?

@fanquake
Copy link
Member

What is your system and Ccache version?

That was on a macOS machine, with 4.10.2. Retested just now, and got the same: Hits: 394 / 445 (88.54%).

@fanquake
Copy link
Member

Just tested the same on a Fedora box (ccache 4.10.2) and ended up with Hits: 447 / 528 (84.66%).

@hebasto
Copy link
Member Author

hebasto commented Sep 11, 2024

Just tested the same on a Fedora box (ccache 4.10.2) and ended up with Hits: 447 / 528 (84.66%).

What if you ccache --zero-stats after configuring for a new build tree, just before building?

On Fedora, ccache masquerades as a compiler, so all compilations during configuration can affect the final hit rate.

@maflcko
Copy link
Member

maflcko commented Sep 12, 2024

Needs rebase and CI failures fixed (they are true ones)

@fanquake
Copy link
Member

What if you ccache --zero-stats after configuring for a new build tree, just before building?

In that case on Fedora it is Hits: 446 / 446 (100.0%), with Uncacheable calls: 12 / 458 ( 2.62%).

@hebasto hebasto marked this pull request as draft September 12, 2024 13:40
@hebasto hebasto force-pushed the 240910-ccache branch 2 times, most recently from 7dd1442 to 9ea2db2 Compare September 12, 2024 14:18
@hebasto
Copy link
Member Author

hebasto commented Sep 12, 2024

What if you ccache --zero-stats after configuring for a new build tree, just before building?

In that case on Fedora it is Hits: 446 / 446 (100.0%), with Uncacheable calls: 12 / 458 ( 2.62%).

If ccache --show-stats --verbose outputs:

Uncacheable calls:      12 / 458 ( 2.62%)
  Called for linking:   12 /  12 (100.0%)

this is expected on systems where ccache masquerades as a compiler.

@hebasto hebasto marked this pull request as ready for review September 14, 2024 16:33
@hebasto
Copy link
Member Author

hebasto commented Sep 14, 2024

The PR has been reworked to keep compatibility with git worktrees. See this discussion.

The PR description has been updated accordingly.

@fanquake
Copy link
Member

Seems like you missed some review comments?
https://github.com/bitcoin/bitcoin/pull/30861/files#r1752126150
#30861 (comment)

Seems like #30861 (comment) is now also more relevant given #30905, so it'd be good to know how this is going to be handed going forward.

@DrahtBot
Copy link
Contributor

Guix builds (on x86_64) [untrusted test-only build, possibly unsafe, not for production use]

File commit 0c4ff18
(master)
commit 441c599
(master and this pull)
SHA256SUMS.part 79b358d3fd281b65... 7480bb06dfe11941...
*-aarch64-linux-gnu-debug.tar.gz 4e496d0eb67133bf... 5b16ef1c658f30cc...
*-aarch64-linux-gnu.tar.gz 43490ff6ab9a74e2... 457bb82ec92bb12f...
*-arm-linux-gnueabihf-debug.tar.gz 38c68631f041e4d8... 6dd507cd8d0080f1...
*-arm-linux-gnueabihf.tar.gz a80c39716b285df7... 2990906bac85028b...
*-arm64-apple-darwin-unsigned.tar.gz 59dce49b541dff6d... eecbd5bd38a1a514...
*-arm64-apple-darwin-unsigned.zip acb355306dcbd43c... f58bd171b8bd2a6a...
*-arm64-apple-darwin.tar.gz b6fa18bedb7fe497... 5013a4b3cb403494...
*-powerpc64-linux-gnu-debug.tar.gz ab07199c08dcbf3d... f13eb7b3069725d6...
*-powerpc64-linux-gnu.tar.gz c93841f69a8a21f2... bc628724a63587cd...
*-riscv64-linux-gnu-debug.tar.gz fa11806d89e9abd7... 3fbcbb305f44259e...
*-riscv64-linux-gnu.tar.gz 379cad9361252115... fb05d80a1c7a7f1b...
*-x86_64-apple-darwin-unsigned.tar.gz 03fd8b75278b79c7... 8c1dd1bdfbe1a736...
*-x86_64-apple-darwin-unsigned.zip e7f5613fc474ffdb... da01e15f8015fac3...
*-x86_64-apple-darwin.tar.gz 9c1621a91eba759d... 048e72e703a89270...
*-x86_64-linux-gnu-debug.tar.gz 0aaee8826bab2f2b... fe32bc318f19c957...
*-x86_64-linux-gnu.tar.gz 163cb7ffd9eec265... 22f3e58d2456792d...
*.tar.gz 73ef39f7a7c8ccd9... cfc14f97ef17ca32...
guix_build.log 2c42f4ee42e6a171... 2ce4aafa975c22ea...
guix_build.log.diff 0827acda3664ba74...

To enhance the user experience when using ccache, we utilize the CMake's
`<LANG>_COMPILER_LAUNCHER` target properties, which are only supported
by the Makefile and Ninja generators.
To maximize performance, it is essential to follow the recommendations
in the Productivity Notes: set the `base_dir` ccache configuration
option or use the `CCACHE_BASEDIR` environment variable.
@hebasto
Copy link
Member Author

hebasto commented Feb 8, 2025

Thanks to all for the review!

Your feedback has been addressed.

Additionally, #31771 has been fixed.

Comment on lines +24 to +26
list(APPEND configure_warnings
"CMAKE_${lang}_COMPILER_LAUNCHER is already set. Skipping built-in ccache support for ${lang}."
)
Copy link
Contributor

@davidgumberg davidgumberg Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is making this a configure_warning compatible with #31665? Maybe it would be a benefit if CI complained when unintentionally skipping ccache?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind elaborating on your suggestion?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better expressed as: Is trying to both override the compiler launcher and make configure_warnings errors a use case that should be supported? If so, making this message a configure_warning is incompatible with #31665 since that makes configure_warnings fatal errors if WCONFIGURE_ERROR=ON.

If it is not a use case that should be supported, then making this message a configure_warning might be good together with #31665, since it would cause an error in CI if ccache ever got disabled because a compiler launcher was set, but maybe there isn't a realistic situation where something like that could happen unintentionally.

Copy link
Contributor

@davidgumberg davidgumberg Feb 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also fair if you think #31665 is a bad approach and this is more evidence of that.

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK 82a9f24 since this seems like a reasonable change, but I'm confused about why it actually doing anything and agree with stickies concern #30861 (review) that forcing CCACHE_NOHASHDIR=1 might not be ideal, especially because according to documentation for hash_dir it sounds like if CWD is not hashed and -fdebug-prefix-map is not used, objects could be built with the wrong debug information.

But mainly I'm just confused why this change has any effect at all given that hash_dir documentation says "The CWD will not be included in the hash if base_dir is set (and matches the CWD) and the compiler option -fdebug-prefix-map is used." It seems like we are doing (or requiring) both of these things so I don't see why the hash_dir setting should change anything. The results posted #30861 (comment) do seem to show it having an effect though, so think I must be misunderstanding something.

Also, I'm confused by why we need to require manually setting base_dir instead of setting it automatically to CMAKE_SOURCE_DIR. I don't understand comment
#30861 (comment) about why this would fail to cache multiple build directories, since most of the time build directories will be under the source directory.

if(NOT MSVC)
# The <LANG>_COMPILER_LAUNCHER target property, used to integrate
# Ccache, is supported only by the Makefiles and Ninja generators.
if(CMAKE_GENERATOR MATCHES "Make|Ninja")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #30861 (comment)

In commit "cmake: Clarify ccache support for different generators" (c19a187)

Thanks! Reworked per your feedback.

It is hard to tell from reading this thread if the "I think we could drop this check entirely" suggestion and other suggestions have been addressed or not. The check appears to be unchanged. Would be good to clear this up.

@hebasto
Copy link
Member Author

hebasto commented Feb 20, 2025

Also, I'm confused by why we need to require manually setting base_dir instead of setting it automatically to CMAKE_SOURCE_DIR.

Setting base_dir to CMAKE_SOURCE_DIR won't be helpful in cases when a worktree or a build directory resides outside of the repository root, for example, it is a sibling directory.

@ryanofsky
Copy link
Contributor

ryanofsky commented Feb 20, 2025

Setting base_dir to CMAKE_SOURCE_DIR won't be helpful in cases when a worktree or a build directory resides outside of the repository root, for example, it is a sibling directory.

I don't understand why it wouldn't be helpful when a worktree is outside the repository root. If source directories are /tree1/ and /tree2 and build directories are /tree1/build and /tree2/build I would expect source paths like src/init.cpp to be treated like ../src/init.cpp in both cases and for the caching to work. Would also expect this to generalize regardless of how the build directories are named as long as they are at the same level relative to the source directory. But, very possible I'm missing something since I haven't tested this.

I do understand that setting base_dir to CMAKE_SOURCE_DIR will not work if developers are placing their build directories completely outside of their source directories, or at inconsistent depths within their source directories, but this seems much less common and not really a consideration if we are just deciding on a default base_dir value.

Separately, I'm still confused about why setting hash_dir has an effect (mentioned #30861 (review)) so there are definitely things I'm not grasping here, but in any case this change seems at least safe and I am happy if it works in practice.

@hebasto
Copy link
Member Author

hebasto commented Feb 20, 2025

I do understand that setting base_dir to CMAKE_SOURCE_DIR will not work if developers are placing their build directories completely outside of their source directories, or at inconsistent depths within their source directories, but this seems much less common and not really a consideration if we are just deciding on a default base_dir value.

Right. As for the PR author, it was not clear to me which cases are more common and which are less common, so I tried to take a more general approach.

Ultimately, the mentioning of base_dir might be dropped, leaving it up to the user.

@hebasto
Copy link
Member Author

hebasto commented Feb 21, 2025

... I'm confused about why it actually doing anything and agree with stickies concern #30861 (review) that forcing CCACHE_NOHASHDIR=1 might not be ideal, especially because according to documentation for hash_dir it sounds like if CWD is not hashed and -fdebug-prefix-map is not used, objects could be built with the wrong debug information.

I'm wondering in which scenarios a user might wish to disable the -fdebug-prefix-map flag?

But mainly I'm just confused why this change has any effect at all given that hash_dir documentation says "The CWD will not be included in the hash if base_dir is set (and matches the CWD) and the compiler option -fdebug-prefix-map is used." It seems like we are doing (or requiring) both of these things so I don't see why the hash_dir setting should change anything. The results posted #30861 (comment) do seem to show it having an effect though, so think I must be misunderstanding something.

For the CWD to be omitted from hashing when a base_dir is set, it must match the base_dir.

@maflcko
Copy link
Member

maflcko commented Feb 25, 2025

Looks like this missed feature-freeze and can be removed from the milestone for now?

@maflcko maflcko removed this from the 29.0 milestone Feb 25, 2025
@fanquake
Copy link
Member

I'm going to re-add it, it'd be good to fix because there are a number of regressions here.

@fanquake fanquake added this to the 29.0 milestone Feb 25, 2025
@maflcko
Copy link
Member

maflcko commented Feb 25, 2025

There is also a risk of adding even more regressions due to CCACHE_NOHASHDIR. I don't know if it is related, but currently one can not use callgrind_annotate, even with --include=<src_dir>. It is likely unrelated, but I wonder if the patch here makes it worse.

Edit: Unrelated issue split up to #31957

@hebasto
Copy link
Member Author

hebasto commented Mar 4, 2025

Closing and marking "Up for grabs".

@ryanofsky
Copy link
Contributor

re: #30861 (comment)

There is also a risk of adding even more regressions due to CCACHE_NOHASHDIR

@maflcko could you clarify this? Are you talking about the problem where objects might be built with the wrong paths in debug info mentioned #30861 (review) or a different problem? The debug path problem didn't seem like a real risk as long as we are specifying -fdebug-prefix-map.


re: #30861 (comment)

I'm wondering in which scenarios a user might wish to disable the -fdebug-prefix-map flag?

I don't think there are any. Just mentioned this because -fdebug-prefix-map seems to be added conditionally in our build.

But mainly I'm just confused why this change has any effect at all given that hash_dir documentation says "The CWD will not be included in the hash if base_dir is set (and matches the CWD) and the compiler option -fdebug-prefix-map is used." It seems like we are doing (or requiring) both of these things so I don't see why the hash_dir setting should change anything. The results posted #30861 (comment) do seem to show it having an effect though, so think I must be misunderstanding something.

For the CWD to be omitted from hashing when a base_dir is set, it must match the base_dir.

Right, the documentation I quoted says the base_dir must match the CWD. But that just means the CWD needs "begin with base_dir" as stated in the base_dir documentation. So it seems like regardless of how hash_dir is set, CWD should not be included in the hash anyway, so it is unclear why this PR has any effect.

The change seems good and does seem to be helping according to #30861 (comment) but I don't understand how it actually works if the documentation is accurate.

davidgumberg added a commit to davidgumberg/bitcoin that referenced this pull request Mar 5, 2025
Without `hash_dir=false`, ccache will not be shared across worktrees and
buildtrees, since ccache will include the current working directory in
hashes.

See bitcoin#30861 and
https://ccache.dev/manual/4.10.html#config_hash_dir
davidgumberg added a commit to davidgumberg/bitcoin that referenced this pull request Mar 5, 2025
Without `hash_dir=false`, ccache will not be shared across worktrees and
buildtrees, since ccache will include the current working directory in
hashes.

See bitcoin#30861 and
https://ccache.dev/manual/4.10.html#config_hash_dir
@hebasto
Copy link
Member Author

hebasto commented Mar 9, 2025

I'm wondering in which scenarios a user might wish to disable the -fdebug-prefix-map flag?

I don't think there are any. Just mentioned this because -fdebug-prefix-map seems to be added conditionally in our build.

Specifically, which condition are you referring to?

@ryanofsky
Copy link
Contributor

I don't think there are any. Just mentioned this because -fdebug-prefix-map seems to be added conditionally in our build.

Specifically, which condition are you referring to?

-fdebug-prefix-map is only added if try_append_cxx_flags succeeds and if the compilation target explicitly links against core_interface. It's reasonable to assume that these things are always true, but since correctness of the output when CCACHE_NOHASHDIR=1 is used seems to depend on them it would be good to document the assumptions where CCACHE_NOHASHDIR=1 is used. in general if code in one part of the build is relying on apparently unrelated code in a different part of the build that kind of thing is good to point out in case the assumptions are broken later.

@fanquake fanquake removed this from the 29.0 milestone Jul 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

cmake: incorrectly reporting MSVC as using ccache