aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-10-23 02:46:27 +0900
committerOphestra <cat@gensokyo.uk>2026-10-23 02:46:27 +0900
commita0689a1f656be32052cd067140d982b4b4e6aa8e (patch)
tree88c36dd5bcc334172af5911711e606433d761463
parent9a9f53daac112c841487a3c530318601c102895a (diff)
internal/rosa/meson: support cross-compilation
Meson does not want to play nice and accept arguments or environment variables for cross-compiling configuration, so a so-called mfile had to be generated and placed here. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--internal/rosa/cmake.go2
-rw-r--r--internal/rosa/make.go2
-rw-r--r--internal/rosa/meson.go64
-rw-r--r--internal/rosa/package/wayland.az4
-rw-r--r--internal/rosa/perl.go2
-rw-r--r--internal/rosa/python.go2
-rw-r--r--internal/rosa/rosa.go17
7 files changed, 77 insertions, 16 deletions
diff --git a/internal/rosa/cmake.go b/internal/rosa/cmake.go
index c037a239..8cfbf00c 100644
--- a/internal/rosa/cmake.go
+++ b/internal/rosa/cmake.go
@@ -35,7 +35,7 @@ type CMakeHelper struct {
var _ Helper = new(CMakeHelper)
// tools returns the cmake handle alongside either ninja or make.
-func (attr *CMakeHelper) tools() P {
+func (attr *CMakeHelper) tools(Toolchain) P {
if attr != nil && attr.Make {
return P{_cmake, _make}
}
diff --git a/internal/rosa/make.go b/internal/rosa/make.go
index e0b9094f..c6a1d2fd 100644
--- a/internal/rosa/make.go
+++ b/internal/rosa/make.go
@@ -61,7 +61,7 @@ type MakeHelper struct {
var _ Helper = new(MakeHelper)
// tools returns make and other optional dependencies.
-func (attr *MakeHelper) tools() P {
+func (attr *MakeHelper) tools(Toolchain) P {
h := _make
if attr != nil && attr.Early {
h = _makeEarly
diff --git a/internal/rosa/meson.go b/internal/rosa/meson.go
index 25291dd0..59029595 100644
--- a/internal/rosa/meson.go
+++ b/internal/rosa/meson.go
@@ -3,6 +3,8 @@ package rosa
import (
"slices"
"strings"
+
+ "hakurei.app/pkg"
)
var (
@@ -35,11 +37,54 @@ type MesonHelper struct {
var _ Helper = new(MesonHelper)
// tools returns hardcoded meson runtime dependencies.
-func (attr *MesonHelper) tools() P {
- if !attr.isPython() {
- return P{_muon}
+func (attr *MesonHelper) tools(t Toolchain) P {
+ m := _muon
+ if attr.isPython() {
+ m = _meson
+ }
+ if t.cross() {
+ return P{m, _qemu}
}
- return P{_meson}
+ return P{m}
+}
+
+// paths returns the cross-compiler mfile, or nil if not cross-compiling.
+func (*MesonHelper) paths(t Toolchain) []pkg.ExecPath {
+ if !t.cross() {
+ return nil
+ }
+
+ arch, mesonArch, target := t.Arch(), t.linuxArch(), t.triple()
+ return []pkg.ExecPath{pkg.Path(
+ AbsSystem.Append("mfile"),
+ false, pkg.NewFile("mfile-"+arch, []byte(`# meson env2mfile
+[binaries]
+# Compilers
+c = ['clang', '--target=`+target+`', '--sysroot=/system/`+arch+`']
+cpp = ['clang++', '--target=`+target+`', '--sysroot=/system/`+arch+`']
+pkg-config = ['pkg-config']
+exe_wrapper = ['qemu-`+mesonArch+`', '-L', '/system/`+arch+`']
+
+# Other binaries
+ar = ['llvm-ar']
+ranlib = ['llvm-ranlib']
+strip = ['llvm-strip']
+
+[built-in options]
+
+[properties]
+sys_root = '/system/`+arch+`'
+pkg_config_libdir = '/system/`+arch+`/system/lib/pkgconfig'
+
+[host_machine]
+cpu = '`+mesonArch+`'
+cpu_family = '`+mesonArch+`'
+endian = 'little'
+system = 'linux'
+subsystem = 'linux'
+kernel = 'linux'
+`)),
+ )}
}
// inputs is a noop.
@@ -65,10 +110,6 @@ func (attr *MesonHelper) isPython() bool {
// script generates the cure script.
func (attr *MesonHelper) script(t Toolchain, name string) string {
- if t.cross() {
- panic(CrossError(name))
- }
-
if attr == nil {
attr = new(MesonHelper)
}
@@ -109,8 +150,13 @@ func (attr *MesonHelper) script(t Toolchain, name string) string {
}
}
+ var setupArgs string
+ if t.cross() {
+ setupArgs += " --cross-file=/system/mfile"
+ }
+
return `
-` + muon + ` setup \
+` + muon + ` setup` + setupArgs + ` \
` + strings.Join(slices.Collect(func(yield func(string) bool) {
for _, v := range append([]KV{
{"wrap_mode", "nofallback"},
diff --git a/internal/rosa/package/wayland.az b/internal/rosa/package/wayland.az
index 3b240994..25f0c680 100644
--- a/internal/rosa/package/wayland.az
+++ b/internal/rosa/package/wayland.az
@@ -35,6 +35,9 @@ echo 'int main(){}' > tests/sanity-test.c
libexpat,
libxml2,
];
+
+ // for wayland-scanner
+ native = [ wayland ];
}
package wayland-protocols {
@@ -53,6 +56,7 @@ package wayland-protocols {
exec = meson {};
inputs = [ wayland ];
+ tools = [ wayland ];
runtime = nil;
unlikely = true;
}
diff --git a/internal/rosa/perl.go b/internal/rosa/perl.go
index 55c17916..6cb87149 100644
--- a/internal/rosa/perl.go
+++ b/internal/rosa/perl.go
@@ -11,7 +11,7 @@ type MakeMakerHelper struct {
}
// tools returns perl and make.
-func (*MakeMakerHelper) tools() P { return P{_perl, _make} }
+func (*MakeMakerHelper) tools(Toolchain) P { return P{_perl, _make} }
// inputs returns perl.
func (*MakeMakerHelper) inputs() P { return P{_perl} }
diff --git a/internal/rosa/python.go b/internal/rosa/python.go
index e97ded49..8b363d87 100644
--- a/internal/rosa/python.go
+++ b/internal/rosa/python.go
@@ -26,7 +26,7 @@ type PipHelper struct {
var _ Helper = new(PipHelper)
// tools returns python and pytest if defaults are assumed.
-func (attr *PipHelper) tools() P {
+func (attr *PipHelper) tools(Toolchain) P {
if attr == nil || (!attr.SkipCheck && attr.Check == "") {
return P{_python, _pythonPyTest}
}
diff --git a/internal/rosa/rosa.go b/internal/rosa/rosa.go
index 27f31ecf..2448f203 100644
--- a/internal/rosa/rosa.go
+++ b/internal/rosa/rosa.go
@@ -214,6 +214,7 @@ var (
_toyboxEarly = H("toybox-early")
_llvm = H("llvm")
_patch = H("patch")
+ _qemu = H("qemu")
)
// HasStageEarly returns whether a stage0 distribution is available.
@@ -281,7 +282,7 @@ const helperInPlace = "\x00"
// Helper is a build system helper for [Toolchain.New].
type Helper interface {
// tools returns helper-specific tool handles.
- tools() P
+ tools(t Toolchain) P
// inputs returns helper-specific input handles.
inputs() P
@@ -301,6 +302,13 @@ type Helper interface {
script(t Toolchain, name string) string
}
+// pathsHelper is a [Helper] with additional paths added to the container.
+type pathsHelper interface {
+ Helper
+
+ paths(t Toolchain) []pkg.ExecPath
+}
+
// PackageAttr holds build-system-agnostic attributes.
type PackageAttr struct {
// Measure output if populated. Required by HostNet.
@@ -515,7 +523,7 @@ func (t Toolchain) New(
if cross {
spv = paGet()
}
- for _, p := range helper.tools() {
+ for _, p := range helper.tools(t) {
root = native.appendHandle(root, pv, p)
}
@@ -600,6 +608,9 @@ cd '/usr/src/` + name + `/'
)),
})
}
+ if ph, ok := helper.(pathsHelper); ok {
+ paths = append(paths, ph.paths(t)...)
+ }
bin := attr.Bin
if attr.PopulateUsrBin {
@@ -682,7 +693,7 @@ type GenericHelper struct {
var _ Helper = new(GenericHelper)
// tools is a noop.
-func (*GenericHelper) tools() P { return nil }
+func (*GenericHelper) tools(Toolchain) P { return nil }
// inputs is a noop.
func (*GenericHelper) inputs() P { return nil }