diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-12-12 15:02:40 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-12-12 15:03:51 +0000 |
| commit | 1cc680471dc68c265d7dd55f80ef7a1de48fa63f (patch) | |
| tree | c38d7903d6247781c05b97b0e3b868d45b5d6654 /pkg/clangtool | |
| parent | 530e80f8ee7c0e39b3e98ed0839a557af2d6192e (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/clangtool')
| -rw-r--r-- | pkg/clangtool/clangtool.go | 47 |
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 } |
