Joel Rosdahl [Fri, 5 Aug 2022 14:39:29 +0000 (16:39 +0200)]
feat: Improve inode cache robustness
- Only enable the inode cache at compile-time if it's possible to
determine filesystem type.
- Only use the inode cache at run-time if the filesystem type is known
to work with the inode cache instead of refusing just on NFS.
Joel Rosdahl [Wed, 3 Aug 2022 08:04:03 +0000 (10:04 +0200)]
fix: Hash time information on inode cache hit
As mentioned in discussion #1086: If the inode cache is enabled,
hash_source_code_file will on an inode cache hit fail to hash time
information if there are temporal macros in the code. This is because
hash_source_code_string (called from hash_source_code_file via
hash_source_code_file_nocache) on an inode cache miss adds time
information to the hash in case one of those macros were found. However,
on an inode cache hit the return value of hash_source_code_file will be
correctly fetched from the cache, but the hash sum will only be updated
with (the hash of) the include file and not the time information.
The fix is to let the inode cache only cache the effects of hashing the
file and checking for macros, not the hashing of time information since
that's volatile.
After the fix:
- The new do_hash_file function performs file hashing and macro
checking. The inode cache caches this step.
- hash_source_code_file returns a Digest instead of adding data to a
Hash.
- hash_source_code_file calls do_hash_file and then potentially hashes
time information. If there are no temporal macros the returned digest
will be identical to the file hash, otherwise the returned digest will
be of a hash of file content hash + time information.
This also improves hashes that are stored in the direct mode manifest:
Previously they were always the hash of the file content hash but now
they are just the file content hash in the common case when there is no
__DATE__ or __TIMESTAMP__ macro in the file.
Joel Rosdahl [Mon, 1 Aug 2022 12:53:52 +0000 (14:53 +0200)]
fix: Always rewrite dependency file if base_dir is used
[1] added the has_absolute_include_headers variable as a performance
optimization for base_dir/CCACHE_BASEDIR so that the dependency file
only has to be parsed/rewritten when necessary. This is based on the
assumption that if no include file has an absolute path then no rewrite
is needed, but apparently Clang can insert other paths into the
dependency file as well, for instance the asan_blacklist.txt file when
using -fsanitize=address.
Fix this by simply always parsing the dependency file when base_dir is
active.
Joel Rosdahl [Thu, 28 Jul 2022 08:58:05 +0000 (10:58 +0200)]
feat: Improve handling of dependency files
- Cache entries are now shared for different -MT/-MQ options. This is
implemented by (on a cache hit) rewriting the stored dependency file
data to have the correct dependency target before writing it to the
destination. Closes #359.
- An intentional side effect of the above is that the correct dependency
target will be produced even when base_dir/CCACHE_BASEDIR is used -
the dependency target will still be an absolute path. Fixes #1042.
- Buggy support for GCC-specific environment variables
DEPENDENCIES_OUTPUT and SUNPRO_DEPENDENCIES has been removed. When one
of those variables was set, ccache used to store and fetch the content
just as if -MMD or -MD were used. This is however incorrect since GCC
*appends* to the destination file instead of (like -MMD/-MD)
*rewriting* it. Since there is no way for ccache to know what the
compiler appended to the dependency file, we simply can't support it.
Reverts #349.
Joel Rosdahl [Tue, 19 Jul 2022 13:31:34 +0000 (15:31 +0200)]
feat: Don't remove inode cache file on -C/--clear
-C/--clear is tied to the cache directory while the inode cache file is
a temporary file. I think it makes more sense to not consider the inode
cache part of the main cache directory.
Rafael Kitover [Tue, 19 Jul 2022 08:29:27 +0000 (01:29 -0700)]
feat: Download dependencies from the Internet when unavailable (#1112)
Change the behavior of ZSTD_FROM_INTERNET and HIREDIS_FROM_INTERNET to
always be on and only come into affect when the package is not found on
the system by normal means.
Also use the cmake standard module FetchContent for the
download/checksum/unpack logic.
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
Joel Rosdahl [Sun, 17 Jul 2022 19:55:06 +0000 (21:55 +0200)]
fix: Avoid false success for -fcolor-diagnostics probe with GCC
Ccache will produce a false hit in the following scenario, if "cc" is
GCC without being a symlink to "gcc":
1. ccache cc -c example.c # adds a cache entry
2. ccache cc -c example.c -fcolor-diagnostics # unexpectedly succeeds
(Most major Linux distributions install cc as a symlink to gcc, and then
the problem doesn't show up since ccache then is able to guess that the
compiler is GCC.)
This bug was introduced by [1] which tried to make yet another tweak of
the color diagnostics guessing/probing by no longer rejecting
-fcolor-diagnostics for an unknown compiler, based on the assumption
that the probing call (speculatively adding -fdiagnostics-color) is only
made when we have guessed a GCC compiler. Unfortunately, this broke the
fix in [2] when the compiler is unknown.
All of this is inherently brittle and I don't see any good way to make
it better with the current compiler guessing approach and adding options
speculatively. The cure is to start doing proper compiler identification
instead (#958). Until that is done, the only reasonable fix is to avoid
doing anything related to color diagnostics flags when the compiler is
unknown. This means that an unknown compiler from now on won't produce
colors when used via ccache even if the compiler actually is GCC or
Clang.
Joel Rosdahl [Sun, 17 Jul 2022 11:43:22 +0000 (13:43 +0200)]
feat: Add support for GCC -fprofile-abs-path option
Note: -fprofile-abs-path makes the compiler include absolute paths based
on actual CWD in the .gcno file. We therefore need to include the actual
CWD in the hash in order not to get false positive cache hits. To opt
out of this, set "gcno_cwd" sloppiness.
Joel Rosdahl [Tue, 5 Jul 2022 18:04:25 +0000 (20:04 +0200)]
enhance: Improve lock file implementation
This commit improves brings two improvements to the lock file
implementation:
1. Support for long-lived locks.
2. Support for non-blocking lock acquisition.
There are now two types of lock file classes: ShortLivedLockFile and
LongLivedLockFile. On Windows the implementations are identical. On
other systems, LongLivedLockFile creates a separate "alive file" whose
mtime will be updated regularly by a helper thread until the lock is
released. This makes it possible for another process to wait for the
lock indefinitely but also to know then a lock is stale and can be
broken. The ShortLivedLockFile class works like the lock file class used
to work before: it considers a lock stale after waiting for two seconds
and noticing that the symlink target has not changed during that time.
ShortLivedLockFile is to be used when the lock is expected to be held
for a very short time so that it's a waste of resources to start a
helper thread to keep the lock alive.
On some systems it would be possible to update mtime of the symlink
itself instead of a separate file, but that does not seem to be portable
enough.
Also worth mentioning is that the reason to not use proper fcntl/flock
locks on non-Windows systems is to continue supporting a cache directory
on NFS since file locks on NFS don't have a good track record.
Joel Rosdahl [Sat, 18 Jun 2022 18:08:10 +0000 (20:08 +0200)]
fix: Use a cleanup stamp instead of directory timestamp for cleanup
In order to know when to clean up the temporary directory, ccache checks
mtime of $CCACHE_DIR and updates it to "now" on cleanup. This doesn't
work well when the configuration file is modified often since that also
updates the same mtime.
Fix this by using a separate cleanup stamp file instead.
Joel Rosdahl [Sat, 18 Jun 2022 17:55:02 +0000 (19:55 +0200)]
fix: Clean up temporary dir if it's left the default
Cleanup of the temporary directory is done if it is $CCACHE_DIR/tmp,
which used to be the default until [1] where the default was changed to
/run/user/$UID/ccache-tmp. Improve this so that cleanup happens if the
temporary directory is equal to the default regardless of the default.
Joel Rosdahl [Sat, 11 Jun 2022 12:13:02 +0000 (14:13 +0200)]
feat: Include timestamp in per-object debug filenames
Including a timestamp in the filenames makes it easier to compare two
builds without having to save previous debug files before the second
build. It also makes sure debug files won't be overwritten if an object
file is compiled several times during one build.
Joel Rosdahl [Fri, 10 Jun 2022 14:17:03 +0000 (16:17 +0200)]
feat: Support masquerading as a compiler via copy or hard link
Setting up ccache to masquerade as a compiler has always meant using
symbolic links, but there is no technical reason why that has to be the
case. This commit adds support for masquerading via a copy or hard link
of the ccache executable as well. This is mostly useful on platforms or
file systems where symbolic links are not supported.
Joel Rosdahl [Fri, 10 Jun 2022 14:12:27 +0000 (16:12 +0200)]
feat: Set CCACHE_DISABLE when calling compiler
If ccache for some reason executes a compiler that in turn calls ccache
then ccache will be run twice (and will potentially store two different
result in the cache since the compiler identications differ), which is
not very useful. This could for instance happen if the compiler is a
wrapper script that in turn calls "ccache $compiler ...".
Improve this by setting CCACHE_DISABLE when executing the compiler. Any
subsequent ccache invocations will then fall back to running the real
compiler.
Joel Rosdahl [Tue, 7 Jun 2022 14:53:44 +0000 (16:53 +0200)]
fix: Use correct umask when populating primary cache from secondary
Util::get_umask retrieves the process's umask and caches it to avoid
some system calls. This doesn't interact well now when using UmaskScope
to change umask temporarily since Util::get_umask then only sometimes
returns the correct value. This leads to the incorrect umask being used
when writing cache entries to the primary storage for secondary storage
hits.
Joel Rosdahl [Tue, 7 Jun 2022 13:12:03 +0000 (15:12 +0200)]
fix: Create temporary file with cpp extension instead of hard linking
[1] added a suitable file extension to the temporary file used for
capturing the preprocessed output by creating a hard link. This fails
when the temporary directory is on a file system that doesn't support
hard links.
Fix this by making it possible to pass a suffix to TemporaryFile and
passing the proper cpp suffix for the tmp stdout file instead of
creating a hard link as an alias.
The hard link in question is used in get_result_key_from_cpp to create
an alias of file that captures stdout from the preprocessor, where the
alias has the correct cpp extension. It can't just be a copy since
do_execute writes to the original name. See #1079.
Joel Rosdahl [Mon, 6 Jun 2022 18:46:09 +0000 (20:46 +0200)]
fix: Work around problem with GCC in util::ends_with
The util::ends_with implementation is taken directly from the
implementation suggestion in the C++20 standard, but it produces a
stringop-overread warning with GCC 11.2. There's either some subtle
aspect to this that I don't understand or a compiler bug, but let's work
around it by tweaking the implementation.
Joel Rosdahl [Wed, 11 May 2022 17:57:50 +0000 (19:57 +0200)]
feat: Improve --show-stats
- Added percentage for most values.
- All indented values now have their total count equal to the parent
value.
- Moved presentation of {direct,preprocessed}_cache_{hit,miss}
counters to a separate "Successful lookups" section.
- Removed "Use the -v/--verbose option for more details." from
--show-stats output since it's a bit wordy.