github.com/bir3/gocompiler@v0.9.2202/src/cmd/gocmd/internal/cache/default.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cache 6 7 import ( 8 "fmt" 9 "os" 10 "path/filepath" 11 "sync" 12 13 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/base" 14 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/cfg" 15 "github.com/bir3/gocompiler/src/internal/goexperiment" 16 ) 17 18 // Default returns the default cache to use. 19 // It never returns nil. 20 func Default() Cache { 21 defaultOnce.Do(initDefaultCache) 22 return defaultCache 23 } 24 25 var ( 26 defaultOnce sync.Once 27 defaultCache Cache 28 ) 29 30 // cacheREADME is a message stored in a README in the cache directory. 31 // Because the cache lives outside the normal Go trees, we leave the 32 // README as a courtesy to explain where it came from. 33 const cacheREADME = `This directory holds cached build artifacts from the Go build system. 34 Run "go clean -cache" if the directory is getting too large. 35 Run "go clean -fuzzcache" to delete the fuzz cache. 36 See golang.org to learn more about Go. 37 ` 38 39 // initDefaultCache does the work of finding the default cache 40 // the first time Default is called. 41 func initDefaultCache() { 42 dir := DefaultDir() 43 if dir == "off" { 44 if defaultDirErr != nil { 45 base.Fatalf("build cache is required, but could not be located: %v", defaultDirErr) 46 } 47 base.Fatalf("build cache is disabled by GOCACHE=off, but required as of Go 1.12") 48 } 49 if err := os.MkdirAll(dir, 0777); err != nil { 50 base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) 51 } 52 if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { 53 // Best effort. 54 os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) 55 } 56 57 diskCache, err := Open(dir) 58 if err != nil { 59 base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) 60 } 61 62 if v := cfg.Getenv("GOCACHEPROG"); v != "" && goexperiment.CacheProg { 63 defaultCache = startCacheProg(v, diskCache) 64 } else { 65 defaultCache = diskCache 66 } 67 } 68 69 var ( 70 defaultDirOnce sync.Once 71 defaultDir string 72 defaultDirErr error 73 ) 74 75 // DefaultDir returns the effective GOCACHE setting. 76 // It returns "off" if the cache is disabled. 77 func DefaultDir() string { 78 // Save the result of the first call to DefaultDir for later use in 79 // initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that 80 // subprocesses will inherit it, but that means initDefaultCache can't 81 // otherwise distinguish between an explicit "off" and a UserCacheDir error. 82 83 defaultDirOnce.Do(func() { 84 defaultDir = cfg.Getenv("GOCACHE") 85 if filepath.IsAbs(defaultDir) || defaultDir == "off" { 86 return 87 } 88 if defaultDir != "" { 89 defaultDir = "off" 90 defaultDirErr = fmt.Errorf("GOCACHE is not an absolute path") 91 return 92 } 93 94 // Compute default location. 95 dir, err := os.UserCacheDir() 96 if err != nil { 97 defaultDir = "off" 98 defaultDirErr = fmt.Errorf("GOCACHE is not defined and %v", err) 99 return 100 } 101 defaultDir = filepath.Join(dir, "go-build") 102 }) 103 104 return defaultDir 105 }