From 789b5c6b781ae94b62992a885b6a3b434a1c2632 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 31 Mar 2025 09:13:54 +0200 Subject: [PATCH] compileopts: add library version to cached library path This may be a bit of a weird place to put the library path, but otherwise it's difficult to get the pathname for the Config.CFlags function. So I've put it here. This should help to avoid stale library caches. The idea is to increment it every time something changes to a library that means it needs to be recompiled. It's a manual process. --- builder/library.go | 5 ++++- compileopts/config.go | 30 +++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/builder/library.go b/builder/library.go index 53ae5d9d6..ca0ff779f 100644 --- a/builder/library.go +++ b/builder/library.go @@ -15,6 +15,9 @@ import ( // Library is a container for information about a single C library, such as a // compiler runtime or libc. +// +// Note: whenever a library gets changed, the version in compileopts/config.go +// probably also needs to be incremented. type Library struct { // The library name, such as compiler-rt or picolibc. name string @@ -50,7 +53,7 @@ type Library struct { // As a side effect, this call creates the library header files if they didn't // exist yet. func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJob, abortLock func(), err error) { - outdir := config.LibcPath(l.name) + outdir := config.LibraryPath(l.name) archiveFilePath := filepath.Join(outdir, "lib.a") // Create a lock on the output (if supported). diff --git a/compileopts/config.go b/compileopts/config.go index 9fa482952..6cc87aabd 100644 --- a/compileopts/config.go +++ b/compileopts/config.go @@ -8,12 +8,23 @@ import ( "os" "path/filepath" "regexp" + "strconv" "strings" "github.com/google/shlex" "github.com/tinygo-org/tinygo/goenv" ) +// Library versions. Whenever an existing library is changed, this number should +// be added/increased so that existing caches are invalidated. +// +// (This is a bit of a layering violation, this should really be part of the +// builder.Library struct but that's hard to do since we want to know the +// library path in advance in several places). +var libVersions = map[string]int{ + "musl": 2, +} + // Config keeps all configuration affecting the build in a single struct. type Config struct { Options *Options @@ -247,9 +258,9 @@ func MuslArchitecture(triple string) string { return CanonicalArchName(triple) } -// LibcPath returns the path to the libc directory. The libc path will be a libc -// path in the cache directory (which might not yet be built). -func (c *Config) LibcPath(name string) string { +// LibraryPath returns the path to the library build directory. The path will be +// a library path in the cache directory (which might not yet be built). +func (c *Config) LibraryPath(name string) string { archname := c.Triple() if c.CPU() != "" { archname += "-" + c.CPU() @@ -265,6 +276,11 @@ func (c *Config) LibcPath(name string) string { archname += "-" + c.Target.Libc } + // Append a version string, if this library has a version. + if v, ok := libVersions[name]; ok { + archname += "-v" + strconv.Itoa(v) + } + // No precompiled library found. Determine the path name that will be used // in the build cache. return filepath.Join(goenv.Get("GOCACHE"), name+"-"+archname) @@ -351,7 +367,7 @@ func (c *Config) LibcCFlags() []string { case "picolibc": root := goenv.Get("TINYGOROOT") picolibcDir := filepath.Join(root, "lib", "picolibc", "newlib", "libc") - path := c.LibcPath("picolibc") + path := c.LibraryPath("picolibc") return []string{ "-nostdlibinc", "-isystem", filepath.Join(path, "include"), @@ -361,7 +377,7 @@ func (c *Config) LibcCFlags() []string { } case "musl": root := goenv.Get("TINYGOROOT") - path := c.LibcPath("musl") + path := c.LibraryPath("musl") arch := MuslArchitecture(c.Triple()) return []string{ "-nostdlibinc", @@ -371,7 +387,7 @@ func (c *Config) LibcCFlags() []string { "-isystem", filepath.Join(root, "lib", "musl", "include"), } case "wasi-libc": - path := c.LibcPath("wasi-libc") + path := c.LibraryPath("wasi-libc") return []string{ "-nostdlibinc", "-isystem", filepath.Join(path, "include"), @@ -381,7 +397,7 @@ func (c *Config) LibcCFlags() []string { return nil case "mingw-w64": root := goenv.Get("TINYGOROOT") - path := c.LibcPath("mingw-w64") + path := c.LibraryPath("mingw-w64") return []string{ "-nostdlibinc", "-isystem", filepath.Join(path, "include"),