internal/rosa: cmake abstraction
All checks were successful
Test / Create distribution (push) Successful in 48s
Test / Sandbox (push) Successful in 3m5s
Test / ShareFS (push) Successful in 4m51s
Test / Sandbox (race detector) (push) Successful in 5m49s
Test / Hakurei (push) Successful in 7m44s
Test / Hpkg (push) Successful in 5m17s
Test / Hakurei (race detector) (push) Successful in 6m36s
Test / Flake checks (push) Successful in 1m56s

This is a helper for generating cure script for a cmake-based project.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-01-19 02:20:37 +09:00
parent 21858ecfe4
commit 3a4f20b759

View File

@@ -1,6 +1,12 @@
package rosa package rosa
import "hakurei.app/internal/pkg" import (
"slices"
"strings"
"hakurei.app/container/check"
"hakurei.app/internal/pkg"
)
// NewCMake returns a [pkg.Artifact] containing an installation of CMake. // NewCMake returns a [pkg.Artifact] containing an installation of CMake.
func (t Toolchain) NewCMake() pkg.Artifact { func (t Toolchain) NewCMake() pkg.Artifact {
@@ -29,3 +35,93 @@ make DESTDIR=/work install
pkg.TarGzip, pkg.TarGzip,
))) )))
} }
// CMakeAttr holds the project-specific attributes that will be applied to a new
// [pkg.Artifact] compiled via CMake.
type CMakeAttr struct {
// Path elements joined with source.
Append []string
// Use source tree as scratch space.
Writable bool
// Dependencies concatenated with the build system itself.
Extra []pkg.Artifact
// CMake CACHE entries.
Cache [][2]string
// Additional environment variables.
Env []string
// Runs before cmake.
ScriptEarly string
// Runs after cmake.
Script string
// Override the default installation prefix [AbsSystem].
Prefix *check.Absolute
}
// NewViaCMake returns a [pkg.Artifact] for compiling and installing via CMake.
func (t Toolchain) NewViaCMake(
name, version, variant string,
source pkg.Artifact,
attr *CMakeAttr,
) pkg.Artifact {
if name == "" || version == "" || variant == "" {
panic("names must be non-empty")
}
if attr == nil {
attr = &CMakeAttr{
Cache: [][2]string{
{"CMAKE_BUILD_TYPE", "Release"},
},
}
}
if len(attr.Cache) == 0 {
panic("CACHE must be non-empty")
}
cmakeExtras := []pkg.Artifact{
t.NewCMake(),
t.NewNinja(),
}
if t == toolchainStage3 {
cmakeExtras = nil
}
scriptEarly := attr.ScriptEarly
if attr.Writable {
scriptEarly = `
chmod -R +w "${ROSA_CMAKE_SOURCE}"
` + scriptEarly
}
prefix := attr.Prefix
if prefix == nil {
prefix = AbsSystem
}
sourcePath := AbsUsrSrc.Append(name)
return t.New(name+"-"+variant+"-"+version, slices.Concat(
attr.Extra,
cmakeExtras,
), nil, slices.Concat([]string{
"ROSA_CMAKE_SOURCE=" + sourcePath.Append(attr.Append...).String(),
"ROSA_INSTALL_PREFIX=/work" + prefix.String(),
}, attr.Env), scriptEarly+`
cd "$(mktemp -d)"
cmake -G Ninja \
-DCMAKE_C_COMPILER_TARGET="${ROSA_TRIPLE}" \
-DCMAKE_CXX_COMPILER_TARGET="${ROSA_TRIPLE}" \
-DCMAKE_ASM_COMPILER_TARGET="${ROSA_TRIPLE}" \
`+strings.Join(slices.Collect(func(yield func(string) bool) {
for _, v := range attr.Cache {
if !yield("-D" + v[0] + "=" + v[1]) {
return
}
}
}), " \\\n\t")+` \
-DCMAKE_INSTALL_PREFIX="${ROSA_INSTALL_PREFIX}" \
"${ROSA_CMAKE_SOURCE}"
cmake --build .
cmake --install .
`+attr.Script, pkg.Path(sourcePath, attr.Writable, source))
}