internal/rosa: lazy initialise all artifacts
All checks were successful
Test / Create distribution (push) Successful in 48s
Test / Sandbox (push) Successful in 2m37s
Test / Hakurei (push) Successful in 4m5s
Test / ShareFS (push) Successful in 4m2s
Test / Hpkg (push) Successful in 4m33s
Test / Sandbox (race detector) (push) Successful in 4m59s
Test / Hakurei (race detector) (push) Successful in 5m57s
Test / Flake checks (push) Successful in 1m44s

This improves performance, though not as drastically as lazy initialising llvm.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-01-25 01:32:21 +09:00
parent 43b8a40fc0
commit 20790af71e
17 changed files with 174 additions and 94 deletions

View File

@@ -143,24 +143,52 @@ func main() {
if len(args) != 1 {
return errors.New("cure requires 1 argument")
}
var a pkg.Artifact
var p rosa.PArtifact
switch args[0] {
case "autoconf":
p = rosa.Autoconf
case "bash":
p = rosa.Bash
case "busybox":
a = rosa.Std.NewBusybox()
case "musl":
a = rosa.Std.NewMusl(nil)
p = rosa.Busybox
case "cmake":
p = rosa.CMake
case "coreutils":
p = rosa.Coreutils
case "diffutils":
p = rosa.Diffutils
case "gettext":
p = rosa.Gettext
case "git":
a = rosa.Std.NewGit()
p = rosa.Git
case "go":
a = rosa.Std.NewGo()
p = rosa.Go
case "kernel-headers":
p = rosa.KernelHeaders
case "libffi":
p = rosa.Libffi
case "m4":
p = rosa.M4
case "make":
p = rosa.Make
case "ninja":
p = rosa.Ninja
case "perl":
p = rosa.Perl
case "patch":
p = rosa.Patch
case "python":
p = rosa.Python
case "rsync":
a = rosa.Std.NewRsync()
p = rosa.Rsync
case "zlib":
p = rosa.Zlib
default:
return fmt.Errorf("unsupported artifact %q", args[0])
}
pathname, _, err := cache.Cure(a)
pathname, _, err := cache.Cure(rosa.Std.Load(p))
if err == nil {
log.Println(pathname)
}

53
internal/rosa/all.go Normal file
View File

@@ -0,0 +1,53 @@
package rosa
import (
"sync"
"hakurei.app/internal/pkg"
)
// PArtifact is a lazily-initialised [pkg.Artifact] preset.
type PArtifact int
const (
Autoconf PArtifact = iota
Bash
Busybox
CMake
Coreutils
Diffutils
Gettext
Git
Go
KernelHeaders
Libffi
M4
Make
Ninja
Perl
Patch
Python
Rsync
Zlib
// _presetEnd is the total number of presets and does not denote a preset.
_presetEnd
)
var (
// artifactsF is an array of functions for the result of [PArtifact].
artifactsF [_presetEnd]func(t Toolchain) pkg.Artifact
// artifacts stores the result of artifactsF.
artifacts [_toolchainEnd][len(artifactsF)]pkg.Artifact
// artifactsOnce is for lazy initialisation of artifacts.
artifactsOnce [_toolchainEnd][len(artifactsF)]sync.Once
)
// Load returns the resulting [pkg.Artifact] of [PArtifact].
func (t Toolchain) Load(p PArtifact) pkg.Artifact {
artifactsOnce[t][p].Do(func() {
artifacts[t][p] = artifactsF[p](t)
})
return artifacts[t][p]
}

View File

@@ -100,9 +100,7 @@ func newBusyboxBin() pkg.Artifact {
)
}
// NewBusybox returns a [pkg.Artifact] containing a dynamically linked busybox
// installation usable within the [Toolchain] it is compiled against.
func (t Toolchain) NewBusybox() pkg.Artifact {
func (t Toolchain) newBusybox() pkg.Artifact {
const (
version = "1.37.0"
checksum = "Ial94Tnt7esJ_YEeb0AxunVL6MGYFyOw7Rtu2o87CXCi1TLrc6rlznVsN1rZk7it"
@@ -114,8 +112,8 @@ func (t Toolchain) NewBusybox() pkg.Artifact {
}
return t.New("busybox-"+version, stage3Concat(t, []pkg.Artifact{},
t.NewMake(),
t.NewKernelHeaders(),
t.Load(Make),
t.Load(KernelHeaders),
), nil, slices.Concat([]string{
"ROSA_BUSYBOX_ENABLE=" + strings.Join([]string{
"STATIC",
@@ -354,3 +352,4 @@ index 64e752f4b..40f5ba7f7 100644
}`)),
))
}
func init() { artifactsF[Busybox] = Toolchain.newBusybox }

View File

@@ -8,15 +8,14 @@ import (
"hakurei.app/internal/pkg"
)
// NewCMake returns a [pkg.Artifact] containing an installation of CMake.
func (t Toolchain) NewCMake() pkg.Artifact {
func (t Toolchain) newCMake() pkg.Artifact {
const (
version = "4.2.1"
checksum = "Y3OdbMsob6Xk2y1DCME6z4Fryb5_TkFD7knRT8dTNIRtSqbiCJyyDN9AxggN_I75"
)
return t.New("cmake-"+version, []pkg.Artifact{
t.NewMake(),
t.NewKernelHeaders(),
t.Load(Make),
t.Load(KernelHeaders),
}, nil, nil, `
# expected to be writable in the copy made during bootstrap
chmod -R +w /usr/src/cmake/Tests
@@ -37,6 +36,7 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[CMake] = Toolchain.newCMake }
// CMakeAttr holds the project-specific attributes that will be applied to a new
// [pkg.Artifact] compiled via CMake.
@@ -95,8 +95,8 @@ chmod -R +w "${ROSA_SOURCE}"
sourcePath := AbsUsrSrc.Append(name)
return t.New(name+"-"+variant+"-"+version, stage3Concat(t, attr.Extra,
t.NewCMake(),
t.NewNinja(),
t.Load(CMake),
t.Load(Ninja),
), nil, slices.Concat([]string{
"ROSA_SOURCE=" + sourcePath.String(),
"ROSA_CMAKE_SOURCE=" + sourcePath.Append(attr.Append...).String(),

View File

@@ -4,20 +4,19 @@ import (
"hakurei.app/internal/pkg"
)
// NewGit returns a [pkg.Artifact] containing an installation of git.
func (t Toolchain) NewGit() pkg.Artifact {
func (t Toolchain) newGit() pkg.Artifact {
const (
version = "2.52.0"
checksum = "uH3J1HAN_c6PfGNJd2OBwW4zo36n71wmkdvityYnrh8Ak0D1IifiAvEWz9Vi9DmS"
)
return t.New("git-"+version, stage3Concat(t, []pkg.Artifact{},
t.NewMake(),
t.NewPerl(),
t.NewM4(),
t.NewAutoconf(),
t.NewGettext(),
t.Load(Make),
t.Load(Perl),
t.Load(M4),
t.Load(Autoconf),
t.Load(Gettext),
t.NewZlib(),
t.Load(Zlib),
), nil, nil, `
chmod -R +w /usr/src/git && cd /usr/src/git
make configure
@@ -31,3 +30,4 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Git] = Toolchain.newGit }

View File

@@ -2,8 +2,7 @@ package rosa
import "hakurei.app/internal/pkg"
// NewMake returns a [pkg.Artifact] containing an installation of GNU Make.
func (t Toolchain) NewMake() pkg.Artifact {
func (t Toolchain) newMake() pkg.Artifact {
const (
version = "4.4.1"
checksum = "YS_B07ZcAy9PbaK5_vKGj64SrxO2VMpnMKfc9I0Q9IC1rn0RwOH7802pJoj2Mq4a"
@@ -23,15 +22,15 @@ cd "$(mktemp -d)"
pkg.TarGzip,
)))
}
func init() { artifactsF[Make] = Toolchain.newMake }
// NewM4 returns a [pkg.Artifact] containing an installation of GNU M4.
func (t Toolchain) NewM4() pkg.Artifact {
func (t Toolchain) newM4() pkg.Artifact {
const (
version = "1.4.20"
checksum = "RT0_L3m4Co86bVBY3lCFAEs040yI1WdeNmRylFpah8IZovTm6O4wI7qiHJN3qsW9"
)
return t.New("m4-"+version, []pkg.Artifact{
t.NewMake(),
t.Load(Make),
}, nil, nil, `
cd /usr/src/m4
chmod +w tests/test-c32ispunct.sh && echo '#!/bin/sh' > tests/test-c32ispunct.sh
@@ -49,17 +48,17 @@ make DESTDIR=/work install
pkg.TarBzip2,
)))
}
func init() { artifactsF[M4] = Toolchain.newM4 }
// NewAutoconf returns a [pkg.Artifact] containing an installation of GNU Autoconf.
func (t Toolchain) NewAutoconf() pkg.Artifact {
func (t Toolchain) newAutoconf() pkg.Artifact {
const (
version = "2.72"
checksum = "-c5blYkC-xLDer3TWEqJTyh1RLbOd1c5dnRLKsDnIrg_wWNOLBpaqMY8FvmUFJ33"
)
return t.New("autoconf-"+version, []pkg.Artifact{
t.NewMake(),
t.NewM4(),
t.NewPerl(),
t.Load(Make),
t.Load(M4),
t.Load(Perl),
}, nil, nil, `
cd "$(mktemp -d)"
/usr/src/autoconf/configure \
@@ -74,15 +73,15 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Autoconf] = Toolchain.newAutoconf }
// NewGettext returns a [pkg.Artifact] containing an installation of GNU gettext.
func (t Toolchain) NewGettext() pkg.Artifact {
func (t Toolchain) newGettext() pkg.Artifact {
const (
version = "0.26"
checksum = "IMu7yDZX7xL5UO1ZxXc-iBMbY9LLEUlOroyuSlHMZwg9MKtxG7HIm8F2LheDua0y"
)
return t.New("gettext-"+version, []pkg.Artifact{
t.NewMake(),
t.Load(Make),
}, nil, nil, `
cd /usr/src/gettext
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }
@@ -110,15 +109,15 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Gettext] = Toolchain.newGettext }
// NewDiffutils returns a [pkg.Artifact] containing an installation of GNU diffutils.
func (t Toolchain) NewDiffutils() pkg.Artifact {
func (t Toolchain) newDiffutils() pkg.Artifact {
const (
version = "3.12"
checksum = "9J5VAq5oA7eqwzS1Yvw-l3G5o-TccUrNQR3PvyB_lgdryOFAfxtvQfKfhdpquE44"
)
return t.New("diffutils-"+version, []pkg.Artifact{
t.NewMake(),
t.Load(Make),
}, nil, nil, `
cd /usr/src/diffutils
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }
@@ -139,15 +138,15 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Diffutils] = Toolchain.newDiffutils }
// NewPatch returns a [pkg.Artifact] containing an installation of GNU patch.
func (t Toolchain) NewPatch() pkg.Artifact {
func (t Toolchain) newPatch() pkg.Artifact {
const (
version = "2.8"
checksum = "MA0BQc662i8QYBD-DdGgyyfTwaeALZ1K0yusV9rAmNiIsQdX-69YC4t9JEGXZkeR"
)
return t.New("patch-"+version, []pkg.Artifact{
t.NewMake(),
t.Load(Make),
}, nil, nil, `
cd /usr/src/patch
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }
@@ -168,15 +167,15 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Patch] = Toolchain.newPatch }
// NewBash returns a [pkg.Artifact] containing an installation of GNU Bash.
func (t Toolchain) NewBash() pkg.Artifact {
func (t Toolchain) newBash() pkg.Artifact {
const (
version = "5.3"
checksum = "4LQ_GRoB_ko-Ih8QPf_xRKA02xAm_TOxQgcJLmFDT6udUPxTAWrsj-ZNeuTusyDq"
)
return t.New("bash-"+version, []pkg.Artifact{
t.NewMake(),
t.Load(Make),
}, nil, nil, `
cd "$(mktemp -d)"
/usr/src/bash/configure \
@@ -192,18 +191,18 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Bash] = Toolchain.newBash }
// NewCoreutils returns a [pkg.Artifact] containing an installation of GNU Coreutils.
func (t Toolchain) NewCoreutils() pkg.Artifact {
func (t Toolchain) newCoreutils() pkg.Artifact {
const (
version = "9.9"
checksum = "B1_TaXj1j5aiVIcazLWu8Ix03wDV54uo2_iBry4qHG6Y-9bjDpUPlkNLmU_3Nvw6"
)
return t.New("coreutils-"+version, []pkg.Artifact{
t.NewMake(),
t.NewPerl(),
t.Load(Make),
t.Load(Perl),
t.NewKernelHeaders(),
t.Load(KernelHeaders),
}, nil, nil, `
cd /usr/src/coreutils
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }
@@ -223,3 +222,4 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Coreutils] = Toolchain.newCoreutils }

View File

@@ -10,7 +10,7 @@ import (
func (t Toolchain) newGoBootstrap() pkg.Artifact {
const checksum = "8o9JL_ToiQKadCTb04nvBDkp8O1xiWOolAxVEqaTGodieNe4lOFEjlOxN3bwwe23"
return t.New("go1.4-bootstrap", []pkg.Artifact{
t.NewBash(),
t.Load(Bash),
}, nil, []string{
"CGO_ENABLED=0",
}, `
@@ -65,8 +65,7 @@ sh make.bash
)))
}
// NewGo returns a [pkg.Artifact] containing the Go toolchain.
func (t Toolchain) NewGo() pkg.Artifact {
func (t Toolchain) newGoLatest() pkg.Artifact {
go119 := t.newGo(
"1.19",
"9_e0aFHsIkVxWVGsp9T2RvvjOc3p4n9o9S8tkNe9Cvgzk_zI2FhRQB7ioQkeAAro",
@@ -90,3 +89,4 @@ func (t Toolchain) NewGo() pkg.Artifact {
)
return go125
}
func init() { artifactsF[Go] = Toolchain.newGoLatest }

View File

@@ -16,7 +16,7 @@ func (t Toolchain) newKernel(
checksum = "-V1e1WWl7HuePkmm84sSKF7nLuHfUs494uNMzMqXEyxcNE_PUE0FICL0oGWn44mM"
)
return t.New("kernel-"+version, slices.Concat([]pkg.Artifact{
t.NewMake(),
t.Load(Make),
}, extra), nil, nil, `
export LLVM=1
export HOSTLDFLAGS="${LDFLAGS}"
@@ -30,11 +30,11 @@ chmod -R +w /usr/src/linux && cd /usr/src/linux
)))
}
// NewKernelHeaders returns a [pkg.Artifact] containing kernel headers.
func (t Toolchain) NewKernelHeaders() pkg.Artifact {
func (t Toolchain) newKernelHeaders() pkg.Artifact {
return t.newKernel(`
make "-j$(nproc)" \
INSTALL_HDR_PATH=/work/system \
headers_install
`, t.NewRsync())
`, t.Load(Rsync))
}
func init() { artifactsF[KernelHeaders] = Toolchain.newKernelHeaders }

View File

@@ -2,15 +2,14 @@ package rosa
import "hakurei.app/internal/pkg"
// NewLibffi returns a [pkg.Artifact] containing an installation of libffi.
func (t Toolchain) NewLibffi() pkg.Artifact {
func (t Toolchain) newLibffi() pkg.Artifact {
const (
version = "3.4.5"
checksum = "apIJzypF4rDudeRoI_n3K7N-zCeBLTbQlHRn9NSAZqdLAWA80mR0gXPTpHsL7oMl"
)
return t.New("libffi-"+version, []pkg.Artifact{
t.NewMake(),
t.NewKernelHeaders(),
t.Load(Make),
t.Load(KernelHeaders),
}, nil, nil, `
cd "$(mktemp -d)"
/usr/src/libffi/configure \
@@ -26,3 +25,4 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Libffi] = Toolchain.newLibffi }

View File

@@ -188,7 +188,7 @@ cp -r /system/include /usr/include && rm -rf /system/include
if len(patches) > 1 {
source = t.New(
"llvmorg-patched", stage3Concat(t, []pkg.Artifact{},
t.NewPatch(),
t.Load(Patch),
), nil, nil, `
cp -r /usr/src/llvmorg/. /work/.
chmod -R +w /work && cd /work
@@ -201,14 +201,14 @@ cat /usr/src/llvm-patches/* | patch -p 1
Cache: slices.Concat(cache, attr.cmake),
Append: cmakeAppend,
Extra: stage3Concat(t, attr.extra,
t.NewLibffi(),
t.NewPython(),
t.NewPerl(),
t.NewDiffutils(),
t.NewBash(),
t.NewCoreutils(),
t.Load(Libffi),
t.Load(Python),
t.Load(Perl),
t.Load(Diffutils),
t.Load(Bash),
t.Load(Coreutils),
t.NewKernelHeaders(),
t.Load(KernelHeaders),
),
Prefix: attr.prefix,
@@ -327,7 +327,7 @@ ln -s \
musl,
compilerRT,
runtimes,
t.NewGit(),
t.Load(Git),
},
script: `
ln -s clang /work/system/bin/cc

View File

@@ -42,7 +42,7 @@ rmdir -v /work/lib
}
return t.New("musl-"+version, stage3Concat(t, attr.Extra,
t.NewMake(),
t.Load(Make),
), nil, slices.Concat([]string{
"ROSA_MUSL_TARGET=" + target,
}, attr.Env), `

View File

@@ -2,15 +2,14 @@ package rosa
import "hakurei.app/internal/pkg"
// NewNinja returns a [pkg.Artifact] containing an installation of Ninja.
func (t Toolchain) NewNinja() pkg.Artifact {
func (t Toolchain) newNinja() pkg.Artifact {
const (
version = "1.13.2"
checksum = "ygKWMa0YV2lWKiFro5hnL-vcKbc_-RACZuPu0Io8qDvgQlZ0dxv7hPNSFkt4214v"
)
return t.New("ninja-"+version, []pkg.Artifact{
t.NewCMake(),
t.NewPython(),
t.Load(CMake),
t.Load(Python),
}, nil, nil, `
chmod -R +w /usr/src/ninja/
mkdir -p /work/system/bin/ && cd /work/system/bin/
@@ -33,3 +32,4 @@ python3 /usr/src/ninja/configure.py \
pkg.TarGzip,
)))
}
func init() { artifactsF[Ninja] = Toolchain.newNinja }

View File

@@ -2,14 +2,13 @@ package rosa
import "hakurei.app/internal/pkg"
// NewPerl returns a [pkg.Artifact] containing an installation of perl.
func (t Toolchain) NewPerl() pkg.Artifact {
func (t Toolchain) newPerl() pkg.Artifact {
const (
version = "5.42.0"
checksum = "2KR7Jbpk-ZVn1a30LQRwbgUvg2AXlPQZfzrqCr31qD5-yEsTwVQ_W76eZH-EdxM9"
)
return t.New("perl-"+version, []pkg.Artifact{
t.NewMake(),
t.Load(Make),
}, nil, nil, `
chmod -R +w /usr/src/perl && cd /usr/src/perl
@@ -32,3 +31,4 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Perl] = Toolchain.newPerl }

View File

@@ -6,8 +6,7 @@ import (
"hakurei.app/internal/pkg"
)
// NewPython returns a [pkg.Artifact] containing an installation of Python.
func (t Toolchain) NewPython() pkg.Artifact {
func (t Toolchain) newPython() pkg.Artifact {
const (
version = "3.14.2"
checksum = "7nZunVMGj0viB-CnxpcRego2C90X5wFsMTgsoewd5z-KSZY2zLuqaBwG-14zmKys"
@@ -34,9 +33,9 @@ func (t Toolchain) NewPython() pkg.Artifact {
"test_dbm_gnu",
}
return t.New("python-"+version, []pkg.Artifact{
t.NewMake(),
t.NewZlib(),
t.NewLibffi(),
t.Load(Make),
t.Load(Zlib),
t.Load(Libffi),
}, nil, []string{
"EXTRATESTOPTS=-j0 -x " + strings.Join(skipTests, " -x "),
@@ -63,3 +62,4 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Python] = Toolchain.newPython }

View File

@@ -235,7 +235,7 @@ ln -vs ../usr/bin /work/bin
compilerRT,
runtimes,
clang,
boot.NewBusybox(),
boot.Load(Busybox),
})
env = fixupEnviron(env, []string{
EnvTriplet + "=" + triplet(),

View File

@@ -2,14 +2,13 @@ package rosa
import "hakurei.app/internal/pkg"
// NewRsync returns a [pkg.Artifact] containing an installation of rsync.
func (t Toolchain) NewRsync() pkg.Artifact {
func (t Toolchain) newRsync() pkg.Artifact {
const (
version = "3.4.1"
checksum = "VBlTsBWd9z3r2-ex7GkWeWxkUc5OrlgDzikAC0pK7ufTjAJ0MbmC_N04oSVTGPiv"
)
return t.New("rsync-"+version, []pkg.Artifact{
t.NewMake(),
t.Load(Make),
}, nil, nil, `
cd "$(mktemp -d)"
/usr/src/rsync/configure --prefix=/system \
@@ -27,3 +26,4 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Rsync] = Toolchain.newRsync }

View File

@@ -2,14 +2,13 @@ package rosa
import "hakurei.app/internal/pkg"
// NewZlib returns a new [pkg.Artifact] containing an installation of zlib.
func (t Toolchain) NewZlib() pkg.Artifact {
func (t Toolchain) newZlib() pkg.Artifact {
const (
version = "1.3.1"
checksum = "E-eIpNzE8oJ5DsqH4UuA_0GDKuQF5csqI8ooDx2w7Vx-woJ2mb-YtSbEyIMN44mH"
)
return t.New("zlib-"+version, []pkg.Artifact{
t.NewMake(),
t.Load(Make),
}, nil, nil, `
cd "$(mktemp -d)"
CC="clang -fPIC" /usr/src/zlib/configure \
@@ -23,3 +22,4 @@ make DESTDIR=/work install
pkg.TarGzip,
)))
}
func init() { artifactsF[Zlib] = Toolchain.newZlib }