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.
This commit is contained in:
Ayke van Laethem
2025-03-31 09:13:54 +02:00
committed by Ron Evans
parent dcf609defb
commit 789b5c6b78
2 changed files with 27 additions and 8 deletions
+4 -1
View File
@@ -15,6 +15,9 @@ import (
// Library is a container for information about a single C library, such as a // Library is a container for information about a single C library, such as a
// compiler runtime or libc. // 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 { type Library struct {
// The library name, such as compiler-rt or picolibc. // The library name, such as compiler-rt or picolibc.
name string name string
@@ -50,7 +53,7 @@ type Library struct {
// As a side effect, this call creates the library header files if they didn't // As a side effect, this call creates the library header files if they didn't
// exist yet. // exist yet.
func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJob, abortLock func(), err error) { 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") archiveFilePath := filepath.Join(outdir, "lib.a")
// Create a lock on the output (if supported). // Create a lock on the output (if supported).
+23 -7
View File
@@ -8,12 +8,23 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv"
"strings" "strings"
"github.com/google/shlex" "github.com/google/shlex"
"github.com/tinygo-org/tinygo/goenv" "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. // Config keeps all configuration affecting the build in a single struct.
type Config struct { type Config struct {
Options *Options Options *Options
@@ -247,9 +258,9 @@ func MuslArchitecture(triple string) string {
return CanonicalArchName(triple) return CanonicalArchName(triple)
} }
// LibcPath returns the path to the libc directory. The libc path will be a libc // LibraryPath returns the path to the library build directory. The path will be
// path in the cache directory (which might not yet be built). // a library path in the cache directory (which might not yet be built).
func (c *Config) LibcPath(name string) string { func (c *Config) LibraryPath(name string) string {
archname := c.Triple() archname := c.Triple()
if c.CPU() != "" { if c.CPU() != "" {
archname += "-" + c.CPU() archname += "-" + c.CPU()
@@ -265,6 +276,11 @@ func (c *Config) LibcPath(name string) string {
archname += "-" + c.Target.Libc 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 // No precompiled library found. Determine the path name that will be used
// in the build cache. // in the build cache.
return filepath.Join(goenv.Get("GOCACHE"), name+"-"+archname) return filepath.Join(goenv.Get("GOCACHE"), name+"-"+archname)
@@ -351,7 +367,7 @@ func (c *Config) LibcCFlags() []string {
case "picolibc": case "picolibc":
root := goenv.Get("TINYGOROOT") root := goenv.Get("TINYGOROOT")
picolibcDir := filepath.Join(root, "lib", "picolibc", "newlib", "libc") picolibcDir := filepath.Join(root, "lib", "picolibc", "newlib", "libc")
path := c.LibcPath("picolibc") path := c.LibraryPath("picolibc")
return []string{ return []string{
"-nostdlibinc", "-nostdlibinc",
"-isystem", filepath.Join(path, "include"), "-isystem", filepath.Join(path, "include"),
@@ -361,7 +377,7 @@ func (c *Config) LibcCFlags() []string {
} }
case "musl": case "musl":
root := goenv.Get("TINYGOROOT") root := goenv.Get("TINYGOROOT")
path := c.LibcPath("musl") path := c.LibraryPath("musl")
arch := MuslArchitecture(c.Triple()) arch := MuslArchitecture(c.Triple())
return []string{ return []string{
"-nostdlibinc", "-nostdlibinc",
@@ -371,7 +387,7 @@ func (c *Config) LibcCFlags() []string {
"-isystem", filepath.Join(root, "lib", "musl", "include"), "-isystem", filepath.Join(root, "lib", "musl", "include"),
} }
case "wasi-libc": case "wasi-libc":
path := c.LibcPath("wasi-libc") path := c.LibraryPath("wasi-libc")
return []string{ return []string{
"-nostdlibinc", "-nostdlibinc",
"-isystem", filepath.Join(path, "include"), "-isystem", filepath.Join(path, "include"),
@@ -381,7 +397,7 @@ func (c *Config) LibcCFlags() []string {
return nil return nil
case "mingw-w64": case "mingw-w64":
root := goenv.Get("TINYGOROOT") root := goenv.Get("TINYGOROOT")
path := c.LibcPath("mingw-w64") path := c.LibraryPath("mingw-w64")
return []string{ return []string{
"-nostdlibinc", "-nostdlibinc",
"-isystem", filepath.Join(path, "include"), "-isystem", filepath.Join(path, "include"),