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
// 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).
+23 -7
View File
@@ -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"),