aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-01-19 02:20:37 +0900
committerOphestra <cat@gensokyo.uk>2026-01-19 02:20:37 +0900
commit3a4f20b759bc9c8315320d27fc308bb75d2150a3 (patch)
tree65cf6228c234255271b252e723e545e0fc964f02 /internal
parent21858ecfe446d6bf037671687745d773f9218104 (diff)
internal/rosa: cmake abstraction
This is a helper for generating cure script for a cmake-based project. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal')
-rw-r--r--internal/rosa/cmake.go98
1 files changed, 97 insertions, 1 deletions
diff --git a/internal/rosa/cmake.go b/internal/rosa/cmake.go
index 3468d1d8..ef91a725 100644
--- a/internal/rosa/cmake.go
+++ b/internal/rosa/cmake.go
@@ -1,6 +1,12 @@
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.
func (t Toolchain) NewCMake() pkg.Artifact {
@@ -29,3 +35,93 @@ make DESTDIR=/work install
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))
+}