aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-12-12 15:02:40 +0100
committerDmitry Vyukov <dvyukov@google.com>2024-12-12 15:03:51 +0000
commit1cc680471dc68c265d7dd55f80ef7a1de48fa63f (patch)
treec38d7903d6247781c05b97b0e3b868d45b5d6654 /pkg
parent530e80f8ee7c0e39b3e98ed0839a557af2d6192e (diff)
pkg/clangtool: cache combined output
Instead of caching output for each file separately, cache total combined output in a single file. Caching output for each file is not useful in practice, I either use everything cached, or regenerate whole cache. Caching combined output is much more efficient. With function info there are lots of duplication across individual output files. E.g. I am getting 6GB cache for individual files, and only 60MB for the combined cache. Also change how caching works. Remove the flag and always use the cache if it exists. It's much more convinient and safer to use (accidentially not using the cache). The cache file can be removed to force regeneration.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/clangtool/clangtool.go47
1 files changed, 24 insertions, 23 deletions
diff --git a/pkg/clangtool/clangtool.go b/pkg/clangtool/clangtool.go
index 4e2605a48..f0f14501b 100644
--- a/pkg/clangtool/clangtool.go
+++ b/pkg/clangtool/clangtool.go
@@ -22,17 +22,26 @@ import (
)
type Config struct {
- ToolBin string
- KernelSrc string
- KernelObj string
- CacheDir string
- ReuseCache bool
+ ToolBin string
+ KernelSrc string
+ KernelObj string
+ CacheFile string
}
// Run runs the clang tool on all files in the compilation database
// in the kernel build dir and returns combined output for all files.
// It always caches results, and optionally reuses previously cached results.
func Run(cfg *Config) (*declextract.Output, error) {
+ if cfg.CacheFile != "" {
+ data, err := os.ReadFile(cfg.CacheFile)
+ if err == nil {
+ out, err := unmarshal(data)
+ if err == nil {
+ return out, nil
+ }
+ }
+ }
+
dbFile := filepath.Join(cfg.KernelObj, "compile_commands.json")
cmds, err := loadCompileCommands(dbFile)
if err != nil {
@@ -67,22 +76,22 @@ func Run(cfg *Config) (*declextract.Output, error) {
out.Merge(res.out)
}
out.SortAndDedup()
+ if cfg.CacheFile != "" {
+ osutil.MkdirAll(filepath.Dir(cfg.CacheFile))
+ data, err := json.MarshalIndent(out, "", "\t")
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal output data: %w", err)
+ }
+ if err := osutil.WriteFile(cfg.CacheFile, data); err != nil {
+ return nil, err
+ }
+ }
return out, nil
}
func runTool(cfg *Config, dbFile, file string) (*declextract.Output, error) {
relFile := strings.TrimPrefix(strings.TrimPrefix(strings.TrimPrefix(filepath.Clean(file),
cfg.KernelSrc), cfg.KernelObj), "/")
- cacheFile := filepath.Join(cfg.CacheDir, relFile+".json")
- if cfg.ReuseCache {
- data, err := os.ReadFile(cacheFile)
- if err == nil {
- out, err := unmarshal(data)
- if err == nil {
- return out, nil
- }
- }
- }
// Suppress warning since we may build the tool on a different clang
// version that produces more warnings.
data, err := exec.Command(cfg.ToolBin, "-p", dbFile, "--extra-arg=-w", file).Output()
@@ -98,14 +107,6 @@ func runTool(cfg *Config, dbFile, file string) (*declextract.Output, error) {
return nil, err
}
fixupFileNames(cfg, out, relFile)
- normalized, err := json.MarshalIndent(out, "", "\t")
- if err != nil {
- return nil, fmt.Errorf("failed to marshal output data: %w", err)
- }
- osutil.MkdirAll(filepath.Dir(cacheFile))
- if err := osutil.WriteFile(cacheFile, normalized); err != nil {
- return nil, err
- }
return out, nil
}