diff options
35 files changed, 851 insertions, 117 deletions
diff --git a/cmd/dist/main.go b/cmd/dist/main.go index b147ade5..b3b58b56 100644 --- a/cmd/dist/main.go +++ b/cmd/dist/main.go @@ -192,7 +192,7 @@ func main() { ) log.Println() - if runTests { + if arch == runtime.GOARCH && runTests { log.Println("##### Testing Hakurei.") mustRun( ctx, nil, "go", "test", raceFlag, diff --git a/cmd/mbf/main.go b/cmd/mbf/main.go index 115ca1a2..eb250ec8 100644 --- a/cmd/mbf/main.go +++ b/cmd/mbf/main.go @@ -178,12 +178,17 @@ func main() { } if azaleaPath != "" { + prefix := azaleaPath + if prefix[len(prefix)-1] != '/' { + prefix += "/" + } + var root *os.Root if a, err := check.NewAbs(azaleaPath); err != nil { return err } else if root, err = os.OpenRoot(a.String()); err != nil { return err - } else if err = builtin.RegisterFS(root.FS()); err != nil { + } else if err = builtin.RegisterFS(root.FS(), prefix); err != nil { return err } } diff --git a/internal/rosa/azalea/azalea.go b/internal/rosa/azalea/azalea.go index 94e54585..d97b6f7d 100644 --- a/internal/rosa/azalea/azalea.go +++ b/internal/rosa/azalea/azalea.go @@ -126,10 +126,12 @@ func (v Val) String() string { // parseVal parses until the end of the [Val]. func (p *parser) parseVal() (v Val) { - v = append(v, p.parseExpr()) + expr, _ := p.parseExpr() + v = append(v, expr) for p.tok == '+' { p.scan() - v = append(v, p.parseExpr()) + expr, _ = p.parseExpr() + v = append(v, expr) } return } @@ -194,6 +196,8 @@ type Func struct { Package bool // Key-value arguments. Args []Arg + // Position of the character immediately after the function identifier. + Pos scanner.Position } // fullFuncString controls whether [Func.String] includes the function body. @@ -233,17 +237,17 @@ func (v Func) String() string { } // parseExpr parses the current expression. -func (p *parser) parseExpr() any { +func (p *parser) parseExpr() (any, scanner.Position) { switch p.tok { case scanner.Int: v := p.parseInt() p.scan() - return v + return v, p.s.Pos() case scanner.String, scanner.RawString: v := p.parseString() p.scan() - return v + return v, p.s.Pos() case scanner.Ident: var v Func @@ -252,6 +256,7 @@ func (p *parser) parseExpr() any { p.scanAs(scanner.Ident) v.Ident = Ident(p.s.TokenText()) } + v.Pos = p.s.Pos() p.scan() switch p.tok { @@ -261,7 +266,7 @@ func (p *parser) parseExpr() any { switch p.tok { case '}': p.scan() - return v + return v, p.s.Pos() case scanner.Ident: break @@ -312,7 +317,7 @@ func (p *parser) parseExpr() any { } default: - return v.Ident + return v.Ident, p.s.Pos() } case '{': @@ -322,7 +327,7 @@ func (p *parser) parseExpr() any { switch p.tok { case '}': p.scan() - return v + return v, p.s.Pos() default: pair := KV{K: p.parseVal()} @@ -360,7 +365,7 @@ func (p *parser) parseExpr() any { panic(ExprError(',')) case ']': p.scan() - return v + return v, p.s.Pos() case scanner.EOF: panic(ExprError(scanner.EOF)) default: @@ -386,9 +391,10 @@ func (ScanError) Error() string { } // Parse parses expressions from r. -func Parse(r io.Reader) (e []any, err error) { +func Parse(r io.Reader, name string) (e []any, err error) { var p parser p.s.Init(r) + p.s.Filename = name p.s.Mode = scanner.ScanIdents | scanner.ScanInts | @@ -423,7 +429,8 @@ func Parse(r io.Reader) (e []any, err error) { p.scan() for p.tok != scanner.EOF { - e = append(e, p.parseExpr()) + expr, _ := p.parseExpr() + e = append(e, expr) } if p.s.ErrorCount != 0 { diff --git a/internal/rosa/azalea/azalea_test.go b/internal/rosa/azalea/azalea_test.go index 6e184737..7cae6de5 100644 --- a/internal/rosa/azalea/azalea_test.go +++ b/internal/rosa/azalea/azalea_test.go @@ -35,9 +35,21 @@ func TestParse(t *testing.T) { Args: []Arg{{K: []Ident{"v"}, V: Val{ Ident("v"), String("\xfd"), - Func{Ident: "p"}, + Func{Ident: "p", Pos: scanner.Position{ + Filename: "concat.az", + Offset: 18, + Line: 1, + Column: 19, + }}, Int(9), }}}, + + Pos: scanner.Position{ + Filename: "concat.az", + Offset: 1, + Line: 1, + Column: 2, + }, }}, nil}, {"truncated string concat", `f { v = v+; }`, nil, ExprError(';')}, @@ -92,6 +104,13 @@ func TestParse(t *testing.T) { {K: []Ident{Ident("checksum")}, V: Val{String("4ASoWbxaA2FW7PAB0zzHDPC5XnNhyaAyjtDPpGzceSLeYnEIXsNYZR3PA_Zu5P0K")}}, {K: []Ident{Ident("compress")}, V: Val{Ident("gzip")}}, }, + + Pos: scanner.Position{ + Filename: "gcc.az", + Offset: 165, + Line: 7, + Column: 20, + }, }}}, {K: []Ident{Ident("patches")}, V: Val{Array{ {String("musl-off64_t-loff_t.patch")}, @@ -120,12 +139,29 @@ func TestParse(t *testing.T) { {K: []Ident{Ident("amd64"), Ident("arm64")}, V: Val{String("''")}}, {K: []Ident{Ident("default")}, V: Val{Ident("unset")}}, }, + + Pos: scanner.Position{ + Filename: "gcc.az", + Offset: 890, + Line: 32, + Column: 30, + }, }}}, }}}, {K: []Ident{Ident("make")}, V: Val{Array{ {String("BOOT_CFLAGS='-O2 -g'")}, { - Func{Ident: Ident("noop"), Args: []Arg{{K: []Ident{Ident("key")}, V: Val{Ident("value")}}}}, + Func{ + Ident: Ident("noop"), + Args: []Arg{{K: []Ident{Ident("key")}, V: Val{Ident("value")}}}, + + Pos: scanner.Position{ + Filename: "gcc.az", + Offset: 995, + Line: 39, + Column: 8, + }, + }, String("\x00"), }, {String("bootstrap")}, @@ -133,6 +169,13 @@ func TestParse(t *testing.T) { {K: []Ident{Ident("skip-check")}, V: Val{Ident("true")}}, }, + + Pos: scanner.Position{ + Filename: "gcc.az", + Offset: 627, + Line: 22, + Column: 13, + }, }}}, {K: []Ident{Ident("inputs")}, V: Val{Array{ @@ -143,13 +186,23 @@ func TestParse(t *testing.T) { {Ident("kernel-headers")}, }}}, }, + + Pos: scanner.Position{ + Filename: "gcc.az", + Offset: 11, + Line: 1, + Column: 12, + }, }}, nil}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Parallel() - p, err := Parse(strings.NewReader(tc.data)) + p, err := Parse( + strings.NewReader(tc.data), + strings.ReplaceAll(tc.name, " ", "_")+".az", + ) if !reflect.DeepEqual(p, tc.want) { t.Errorf("Parse: %#v, want %#v", p, tc.want) } @@ -163,7 +216,7 @@ func TestParse(t *testing.T) { func BenchmarkParse(b *testing.B) { r := strings.NewReader(sample) for b.Loop() { - if _, err := Parse(r); err != nil { + if _, err := Parse(r, "./testdata/gcc.az"); err != nil { b.Fatal(err) } diff --git a/internal/rosa/azalea/evaluate.go b/internal/rosa/azalea/evaluate.go index 9b119100..85e20583 100644 --- a/internal/rosa/azalea/evaluate.go +++ b/internal/rosa/azalea/evaluate.go @@ -211,6 +211,18 @@ func exprTextIndent(expr any) string { return strings.ReplaceAll(ExprText(expr), "\n", "\n\t") } +// posString returns the string representation of the position of expr, if +// available. Otherwise, it returns a hardcoded string. +func posString(expr any) string { + switch v := expr.(type) { + case Func: + return v.Pos.String() + + default: + return "<unknown>" + } +} + // EvaluationError is an error and the expression it occurred in. type EvaluationError struct { Expr any @@ -225,10 +237,16 @@ func (e EvaluationError) Unwrap() error { return e.Err } func (e EvaluationError) Error() string { v, ok := errors.AsType[EvaluationError](e.Err) if ok { - return fmt.Sprintf("%v\n%s", v, ExprText(e.Expr)) + return fmt.Sprintf( + "%v\n%s\n\t%s", + v, ExprText(e.Expr), posString(e.Expr), + ) } - return fmt.Sprintf("%v\n\n%s", e.Err, ExprText(e.Expr)) + return fmt.Sprintf( + "%v\n\n%s\n\t%s", + e.Err, ExprText(e.Expr), posString(e.Expr), + ) } var ( diff --git a/internal/rosa/azalea/evaluate_test.go b/internal/rosa/azalea/evaluate_test.go index 049fcb52..edd72432 100644 --- a/internal/rosa/azalea/evaluate_test.go +++ b/internal/rosa/azalea/evaluate_test.go @@ -6,6 +6,7 @@ import ( "reflect" "strings" "testing" + "text/scanner" "unique" . "hakurei.app/internal/rosa/azalea" @@ -81,6 +82,12 @@ func TestEvaluate(t *testing.T) { Args: []Arg{ {K: []Ident{"v"}, V: Val{Int(9)}}, }, + Pos: scanner.Position{ + Filename: "apply_undefined.az", + Offset: 1, + Line: 1, + Column: 2, + }, }, Err: UndefinedError("v"), }}, @@ -96,8 +103,13 @@ func TestEvaluate(t *testing.T) { }), "\x00", nil}, {"undefined function", `f {}`, nil, "", EvaluationError{ - Expr: Func{Ident: "f"}, - Err: UndefinedError("f"), + Expr: Func{Ident: "f", Pos: scanner.Position{ + Filename: "undefined_function.az", + Offset: 1, + Line: 1, + Column: 2, + }}, + Err: UndefinedError("f"), }}, {"error wrap deep", `f { v = nonexistent; }`, makeStackCheck(func( @@ -128,6 +140,12 @@ func TestEvaluate(t *testing.T) { Args: []Arg{ {K: []Ident{"v"}, V: Val{Ident("nil")}}, }, + Pos: scanner.Position{ + Filename: "apply_nil_string.az", + Offset: 1, + Line: 1, + Column: 2, + }, }, Err: NilError{Type: reflect.TypeFor[string]()}, }}, @@ -184,6 +202,13 @@ func TestEvaluate(t *testing.T) { "v", }, V: Val{Array(nil)}}, }, + + Pos: scanner.Position{ + Filename: "common_inputs.az", + Offset: 12, + Line: 1, + Column: 13, + }, }, Err: ErrInvalidSpecial, }}, @@ -196,6 +221,13 @@ func TestEvaluate(t *testing.T) { Args: []Arg{ {K: []Ident{"inputs"}, V: Val{Array(nil)}, R: true}, }, + + Pos: scanner.Position{ + Filename: "bound_inputs.az", + Offset: 12, + Line: 1, + Column: 13, + }, }, Err: ErrInvalidSpecial, }}, @@ -208,6 +240,13 @@ func TestEvaluate(t *testing.T) { Args: []Arg{ {K: []Ident{"runtime"}, V: Val{Array(nil)}, R: true}, }, + + Pos: scanner.Position{ + Filename: "bound_runtime.az", + Offset: 12, + Line: 1, + Column: 13, + }, }, Err: ErrInvalidSpecial, }}, @@ -220,6 +259,13 @@ func TestEvaluate(t *testing.T) { Args: []Arg{ {K: []Ident{"inputs"}, V: Val{String(""), String("")}}, }, + + Pos: scanner.Position{ + Filename: "concat_inputs.az", + Offset: 12, + Line: 1, + Column: 13, + }, }, Err: ErrInvalidSpecial, }}, @@ -232,6 +278,13 @@ func TestEvaluate(t *testing.T) { Args: []Arg{ {K: []Ident{"source"}, V: Val{String(""), String("")}}, }, + + Pos: scanner.Position{ + Filename: "concat_source.az", + Offset: 12, + Line: 1, + Column: 13, + }, }, Err: ErrInvalidSpecial, }}, @@ -250,7 +303,10 @@ func TestEvaluate(t *testing.T) { t.Parallel() var expr Func - if e, err := Parse(strings.NewReader(tc.data)); err != nil { + if e, err := Parse( + strings.NewReader(tc.data), + strings.ReplaceAll(tc.name, " ", "_")+".az", + ); err != nil { t.Fatal(err) } else if len(e) != 1 { t.Fatalf("got expression %#v", e) @@ -294,7 +350,7 @@ func TestEvaluateGCC(t *testing.T) { t.Parallel() var gcc Func - if e, err := Parse(strings.NewReader(sample)); err != nil { + if e, err := Parse(strings.NewReader(sample), "./testdata/gcc.az"); err != nil { t.Fatal(err) } else { gcc = e[0].(Func) @@ -421,7 +477,7 @@ func TestEvaluateGCC(t *testing.T) { func BenchmarkEvaluate(b *testing.B) { var gcc Func - if e, err := Parse(strings.NewReader(sample)); err != nil { + if e, err := Parse(strings.NewReader(sample), "testdata/gcc.az"); err != nil { b.Fatal(err) } else { gcc = e[0].(Func) diff --git a/internal/rosa/builtins.go b/internal/rosa/builtins.go index edca2333..bca69a03 100644 --- a/internal/rosa/builtins.go +++ b/internal/rosa/builtins.go @@ -135,7 +135,7 @@ func init() { panic(err) } t := time.Now() - if err = builtin.RegisterFS(sub); err != nil { + if err = builtin.RegisterFS(sub, "internal/rosa/package/"); err != nil { println(err.Error()) os.Exit(1) } diff --git a/internal/rosa/cmake.go b/internal/rosa/cmake.go index 049688e5..b22c124f 100644 --- a/internal/rosa/cmake.go +++ b/internal/rosa/cmake.go @@ -20,6 +20,8 @@ type CMakeHelper struct { // Use the bootstrap minimal [MakeHelper] CMake. Early bool + // Omit CMAKE_CROSSCOMPILING_EMULATOR, because qemu is not yet available. + SkipEmulator bool // Value of CMAKE_BUILD_TYPE. The zero value is equivalent to "Release". BuildType string @@ -40,16 +42,22 @@ type CMakeHelper struct { var _ Helper = new(CMakeHelper) // tools returns the cmake handle alongside either ninja or make. -func (attr *CMakeHelper) tools(Toolchain) P { - h := _cmake - if attr != nil && attr.Early { - h = _cmakeEarly - } +func (attr *CMakeHelper) tools(t Toolchain) P { + tools := P{_cmake, _ninja, _qemu} + if attr != nil { + if attr.Early { + tools[0] = _cmakeEarly + } + + if attr.Make { + tools[1] = _make + } - if attr != nil && attr.Make { - return P{h, _make} + if !t.cross() || attr.SkipEmulator { + tools = tools[:2] + } } - return P{h, _ninja} + return tools } // inputs is a noop. @@ -85,7 +93,8 @@ func (attr *CMakeHelper) script(t Toolchain, name string) string { } script := attr.Script - if !attr.SkipTest && t.opts&OptSkipCheck == 0 { + if !attr.SkipTest && t.opts&OptSkipCheck == 0 && + !(t.cross() && attr.SkipEmulator) { script += "\n" + test } @@ -108,6 +117,11 @@ func (attr *CMakeHelper) script(t Toolchain, name string) string { -DCMAKE_CXX_FLAGS='--target=` + target + ` --sysroot=` + sysroot + `' \ -DCMAKE_ASM_COMPILER=` + Prefix + `/bin/clang \ -DCMAKE_ASM_FLAGS='--target=` + target + ` --sysroot=` + sysroot + `' \` + + if !attr.SkipEmulator { + cross += ` + -DCMAKE_CROSSCOMPILING_EMULATOR='qemu-` + t.linuxArch() + `;-L;` + sysroot + `' \` + } } return ` diff --git a/internal/rosa/doc.go b/internal/rosa/doc.go new file mode 100644 index 00000000..9c61a751 --- /dev/null +++ b/internal/rosa/doc.go @@ -0,0 +1,549 @@ +/* +Package rosa implements the Rosa OS build system via package [hakurei.app/pkg]. + +Software packages required by the Rosa OS base system are included in the +package directory. By default, these built-in packages are embedded at compile +time. The penv build tag may be used to specify the pathname of the source code +of this package at runtime via the environment variable ROSA_SOURCE. Note that +changes to Go code still requires recompilation. + +Software packages not part of the Rosa OS base system must not be added to +the built-in package directory. Additional Azalea source code may be registered +using the [S.RegisterAzalea] function in a new instance of [S]. The +[Rosa OS packages repository] is a good place to put additional packages. + +# Native artifacts + +Package rosa implements custom [hakurei.app/pkg] artifacts. This package must +not be used alongside other packages also implementing custom artifacts. As a +protection against simple cases of this, importing this package sets the +extension variant identification string to [Extension]. + +# Toolchain stages + +Rosa OS has three kinds of toolchain stages, with two sets of each and an +additional [Stage3] final stage. This adds up to a total of seven stages, +however not all of them are normally used. + +Every Rosa OS package is rooted in a binary seed containing at least a +shell and a LLVM toolchain. The early stage, a stage where the unexported +isStage0 method returns true, provides an environment from this binary seed +using only native artifacts. This stage does not support many fields of the +[PackageAttr] structure or [Helper] primitives. Special care must be taken for +packages compiled against this toolchain. + +The intermediate stage (where the unexported isIntermediate method returns true) +and the std stage (where the unexported isStd method returns true) are +functionally identical. They support all [PackageAttr] fields and [Helper] +primitives. The purpose of the intermediate stage is to complete a 3-stage +bootstrap for the mksh shell and LLVM toolchain. + +The final [Stage3] toolchain should generally only be used to validate 3-stage +determinism of the LLVM toolchain itself, by building a fourth LLVM stage. This +works around deficiencies in the CMake-based build system of the LLVM project +when compiling a dynamically-linked LLVM toolchain against a dynamically-linked +host LLVM toolchain. + +The set of Gentoo-derived toolchains are rooted in a Gentoo Linux stage3 +tarball. These are for completing the 3-stage bootstrap of the initial Rosa OS +stage0 toolchain distribution only and is never used again. This bootstrap +path might become broken from time to time. Historically, this is also required +when bootstrapping a completely new architecture, however that is now done via +cross-compilation, so the Gentoo bootstrap path is no longer invoked. The +unexported isRosa method returns whether a toolchain is not rooted in Gentoo. + +# Declaring packages + +Rosa OS packages are described using the Azalea language. Packages must be +declared at the top level: + + package hakurei-source { + // short user-facing description, included in package metadata + description = "hakurei source tree"; + // whether to exclude from listings in exported functions + exclude = true; + + // package version, # adds it to the current scope; if source is set and + // refers to a package declared at the top level, this defaults to the + // version of that package + version# = "0.4.10"; + + // a non-nil output artifact bypasses the build system + output = remoteGit { + url = "https://src.rosa.moe/hakurei"; + // using the version variable previously added to the scope + tag = "v"+version; + checksum = "SZdto_lQCgwebCqUHJREQcHwwO1pHn3euOwFvXYEri0G-46zUhx0hX4buFt2XvkS"; + }; + } + + package hakurei-dist { + // short user-facing description, included in package metadata + description = "low-level userspace tooling for Rosa OS "+ + "(distribution tarball)"; + + // project home page, included in package metadata + website = "https://hakurei.app"; + + // project identifier on release-monitoring.org, to check for updates + anitya = 388834; + + // if non-empty, provides a maintainer-facing reason of blocked update + // and prevent checking for updates via anitya + block = ""; + + // if non-nil, overrides the version filtering function + latest = anityaFallback; + + // artifact containing the source tree, placed in /usr/src/ under a + // directory named after the package, see section "Source fetchers"; + // this can also refer to a package declared at the top level like done + // here + source = hakurei-source; + + // pathnames of patches to apply to source, relative to the Azalea file; + // must be within the base directory + patches = []; + + // unconditionally enter source directory early + enterSource = true; + + // allow writes to the source tree, with all writes going to an + // anonymous instance of tmpfs + writable = true; + + // make all files writable in the source tree + chmod = true; + + // additional files to make available, relative to the Azalea file, + // within the base directory + files = { + // specifying a relative pathname places the file in /usr/src/ under + // the specified name + ".config": arch+".config"; + + // specifying an absolute pathname places the file at the specified + // pathname as is + "/sbin/installkernel": "installkernel"; + // if the contents of the file begins with certain sequences of + // bytes, it is automatically made executable + "/sbin/depmod": "depmod"; + + // prefix is the Rosa OS installation prefix, with the leading path + // separator + prefix+"/oldconfig": "oldconfig"; + }; + + // whether the resulting artifact dodges all other artifacts with this + // field set when being scheduled to cure + exclusive = false; + + // whether the build process does not require the LLVM toolchain + minimal = false; + + // whether this package is allowed in bootstrap stages + bootstrap = true; + + // whether this package requires libc; defaults to true + libc = true; + + // additional environment variables + env = [ + "CGO_ENABLED=1", + "GOCACHE=/tmp/gocache", + "CC=clang -O3 -Werror", + ]; + + // runs before script emitted by exec, implies enterSource if non-empty + early = ""; + + // programs to make available in /bin/ + bin = [ "hostname" ]; + + // whether to replace /usr/bin/ with a symlink to /bin/ + populateUsrBin = false; + + // build system helper, see section "Build system helpers" + exec = generic { + chdir = false; + cross = ` + export HAKUREI_ARCH='`+arch+`' + export HAKUREI_SYSROOT='`+prefix+`/`+arch+`' + + export PKG_CONFIG_SYSROOT_DIR='`+prefix+`/`+arch+`' + export PKG_CONFIG_LIBDIR='`+prefix+`/`+arch+prefix+`/lib/pkgconfig:`+ + prefix+`/`+arch+``+prefix+`/share/pkgconfig' + `; + build = ` + NAME=make`; + check = ` + NAME=all`; + install = ` + DESTDIR=/work "./${NAME}.sh" + `; + }; + + // if non-nil, measures the outcome of the package and fails if it does + // not match the specified checksum value + checksum = nil; + + // native utilities used during the build + tools = [ + go, + pkgconf, + net-tools, + acl, + wayland, + wayland-protocols, + ]; + + // packages made available for the target architecture, in the cross + // sysroot if cross-compiling + inputs = [ + libseccomp, + acl, + fuse, + xcb, + wayland, + wayland-protocols, + util-linux, + kernel-headers, + ]; + + // additional packages to place under directories named after each + // package in /usr/src/ + extra = []; + + // if non-empty, packages specified in extra are overlay-mounted under + // this pathname instead + overlay = ""; + + // inputs made available only during cross-compilation; setting this to + // nil indicates that this package does not require cross-compilation + // because its outcome is identical regardless of the target + cross = []; + + // native utilities made available only during cross-compilation + native = []; + + // whether explicitly specified runtime dependencies are combined with + // resolved runtimes instead of overriding it + join = false; + + // runtime dependencies, resolved from inputs if unset + runtime = nil; + + // whether this package is unlikely to become a runtime dependency + unlikely = true; + } + +# Built-in constants + + prefix Rosa OS installation prefix + prefixR Rosa OS installation prefix relative to sysroot + unversioned special version string denoting an unversioned package + + hostTriple Rosa OS host triple of the current system + hostArch architecture target name of the current system + hostLinuxArch architecture name used by Linux for the current system + + triple Rosa OS host triple of the target system + arch architecture target name of the target system + linuxArch architecture name used by Linux for the target system + llvmArch architecture name used by LLVM for the target system + + jobsE expression for preferred job count + jobsFlagE expression for flag with preferred job count (such as -j8) + jobsLE expression for twice of preferred job count + jobsLFlagE expression for flag with twice of preferred job count (such + as -j16) + + loadE expression for preferred loadavg target + loadFlagE expression for flag with preferred loadavg target (such as + -l9) + + anityaFallback version filter function pointer, returns the first stable + version, or latest if that is unavailable + +# Library functions + +replace returns a copy of the string s with the first n non-overlapping +instances of old replaced by new. If old is empty, it matches at the beginning +of the string and after each UTF-8 sequence, yielding up to k+1 replacements for +a k-rune string. If n == 0, there is no limit on the number of replacements. + + replace { + s = "2.9.0"; + old = "."; + new = "_"; + n = 2; + } + // returns "2_9_0" + +slice returns a subslice of elems. + + slice { + elems = split { + s = "2.42.4"; + sep = "."; + n = 3; + }; + start = 0; + end = 2; + } + // returns [ "2", "42" ] + +join concatenates elems to create a single string. The separator string sep is +placed between elements in the resulting string. + + join { + elems = slice { + elems = split { + s = "2.42.4"; + sep = "."; + n = 3; + }; + end = 2; + }; + sep = "."; + } + // returns "2.42" + +arch returns the value specified for the identifier referring to the target +architecture. As a special case, the cross identifier is matched if currently +cross-compiling, and the target architecture did not match any value specified +before the cross identifier. + + arch { + cross = unset; + default = arch; + + amd64 = "x86"; + ppc64le = "powerpc"; + riscv64 = "riscv"; + } + +# Source fetchers + +remoteTar reads an (optionally compressed) tar stream from url and unpacks its +contents. It is a cure error if the checksum of the full stream read until EOF +from url does not match the specified checksum. + + remoteTar { + url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-"+version+".tar.gz"; + checksum = "e-OfydG1EoUUuOCLHZn2XXt1h3ONKo9fg67IAcYSfU-3c8HrBXJ259AtdC8CZdk0"; + + // available decompressors: gzip, bzip2, zstd + // + // defaults to uncompressed + compress = gzip; + }; + +remoteFile reads the stream from url until EOF. It is a cure error if the +checksum of the full stream read from url does not match the specified checksum. + + remoteFile { + url = "https://web.archive.org/web/"+version+"id_/"+ + "https://www.iana.org/assignments/enterprise-numbers.txt"; + checksum = "IplVyf7P4PDhhDovWCzL6jPGmF0T75InOCv2IOTMoR7khHUcRfki1pY93kobuXHF"; + }; + +remoteGit downloads a remote git repository using the git package. It is a cure +error if the checksum of the [hakurei.app/pkg] archive of the resulting +directory does not match the specified checksum. + + output = remoteGit { + url = "https://src.rosa.moe/hakurei"; + tag = "v"+version; + checksum = "SZdto_lQCgwebCqUHJREQcHwwO1pHn3euOwFvXYEri0G-46zUhx0hX4buFt2XvkS"; + }; + +remoteGitLab downloads the specified ref from a GitLab instance. It is a cure +error if the checksum of the compressed tar stream read from the GitLab instance +does not match the specified checksum. + + remoteGitLab { + domain = "gitlab.freedesktop.org"; + suffix = "wayland/wayland"; + ref = version; + checksum = "79UJi1LDcQBoYl_yR7Jnt3OXptvyklTdJB7GZIeF_Zb0q0ETQRBp5RqsltdZOTAp"; + }; + +remoteGitHub downloads the specified tag from Microsoft Github. It is a cure +error if the checksum of the compressed tar stream read from Microsoft Github +does not match the specified checksum. + + remoteGitHub { + suffix = "nss-dev/nss"; + tag = "NSS_"+join { + elems = split { + s = version; + sep = "."; + n = 3; + }; + sep = "_"; + }+"_RTM"; + checksum = "GBkrmgdeEjvmLuWq6_EX5nkfebL4ojBE0yHsBgeijX7cnoLA5aOY2Z-GIolJwFy_"; + }; + +# Build system helpers + +generic directly passes build script segments for invocations of one-off build +scripts too specific to fit into any other [Helper] implementation. + + generic { + // whether to enter a newly created work directory; defaults to true + chdir = false; + + // runs only if cross-compiling + cross = ` + export HAKUREI_ARCH='`+arch+`' + export HAKUREI_SYSROOT='`+prefix+`/`+arch+`' + + export PKG_CONFIG_SYSROOT_DIR='`+prefix+`/`+arch+`' + export PKG_CONFIG_LIBDIR='`+prefix+`/`+arch+prefix+`/lib/pkgconfig:`+ + prefix+`/`+arch+``+prefix+`/share/pkgconfig' + `; + + // runs first, or after cross if cross-compiling + build = ` + NAME=make`; + + // runs after build, if testing is enabled + check = ` + NAME=all`; + + // runs after build and check + install = ` + DESTDIR=/work "./${NAME}.sh" + `; + } + +make wraps the make program and optionally an autotools-generated build system. + + make { + // whether to enter a newly created work directory; defaults to true + chdir = true; + + // command to generate the build system if non-empty + generate = ""; + + // runs before configure + preConfigure = ""; + + // cross targets to pass to the configure script, the zero value passes + // the Rosa OS target triples, the string `""` causes the corresponding + // flag(s) to be omitted + host, build = ""; + + // whether to let autotools infer the target triple + autoTarget = false; + + // whether to pass sysroot pathname to the configure script, defaults + // to true + sysroot = true; + + // do not clear program prefix/suffix + defaultName = false; + + // alternative name for the configure script if non-empty + configureName = ""; + + // generate autoconf arguments regardless of configureName + forceAutoconf = false; + + // flags passed to the configure script + configure = { + "disable-multilib"; + "enable-default-pie"; + "disable-nls"; + "with-gnu-as"; + "with-gnu-ld"; + "with-system-zlib"; + "enable-languages": "c,c++,go"; + "with-native-system-header-dir": prefix+"/include"; + + "with-multilib-list": arch { + amd64, arm64 = "''"; + }; + }; + + // runs before make + preMake = ""; + + // additional make arguments + make = [ + "BOOT_CFLAGS='-O2 -g'", + "bootstrap", + ]; + + // runs before check + preCheck = ""; + + // replaces the check arguments if non-empty + check = nil; + + // replaces the default install command if non-empty + install = ""; + }; + +cmake builds and tests a CMake project with specified CACHE entries. + + cmake { + // path elements joined with source + append = [ "compiler-rt/lib/builtins" ]; + + // CMake CACHE entries + cache = { + "LLVM_HOST_TRIPLE": triple; + "LLVM_ENABLE_RTTI": "ON"; + "LLVM_BUILD_LLVM_DYLIB": "ON"; + "LLVM_LINK_LLVM_DYLIB": "ON"; + "LLVM_ENABLE_PER_TARGET_RUNTIME_DIR": "ON"; + + "COMPILER_RT_DEFAULT_TARGET_ONLY": "ON"; + }; + + // runs after install + postInstall = ""; + + // replaces the default test command if non-empty; explicitly setting + // this to nil disables testing entirely + test = nil; + }; + +meson builds and tests a meson project. + + meson { + // whether to use muon instead of meson + muon = false; + + // -D flags passed to the setup command + setup = { + "default_library": "both"; + "documentation": "false"; + "tests": "true"; + }; + + // runs after setup + preCompile = ""; + + // runs after compile + postCompile = ""; + + // whether to run the test suite; defaults to true + test = true; + + // names of test suites to skip + skipTests = []; + + // whether to run tests with interactive input/output + interactiveTest = false; + + // runs after install + postInstall = ""; + }; + +[Rosa OS packages repository]: https://src.rosa.moe/packages +*/ +package rosa diff --git a/internal/rosa/llvm.go b/internal/rosa/llvm.go index dacb9098..b214fd83 100644 --- a/internal/rosa/llvm.go +++ b/internal/rosa/llvm.go @@ -293,6 +293,7 @@ cat << EOF > /work` + Prefix + `/bin/clang++.cfg EOF `, + SkipEmulator: true, // LLVM_LINK_LLVM_DYLIB causes llvm test suite to leak system // installation into test environment, and the tests end up testing the // system installation instead. Tests are disabled on stage0 and relies diff --git a/internal/rosa/make.go b/internal/rosa/make.go index 7a8bdec9..6f3d7526 100644 --- a/internal/rosa/make.go +++ b/internal/rosa/make.go @@ -222,7 +222,8 @@ make \ scriptMake += "\n" if !attr.SkipCheck && t.opts&OptSkipCheck == 0 && - (!attr.SkipCheckEarly || !t.stage.isStage0()) { + (!attr.SkipCheckEarly || !t.stage.isStage0()) && + !t.cross() { scriptMake += attr.ScriptCheckEarly + `make \ ` + jobsFlagE + ` \ ` + loadFlagE + ` \ diff --git a/internal/rosa/package/fribidi.az b/internal/rosa/package/fribidi.az index 28df4375..eb74f401 100644 --- a/internal/rosa/package/fribidi.az +++ b/internal/rosa/package/fribidi.az @@ -3,11 +3,11 @@ package fribidi { website = "https://github.com/fribidi/fribidi"; anitya = 857; - version# = "1.0.17"; + version# = "1.0.18"; source = remoteGitHub { suffix = "fribidi/fribidi"; tag = "v"+version; - checksum = "yJWcJqYDmzdyFB-kc9J1JDPLiqWHTw2n2bheXvqzP66bk56HYWW9sz_w-TMUqiEV"; + checksum = "2H3EBgweYle02Nzw7Echd_Bf6vQUk19zEP0F6-K1GywwKJZfmw8qtHE8Q5F5eHR2"; }; exec = meson { diff --git a/internal/rosa/package/fuse/package.az b/internal/rosa/package/fuse/package.az index b73432a3..f7fce8a6 100644 --- a/internal/rosa/package/fuse/package.az +++ b/internal/rosa/package/fuse/package.az @@ -20,6 +20,11 @@ package fuse { "useroot": "false"; "initscriptdir": prefix+"/etc"; }; + test = arch { + default = unset; + // some tests bypass meson exe_wrapper + cross = false; + }; }; tools = [ bash ]; diff --git a/internal/rosa/package/glib/package.az b/internal/rosa/package/glib/package.az index 9c531283..4e46d93f 100644 --- a/internal/rosa/package/glib/package.az +++ b/internal/rosa/package/glib/package.az @@ -22,6 +22,11 @@ package glib { }; // fails with ipv6 disabled skipTests = [ "gio" ]; + test = arch { + default = unset; + // some tests bypass meson exe_wrapper + cross = false; + }; }; tools = [ diff --git a/internal/rosa/package/hakurei.az b/internal/rosa/package/hakurei.az index a9283d96..1a7e953f 100644 --- a/internal/rosa/package/hakurei.az +++ b/internal/rosa/package/hakurei.az @@ -53,11 +53,14 @@ GOARCH='`+arch+`' CGO_ENABLED=0 go build -trimpath -tags=rosa -o /work`+prefix+` -buildid= -X main.hakureiPath=`+prefix+`/bin/hakurei " ./cmd/hsu`; - check = ` + check = arch { + default = ` echo echo '##### Testing hakurei.' go test -ldflags='-buildid= -linkmode external -extldflags=-static' ./... echo`; + cross = unset; + }; install = ` mkdir -p /work`+prefix+`/bin/ (cd /work`+prefix+`/libexec/hakurei && mv \ @@ -112,7 +115,7 @@ export HAKUREI_ARCH='`+arch+`' export HAKUREI_SYSROOT='`+prefix+`/`+arch+`' export PKG_CONFIG_SYSROOT_DIR='`+prefix+`/`+arch+`' -export PKG_CONFIG_LIBDIR='`+prefix+`/`+arch+``+prefix+`/lib/pkgconfig:`+prefix+`/`+arch+``+prefix+`/share/pkgconfig' +export PKG_CONFIG_LIBDIR='`+prefix+`/`+arch+prefix+`/lib/pkgconfig:`+prefix+`/`+arch+``+prefix+`/share/pkgconfig' `; build = ` NAME=make`; diff --git a/internal/rosa/package/kernel/amd64.config b/internal/rosa/package/kernel/amd64.config index d225563e..c7d172e0 100644 --- a/internal/rosa/package/kernel/amd64.config +++ b/internal/rosa/package/kernel/amd64.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86 6.18.59 Kernel Configuration +# Linux/x86 6.18.60 Kernel Configuration # CONFIG_CC_VERSION_TEXT="Rosa OS clang version 23.1.4" CONFIG_GCC_VERSION=0 diff --git a/internal/rosa/package/kernel/arm64.config b/internal/rosa/package/kernel/arm64.config index a3781679..96bde2e5 100644 --- a/internal/rosa/package/kernel/arm64.config +++ b/internal/rosa/package/kernel/arm64.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 6.18.59 Kernel Configuration +# Linux/arm64 6.18.60 Kernel Configuration # CONFIG_CC_VERSION_TEXT="Rosa OS clang version 23.1.4" CONFIG_GCC_VERSION=0 diff --git a/internal/rosa/package/kernel/package.az b/internal/rosa/package/kernel/package.az index 10aeb63f..9712713a 100644 --- a/internal/rosa/package/kernel/package.az +++ b/internal/rosa/package/kernel/package.az @@ -3,10 +3,10 @@ package kernel-source { website = "https://kernel.org"; exclude = true; - version# = "6.18.59"; + version# = "6.18.60"; output = remoteTar { url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-"+version+".tar.gz"; - checksum = "e-OfydG1EoUUuOCLHZn2XXt1h3ONKo9fg67IAcYSfU-3c8HrBXJ259AtdC8CZdk0"; + checksum = "tk4Ax1PBh2RiDE8MEiggD_RVWfSfxUp5Nm3nQ55ztUiaW2YUkfm1PIv-ZjDmCuPr"; compress = gzip; }; } @@ -91,12 +91,7 @@ package kernel { source = kernel-source; files = { - ".config": arch { - amd64 = "amd64.config"; - arm64 = "arm64.config"; - ppc64le = "ppc64le.config"; - riscv64 = "riscv64.config"; - }; + ".config": arch+".config"; "/sbin/installkernel": "installkernel"; // kernel is not aware of kmod moduledir diff --git a/internal/rosa/package/kernel/ppc64le.config b/internal/rosa/package/kernel/ppc64le.config index feab9155..424f8a57 100644 --- a/internal/rosa/package/kernel/ppc64le.config +++ b/internal/rosa/package/kernel/ppc64le.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/powerpc 6.18.59 Kernel Configuration +# Linux/powerpc 6.18.60 Kernel Configuration # CONFIG_CC_VERSION_TEXT="Rosa OS clang version 23.1.4" CONFIG_GCC_VERSION=0 diff --git a/internal/rosa/package/kernel/riscv64.config b/internal/rosa/package/kernel/riscv64.config index 2c7b46ef..ef218abc 100644 --- a/internal/rosa/package/kernel/riscv64.config +++ b/internal/rosa/package/kernel/riscv64.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/riscv 6.18.59 Kernel Configuration +# Linux/riscv 6.18.60 Kernel Configuration # CONFIG_CC_VERSION_TEXT="Rosa OS clang version 23.1.4" CONFIG_GCC_VERSION=0 diff --git a/internal/rosa/package/kmod.az b/internal/rosa/package/kmod.az index e7787d8f..a5050157 100644 --- a/internal/rosa/package/kmod.az +++ b/internal/rosa/package/kmod.az @@ -3,11 +3,11 @@ package kmod { website = "https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git"; anitya = 1517; - version# = "34.2"; + version# = "34.3"; source = remoteTar { url = "https://www.kernel.org/pub/linux/utils/kernel/"+ "kmod/kmod-"+version+".tar.gz"; - checksum = "0K7POeTKxMhExsaTsnKAC6LUNsRSfe6sSZxWONPbOu-GI_pXOw3toU_BIoqfBhJV"; + checksum = "lEeh4iLt40TSULexrrrUcS6Hm6XmC6HWW34oqVgcxZC1x0q1B1aCd7HtFk14khFQ"; compress = gzip; }; diff --git a/internal/rosa/package/libarchive/package.az b/internal/rosa/package/libarchive/package.az index bd57a860..8f0f2883 100644 --- a/internal/rosa/package/libarchive/package.az +++ b/internal/rosa/package/libarchive/package.az @@ -3,11 +3,11 @@ package libarchive { website = "https://www.libarchive.org"; anitya = 1558; - version# = "3.8.10"; + version# = "3.8.11"; source = remoteGitHub { suffix = "libarchive/libarchive"; tag = "v"+version; - checksum = "B8gGWvDB24_W4rzlPz1PxQYroCn-xOmUcnhsRVmzYl-L9mV_t6uj-TnpvjGqQjkV"; + checksum = "_rVNNd1axUWnT9tus-rN8gvn0KI-ofbQ3yBME3IQrCXIsC9kGdaGORVVAUXrTsVl"; }; files = { "CTestCustom.cmake"; }; @@ -15,7 +15,12 @@ package libarchive { writable = true; early = "\ninstall -Dv /usr/src/CTestCustom.cmake /cure/\n"; - exec = cmake {}; + exec = cmake { + test = arch { + default = unset; + cross = nil; + }; + }; inputs = [ zlib, diff --git a/internal/rosa/package/libdisplay-info.az b/internal/rosa/package/libdisplay-info.az index b953203b..99d4e419 100644 --- a/internal/rosa/package/libdisplay-info.az +++ b/internal/rosa/package/libdisplay-info.az @@ -11,7 +11,13 @@ package libdisplay-info { checksum = "CSa7niSNG6xpUiV5bhDIPp6PU239fzY3SShaneY0rhhuFYSxZFzKGTiE16-k6sSA"; }; - exec = meson {}; + exec = meson { + test = arch { + default = unset; + // some tests bypass meson exe_wrapper + cross = false; + }; + }; tools = [ diffutils, hwdata, diff --git a/internal/rosa/package/libdrm.az b/internal/rosa/package/libdrm.az index 6491da28..3ae9a8e5 100644 --- a/internal/rosa/package/libdrm.az +++ b/internal/rosa/package/libdrm.az @@ -15,6 +15,11 @@ package libdrm { setup = { "intel": "enabled"; }; + test = arch { + default = unset; + // some tests bypass meson exe_wrapper + cross = false; + }; }; tools = [ diff --git a/internal/rosa/package/libxml2.az b/internal/rosa/package/libxml2.az index a169c0e4..b0843081 100644 --- a/internal/rosa/package/libxml2.az +++ b/internal/rosa/package/libxml2.az @@ -14,7 +14,13 @@ package libxml2 { // can't create shell.out: Read-only file system writable = true; - exec = meson {}; + exec = meson { + test = arch { + default = unset; + // some tests bypass meson exe_wrapper + cross = false; + }; + }; tools = [ git, diff --git a/internal/rosa/package/llvm/package.az b/internal/rosa/package/llvm/package.az index 007b94c3..7a047b74 100644 --- a/internal/rosa/package/llvm/package.az +++ b/internal/rosa/package/llvm/package.az @@ -33,6 +33,7 @@ package early-builtins { "COMPILER_RT_DEFAULT_TARGET_ONLY": "ON"; }; + qemu = false; test = nil; }; @@ -85,6 +86,7 @@ message(NOTICE "${LLVM_VERSION_MAJOR}") "COMPILER_RT_BUILD_XRAY": "OFF"; "COMPILER_RT_BUILD_ORC": "OFF"; }; + qemu = false; test = nil; postInstall = ` mkdir -p "/work`+prefix+`/lib/clang/$LLVM_VERSION_MAJOR/lib/" @@ -139,6 +141,7 @@ package early-runtimes { "LLVM_ENABLE_ZSTD": "FORCE_ON"; "LLVM_ENABLE_LIBXML2": "OFF"; }; + qemu = false; test = nil; }; diff --git a/internal/rosa/package/pcre2.az b/internal/rosa/package/pcre2.az index e964ced0..74649dfd 100644 --- a/internal/rosa/package/pcre2.az +++ b/internal/rosa/package/pcre2.az @@ -18,6 +18,12 @@ package pcre2 { cache = { "PCRE2_SUPPORT_JIT": "ON"; }; + + test = arch { + default = unset; + // test suite bypasses ctest + cross = nil; + }; }; tools = [ diff --git a/internal/rosa/package/pipewire/package.az b/internal/rosa/package/pipewire.az index 8952b9ea..53c8749c 100644 --- a/internal/rosa/package/pipewire/package.az +++ b/internal/rosa/package/pipewire.az @@ -3,14 +3,13 @@ package wireplumber { website = "https://gitlab.freedesktop.org/pipewire/wireplumber"; anitya = 235056; - version# = "0.5.18"; + version# = "0.5.19"; source = remoteGitLab { domain = "gitlab.freedesktop.org"; suffix = "pipewire/wireplumber"; ref = version; - checksum = "YsKFuMxDJQtwnR0N7h7KA7fNR866k7XhCiSdn3L30Wn1kU7mTV66V8eHHL9dZ5sZ"; + checksum = "xvyjvJfQu1Jh56D460X6mrmgkxLO2TwBY5p-fCZg9eOc7RPLFvXNizbX9AFkhR7W"; }; - patches = [ "fcc8d79b6b5e1bc21ff7ea6353f3cd230e9243ee.patch" ]; // OSError: [Errno 30] Read-only file system: '../../usr/src/wireplumber/po/conf.pot' writable = true; diff --git a/internal/rosa/package/pipewire/fcc8d79b6b5e1bc21ff7ea6353f3cd230e9243ee.patch b/internal/rosa/package/pipewire/fcc8d79b6b5e1bc21ff7ea6353f3cd230e9243ee.patch deleted file mode 100644 index c5318f4f..00000000 --- a/internal/rosa/package/pipewire/fcc8d79b6b5e1bc21ff7ea6353f3cd230e9243ee.patch +++ /dev/null @@ -1,40 +0,0 @@ -From fcc8d79b6b5e1bc21ff7ea6353f3cd230e9243ee Mon Sep 17 00:00:00 2001 -From: Julian Bouzas <julian.bouzas@collabora.com> -Date: Fri, 16 Oct 2026 14:44:36 -0400 -Subject: [PATCH] m-lua-scripting: fix the values of the Perm constants - -Lua does not support octal literals, so the permission values were -parsed as decimal numbers and did not match the PipeWire ones. This -gave restricted and flatpak clients write and link permissions. Use -hexadecimal values instead. - -Fixes: #1044 -Assisted-by: Claude:claude-opus-5-5 ---- - modules/module-lua-scripting/api/api.lua | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/modules/module-lua-scripting/api/api.lua b/modules/module-lua-scripting/api/api.lua -index aafa49d98..0ca8c4155 100644 ---- a/modules/module-lua-scripting/api/api.lua -+++ b/modules/module-lua-scripting/api/api.lua -@@ -184,11 +184,11 @@ local Feature = { - }, - } - --PERM_R_VAL = 0400 --PERM_W_VAL = 0200 --PERM_X_VAL = 0100 --PERM_M_VAL = 0010 --PERM_L_VAL = 0020 -+PERM_R_VAL = 0x100 -+PERM_W_VAL = 0x080 -+PERM_X_VAL = 0x040 -+PERM_M_VAL = 0x008 -+PERM_L_VAL = 0x010 - - local Perm = { - NONE = 0, --- -GitLab - diff --git a/internal/rosa/package/spirv.az b/internal/rosa/package/spirv.az index 33a4816a..d2d4ad99 100644 --- a/internal/rosa/package/spirv.az +++ b/internal/rosa/package/spirv.az @@ -37,6 +37,12 @@ package spirv-tools { cross = prefix+"/"+arch; }+prefix; }; + + test = arch { + default = unset; + // attempts to invoke python through qemu + cross = nil; + }; }; tools = [ python ]; @@ -156,6 +162,12 @@ package spirv-llvm-translator { "LLVM_EXTERNAL_LIT": prefix+"/bin/lit"; "LLVM_INCLUDE_TESTS": "ON"; }; + + test = arch { + default = unset; + // lit does not use emulator specified for CMake + cross = nil; + }; }; tools = [ diff --git a/internal/rosa/package/wayland.az b/internal/rosa/package/wayland.az index 25f0c680..b07baafd 100644 --- a/internal/rosa/package/wayland.az +++ b/internal/rosa/package/wayland.az @@ -23,6 +23,13 @@ echo 'int main(){}' > tests/sanity-test.c "documentation": "false"; "tests": "true"; }; + + test = arch { + default = unset; + // some tests bypass meson exe_wrapper, qemu sets off + // fd leak tests + cross = false; + }; }; tools = [ @@ -45,12 +52,12 @@ package wayland-protocols { website = "https://wayland.freedesktop.org"; anitya = 13997; - version# = "1.49"; + version# = "1.50"; source = remoteGitLab { domain = "gitlab.freedesktop.org"; suffix = "wayland/wayland-protocols"; ref = version; - checksum = "HvV0Zk4KadZNqVBD-FXYN1ZcOsHI2HKnqVFk0hZzEF2jt3UZjkddgZLJthF0v8Ki"; + checksum = "MbaMJu7xnt604OQ9gGD717N_zR7vpJ9VcEfnnVnyQWJ6wVhhnTMtV3XGrXoocGux"; }; exec = meson {}; diff --git a/internal/rosa/package/zstd.az b/internal/rosa/package/zstd.az index 29e2c51f..47974385 100644 --- a/internal/rosa/package/zstd.az +++ b/internal/rosa/package/zstd.az @@ -18,10 +18,14 @@ package zstd { exec = cmake { append = [ "build", "cmake" ]; - test = ` + test = arch { + default = ` make -C /usr/src/zstd/tests datagen ZSTD_BIN=/cure/programs/zstd /usr/src/zstd/tests/playTests.sh `; + // does not use ctest + cross = nil; + }; }; tools = [ diff --git a/internal/rosa/rosa.go b/internal/rosa/rosa.go index 71755ef9..c50a7efe 100644 --- a/internal/rosa/rosa.go +++ b/internal/rosa/rosa.go @@ -1,4 +1,3 @@ -// Package rosa provides Rosa OS toolchain artifacts and miscellaneous software. package rosa import ( diff --git a/internal/rosa/state.go b/internal/rosa/state.go index febde19f..c236ee6d 100644 --- a/internal/rosa/state.go +++ b/internal/rosa/state.go @@ -226,15 +226,13 @@ type S struct { // crosscompiling state for the native architecture. var ErrInvalidCross = errors.New("invalid cross-compilation state") -// NewCross returns a copy of s for cross-compilation. Testing is disabled in -// the copy. +// NewCross returns a copy of s for cross-compilation. func (s *S) NewCross(arch string) *S { if s.native != nil && arch == s.native.Arch() { panic(ErrInvalidCross) } p := s.Clone() - p.opts |= OptSkipCheck p.native, p.arch = s, arch return p } @@ -928,8 +926,10 @@ func (s *S) getFrame() azalea.Frame { ) (v any, set bool, err error) { var attr CMakeHelper var test azalea.AString + qemu := true if err = args.Apply(map[unique.Handle[azalea.Ident]]any{ k("early"): &attr.Early, + k("qemu"): &qemu, k("append"): &attr.Append, k("buildType"): &attr.BuildType, k("cache"): &attr.Cache, @@ -939,6 +939,7 @@ func (s *S) getFrame() azalea.Frame { }); err != nil { return } + attr.SkipEmulator = !qemu attr.Test = test.V attr.SkipTest = test.Nil @@ -1274,15 +1275,21 @@ func (ctx *evalContext) pf( } if kc != nil { - checksum, ok := kc.(string) - if !ok { + switch checksum := kc.(type) { + case string: + attr.KnownChecksum = new(mustDecode(checksum)) + break + + case azalea.Nil: + break + + default: err = azalea.TypeError{ Concrete: reflect.TypeOf(kc), Asserted: reflect.TypeFor[string](), } return } - attr.KnownChecksum = new(mustDecode(checksum)) } if helper == nil { @@ -1309,9 +1316,9 @@ var ( // RegisterAzalea registers all package declarations from r. The backing // filesystem is directly exposed to azalea pathnames. -func (s *S) RegisterAzalea(r io.Reader, b fs.FS) error { +func (s *S) RegisterAzalea(r io.Reader, name string, b fs.FS) error { var pending []*azalea.Func - if expressions, err := azalea.Parse(r); err != nil { + if expressions, err := azalea.Parse(r, name); err != nil { return err } else { pending = make([]*azalea.Func, len(expressions)) @@ -1348,7 +1355,10 @@ func (s *S) RegisterAzalea(r io.Reader, b fs.FS) error { // evaluated if it is at the top level and its name has the suffix ".az", or it // is in a top-level directory with the exact file name "package.az". The // backing filesystem is directly exposed to azalea pathnames. -func (s *S) RegisterFS(fsys fs.FS) error { +// +// The prefix string is only used for position information and must use forward +// slashes as its path separator and end with a path separator. +func (s *S) RegisterFS(fsys fs.FS, prefix string) error { dents, err := fs.ReadDir(fsys, ".") if err != nil { return err @@ -1371,7 +1381,7 @@ func (s *S) RegisterFS(fsys fs.FS) error { return err } - err = s.RegisterAzalea(r, sub) + err = s.RegisterAzalea(r, prefix+dent.Name()+"/package.az", sub) if _err := r.Close(); err == nil { err = _err } @@ -1391,7 +1401,7 @@ func (s *S) RegisterFS(fsys fs.FS) error { return err } - err = s.RegisterAzalea(r, fsys) + err = s.RegisterAzalea(r, prefix+dent.Name(), fsys) if _err := r.Close(); err == nil { err = _err } diff --git a/internal/workflows/Containerfile b/internal/workflows/Containerfile index 82ce8820..991205b3 100644 --- a/internal/workflows/Containerfile +++ b/internal/workflows/Containerfile @@ -77,7 +77,7 @@ RUN PACKAGES=" \ "$MESON" compile -C build && \ "$MESON" install -C build && \ rm -rf build "/tmp/sway-$VERSION" && \ - VERSION='0.5.14' && \ + VERSION='0.5.19' && \ curl "https://gitlab.freedesktop.org/pipewire/wireplumber/-/archive/${VERSION}/wireplumber-${VERSION}.tar.bz2" | \ tar -C /tmp -jx && \ "$MESON" setup \ |
