From 67b2914c94de1d35f72fc43a8051056afc8d53e9 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Mon, 16 Feb 2026 13:17:56 +0900 Subject: [PATCH] internal/rosa: meson helper This is used by quite a few projects. Signed-off-by: Ophestra --- internal/rosa/fuse.go | 43 +++++++---------- internal/rosa/kmod.go | 45 +++++++----------- internal/rosa/meson.go | 100 ++++++++++++++++++++++++++++++++++++++- internal/rosa/wayland.go | 81 +++++++++++-------------------- 4 files changed, 162 insertions(+), 107 deletions(-) diff --git a/internal/rosa/fuse.go b/internal/rosa/fuse.go index c80e6e4..8ce0743 100644 --- a/internal/rosa/fuse.go +++ b/internal/rosa/fuse.go @@ -7,11 +7,23 @@ func (t Toolchain) newFuse() pkg.Artifact { version = "3.18.1" checksum = "COb-BgJRWXLbt9XUkNeuiroQizpMifXqxgieE1SlkMXhs_WGSyJStrmyewAw2hd6" ) - return t.New("fuse-"+version, 0, []pkg.Artifact{ - t.Load(Python), - t.Load(Meson), - t.Load(Ninja), + return t.NewViaMeson("fuse", version, pkg.NewHTTPGetTar( + nil, "https://github.com/libfuse/libfuse/releases/download/"+ + "fuse-"+version+"/fuse-"+version+".tar.gz", + mustDecode(checksum), + pkg.TarGzip, + ), &MesonAttr{ + Configure: [][2]string{ + {"Ddefault_library", "both"}, + {"Dtests", "true"}, + {"Duseroot", "false"}, + {"Dinitscriptdir", "/system/init.d"}, + }, + ScriptCompiled: "python3 -m pytest test/", + // this project uses pytest + SkipCheck: true, + }, t.Load(IniConfig), t.Load(Packaging), t.Load(Pluggy), @@ -19,27 +31,6 @@ func (t Toolchain) newFuse() pkg.Artifact { t.Load(PyTest), t.Load(KernelHeaders), - }, nil, nil, ` -cd "$(mktemp -d)" -meson setup \ - --reconfigure \ - --buildtype=release \ - --prefix=/system \ - --prefer-static \ - -Dtests=true \ - -Duseroot=false \ - -Dinitscriptdir=/system/init.d \ - -Ddefault_library=both \ - . /usr/src/fuse -meson compile -python3 -m pytest test/ -meson install \ - --destdir=/work -`, pkg.Path(AbsUsrSrc.Append("fuse"), false, pkg.NewHTTPGetTar( - nil, "https://github.com/libfuse/libfuse/releases/download/"+ - "fuse-"+version+"/fuse-"+version+".tar.gz", - mustDecode(checksum), - pkg.TarGzip, - ))) + ) } func init() { artifactsF[Fuse] = Toolchain.newFuse } diff --git a/internal/rosa/kmod.go b/internal/rosa/kmod.go index 2ac319d..5be4873 100644 --- a/internal/rosa/kmod.go +++ b/internal/rosa/kmod.go @@ -7,36 +7,27 @@ func (t Toolchain) newKmod() pkg.Artifact { version = "34.2" checksum = "0K7POeTKxMhExsaTsnKAC6LUNsRSfe6sSZxWONPbOu-GI_pXOw3toU_BIoqfBhJV" ) - return t.New("kmod-"+version, 0, []pkg.Artifact{ - t.Load(Python), - t.Load(Meson), - t.Load(PkgConfig), - t.Load(CMake), - t.Load(Ninja), - - t.Load(Zlib), - t.Load(Zstd), - t.Load(OpenSSL), - t.Load(KernelHeaders), - }, nil, nil, ` -cd "$(mktemp -d)" -meson setup \ - --buildtype=release \ - --prefix=/system \ - -Dsysconfdir=/system/etc \ - -Dbashcompletiondir=no \ - -Dfishcompletiondir=no \ - -Dxz=disabled \ - -Dmanpages=false \ - . /usr/src/kmod -meson compile -meson install \ - --destdir=/work -`, pkg.Path(AbsUsrSrc.Append("kmod"), false, pkg.NewHTTPGetTar( + return t.NewViaMeson("kmod", version, pkg.NewHTTPGetTar( nil, "https://www.kernel.org/pub/linux/utils/kernel/"+ "kmod/kmod-"+version+".tar.gz", mustDecode(checksum), pkg.TarGzip, - ))) + ), &MesonAttr{ + Configure: [][2]string{ + {"Dsysconfdir", "/system/etc"}, + {"Dbashcompletiondir", "no"}, + {"Dfishcompletiondir", "no"}, + {"Dxz", "disabled"}, + {"Dmanpages", "false"}, + }, + + // makes assumptions about the running kernel + SkipCheck: true, + }, + t.Load(Zlib), + t.Load(Zstd), + t.Load(OpenSSL), + t.Load(KernelHeaders), + ) } func init() { artifactsF[Kmod] = Toolchain.newKmod } diff --git a/internal/rosa/meson.go b/internal/rosa/meson.go index 33817ad..fbdb363 100644 --- a/internal/rosa/meson.go +++ b/internal/rosa/meson.go @@ -1,6 +1,11 @@ package rosa -import "hakurei.app/internal/pkg" +import ( + "slices" + "strings" + + "hakurei.app/internal/pkg" +) func (t Toolchain) newMeson() pkg.Artifact { const ( @@ -25,3 +30,96 @@ python3 setup.py \ ))) } func init() { artifactsF[Meson] = Toolchain.newMeson } + +// MesonAttr holds the project-specific attributes that will be applied to a new +// [pkg.Artifact] compiled via [Meson]. +type MesonAttr struct { + // Mount the source tree writable. + Writable bool + + // Additional environment variables. + Env []string + // Runs before setup. + ScriptEarly string + // Runs after configure. + ScriptCompiled string + // Runs after install. + Script string + + // Flags passed to the setup command. + Configure [][2]string + // Whether to skip meson test. + SkipCheck bool + // Appended after the test command. + AppendTest string + + // Suffix appended to the source pathname. + SourceSuffix string + + // Passed through to [Toolchain.New], before source. + Paths []pkg.ExecPath + // Passed through to [Toolchain.New]. + Flag int +} + +// NewViaMeson returns a [pkg.Artifact] for compiling and installing via [Meson]. +func (t Toolchain) NewViaMeson( + name, version string, + source pkg.Artifact, + attr *MesonAttr, + extra ...pkg.Artifact, +) pkg.Artifact { + if name == "" || version == "" { + panic("names must be non-empty") + } + if attr == nil { + attr = new(MesonAttr) + } + + scriptCompiled := attr.ScriptCompiled + if len(scriptCompiled) > 0 && scriptCompiled[0] != '\n' { + scriptCompiled = "\n" + scriptCompiled + } + + var check string + if !attr.SkipCheck { + check = "\nmeson test \\\n\t--print-errorlogs" + attr.AppendTest + } + + return t.New(name+"-"+version, attr.Flag, slices.Concat([]pkg.Artifact{ + t.Load(Python), + t.Load(Meson), + t.Load(Ninja), + + t.Load(PkgConfig), + t.Load(CMake), + }, extra), nil, attr.Env, attr.ScriptEarly+` +cd "$(mktemp -d)" +meson setup \ + `+strings.Join(slices.Collect(func(yield func(string) bool) { + for _, v := range append([][2]string{ + {"prefix", "/system"}, + {"buildtype", "release"}, + }, attr.Configure...) { + s := "-" + v[0] + if len(v[0]) > 0 && v[0][0] != 'D' { + s = "-" + s + } + if v[1] != "" { + s += "=" + v[1] + } + if !yield(s) { + return + } + } + }), " \\\n\t")+` \ + . /usr/src/`+name+` +meson compile`+scriptCompiled+check+` +meson install \ + --destdir=/work +`+attr.Script, slices.Concat(attr.Paths, []pkg.ExecPath{ + pkg.Path(AbsUsrSrc.Append( + name+attr.SourceSuffix, + ), attr.Writable, source), + })...) +} diff --git a/internal/rosa/wayland.go b/internal/rosa/wayland.go index 10531ea..f0d0c77 100644 --- a/internal/rosa/wayland.go +++ b/internal/rosa/wayland.go @@ -7,41 +7,31 @@ func (t Toolchain) newWayland() pkg.Artifact { version = "1.24.0" checksum = "JxgLiFRRGw2D3uhVw8ZeDbs3V7K_d4z_ypDog2LBqiA_5y2vVbUAk5NT6D5ozm0m" ) - return t.New("wayland-"+version, 0, []pkg.Artifact{ - t.Load(Python), - t.Load(Meson), - t.Load(PkgConfig), - t.Load(CMake), - t.Load(Ninja), + return t.NewViaMeson("wayland", version, pkg.NewHTTPGetTar( + nil, "https://gitlab.freedesktop.org/wayland/wayland/"+ + "-/archive/"+version+"/wayland-"+version+".tar.bz2", + mustDecode(checksum), + pkg.TarBzip2, + ), &MesonAttr{ + Writable: true, + ScriptEarly: ` +cd /usr/src/wayland +chmod +w tests tests/sanity-test.c +echo 'int main(){}' > tests/sanity-test.c +`, + Configure: [][2]string{ + {"Ddefault_library", "both"}, + {"Ddocumentation", "false"}, + {"Dtests", "true"}, + }, + }, t.Load(Gawk), t.Load(Diffutils), t.Load(Libffi), t.Load(Libexpat), t.Load(Libxml2), - }, nil, nil, ` -cd /usr/src/wayland -chmod +w tests tests/sanity-test.c -echo 'int main(){}' > tests/sanity-test.c - -cd "$(mktemp -d)" -meson setup \ - --buildtype=release \ - --prefix=/system \ - -Ddocumentation=false \ - -Dtests=true \ - -Ddefault_library=both \ - . /usr/src/wayland -meson compile -meson test -meson install \ - --destdir=/work -`, pkg.Path(AbsUsrSrc.Append("wayland"), true, pkg.NewHTTPGetTar( - nil, "https://gitlab.freedesktop.org/wayland/wayland/"+ - "-/archive/"+version+"/wayland-"+version+".tar.bz2", - mustDecode(checksum), - pkg.TarBzip2, - ))) + ) } func init() { artifactsF[Wayland] = Toolchain.newWayland } @@ -50,33 +40,18 @@ func (t Toolchain) newWaylandProtocols() pkg.Artifact { version = "1.47" checksum = "B_NodZ7AQfCstcx7kgbaVjpkYOzbAQq0a4NOk-SA8bQixAE20FY3p1-6gsbPgHn9" ) - return t.New("wayland-protocols-"+version, 0, []pkg.Artifact{ - t.Load(Python), - t.Load(Meson), - t.Load(PkgConfig), - t.Load(CMake), - t.Load(Ninja), - - t.Load(Wayland), - t.Load(Libffi), - t.Load(Libexpat), - t.Load(Libxml2), - }, nil, nil, ` -cd "$(mktemp -d)" -meson setup \ - --reconfigure \ - --buildtype=release \ - --prefix=/system \ - --prefer-static \ - . /usr/src/wayland-protocols -meson compile -meson install \ - --destdir=/work -`, pkg.Path(AbsUsrSrc.Append("wayland-protocols"), false, pkg.NewHTTPGetTar( + return t.NewViaMeson("wayland-protocols", version, pkg.NewHTTPGetTar( nil, "https://gitlab.freedesktop.org/wayland/wayland-protocols/"+ "-/archive/"+version+"/wayland-protocols-"+version+".tar.bz2", mustDecode(checksum), pkg.TarBzip2, - ))) + ), &MesonAttr{ + SkipCheck: true, + }, + t.Load(Wayland), + t.Load(Libffi), + t.Load(Libexpat), + t.Load(Libxml2), + ) } func init() { artifactsF[WaylandProtocols] = Toolchain.newWaylandProtocols }