Bazel is more strict about what constitutes a dependency change. It doesn't use mtime on the file, it relies on the checksum. It also considers the command line flags to be part of the cache key.
So, spurious changes (touching a file) will result in a cache hit, while hidden changes (changing an environment flag used by Make) are caught.
This is particularly important if verifiable builds are needed for SoX compliance.
Does it re-read every single source file to find out which were changed? Sounds like a terrible approach. Or it uses mtime first and checksum after that?
Mtime first is unreliable on modern (fast) machines, you can edit a file twice in a single second. I think bazel has a daemon watch for file changes, but I'm not certain of that.
Bazel has a stateful server component that caches information about the build graph and source files in memory. As you said, this allows it to check mtimes first to avoid re-computing hashes for source files.
Bazel can also read source file hashes from the filesystem if the filesystem supports it.
My understanding is that somehow the bazel server tracks all that and keeps a hot process for monitoring the source files somehow to make the file io more bearable.
So, spurious changes (touching a file) will result in a cache hit, while hidden changes (changing an environment flag used by Make) are caught.
This is particularly important if verifiable builds are needed for SoX compliance.