forked from rosa/hakurei
Compare commits
67 Commits
38728cd627
...
staging
| Author | SHA1 | Date | |
|---|---|---|---|
|
823575acac
|
|||
|
136bc0917b
|
|||
|
d6b082dd0b
|
|||
|
89d6d9576b
|
|||
|
fafce04a5d
|
|||
|
5d760a1db9
|
|||
|
d197e40b2a
|
|||
|
2008902247
|
|||
|
30ac985fd2
|
|||
|
e9fec368f8
|
|||
|
46add42f58
|
|||
|
377b61e342
|
|||
|
520c36db6d
|
|||
|
3352bb975b
|
|||
|
f7f48d57e9
|
|||
|
5c2345128e
|
|||
|
78f9676b1f
|
|||
|
5b5b676132
|
|||
|
78383fb6e8
|
|||
|
e97f6a393f
|
|||
|
eeffefd22b
|
|||
|
ac825640ab
|
|||
|
a7f7ce1795
|
|||
|
38c639e35c
|
|||
|
b2cb13e94c
|
|||
|
46f98d12d6
|
|||
|
503c7f953c
|
|||
|
15c9f6545d
|
|||
|
83b0e32c55
|
|||
|
eeaf26e7a2
|
|||
|
b587caf2e8
|
|||
|
f1c2ca4928
|
|||
|
0ca301219f
|
|||
|
e2199e1276
|
|||
|
86eacb3208
|
|||
|
8541bdd858
|
|||
|
46be0b0dc8
|
|||
|
cbe37e87e7
|
|||
|
66d741fb07
|
|||
|
0d449011f6
|
|||
|
46428ed85d
|
|||
|
081d6b463c
|
|||
|
11b3171180
|
|||
|
adbb84c3dd
|
|||
|
1084e31d95
|
|||
|
27a1b8fe0a
|
|||
|
b2141a41d7
|
|||
|
c0dff5bc87
|
|||
|
04513c0510
|
|||
|
28ebf973d6
|
|||
|
41aeb404ec
|
|||
|
0b1009786f
|
|||
|
b390640376
|
|||
|
ad2c9f36cd
|
|||
|
67db3fbb8d
|
|||
|
560cb626a1
|
|||
|
c33a6a5b7e
|
|||
|
952082bd9b
|
|||
|
24a9b24823
|
|||
|
c2e61e7987
|
|||
|
86787b3bc5
|
|||
|
cdfcfe6ce0
|
|||
|
68a2f0c240
|
|||
|
7319c7adf9
|
|||
|
e9c890cbb2
|
|||
|
6f924336fc
|
|||
|
bd88f10524
|
@@ -2,7 +2,7 @@
|
||||
package check
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
@@ -30,6 +30,16 @@ func (e AbsoluteError) Is(target error) bool {
|
||||
// Absolute holds a pathname checked to be absolute.
|
||||
type Absolute struct{ pathname unique.Handle[string] }
|
||||
|
||||
var (
|
||||
_ encoding.TextAppender = new(Absolute)
|
||||
_ encoding.TextMarshaler = new(Absolute)
|
||||
_ encoding.TextUnmarshaler = new(Absolute)
|
||||
|
||||
_ encoding.BinaryAppender = new(Absolute)
|
||||
_ encoding.BinaryMarshaler = new(Absolute)
|
||||
_ encoding.BinaryUnmarshaler = new(Absolute)
|
||||
)
|
||||
|
||||
// ok returns whether [Absolute] is not the zero value.
|
||||
func (a *Absolute) ok() bool { return a != nil && *a != (Absolute{}) }
|
||||
|
||||
@@ -84,13 +94,16 @@ func (a *Absolute) Append(elem ...string) *Absolute {
|
||||
// Dir calls [filepath.Dir] with [Absolute] as its argument.
|
||||
func (a *Absolute) Dir() *Absolute { return unsafeAbs(filepath.Dir(a.String())) }
|
||||
|
||||
// GobEncode returns the checked pathname.
|
||||
func (a *Absolute) GobEncode() ([]byte, error) {
|
||||
return []byte(a.String()), nil
|
||||
// AppendText appends the checked pathname.
|
||||
func (a *Absolute) AppendText(data []byte) ([]byte, error) {
|
||||
return append(data, a.String()...), nil
|
||||
}
|
||||
|
||||
// GobDecode stores data if it represents an absolute pathname.
|
||||
func (a *Absolute) GobDecode(data []byte) error {
|
||||
// MarshalText returns the checked pathname.
|
||||
func (a *Absolute) MarshalText() ([]byte, error) { return a.AppendText(nil) }
|
||||
|
||||
// UnmarshalText stores data if it represents an absolute pathname.
|
||||
func (a *Absolute) UnmarshalText(data []byte) error {
|
||||
pathname := string(data)
|
||||
if !filepath.IsAbs(pathname) {
|
||||
return AbsoluteError(pathname)
|
||||
@@ -99,23 +112,9 @@ func (a *Absolute) GobDecode(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON returns a JSON representation of the checked pathname.
|
||||
func (a *Absolute) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(a.String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON stores data if it represents an absolute pathname.
|
||||
func (a *Absolute) UnmarshalJSON(data []byte) error {
|
||||
var pathname string
|
||||
if err := json.Unmarshal(data, &pathname); err != nil {
|
||||
return err
|
||||
}
|
||||
if !filepath.IsAbs(pathname) {
|
||||
return AbsoluteError(pathname)
|
||||
}
|
||||
a.pathname = unique.Make(pathname)
|
||||
return nil
|
||||
}
|
||||
func (a *Absolute) AppendBinary(data []byte) ([]byte, error) { return a.AppendText(data) }
|
||||
func (a *Absolute) MarshalBinary() ([]byte, error) { return a.MarshalText() }
|
||||
func (a *Absolute) UnmarshalBinary(data []byte) error { return a.UnmarshalText(data) }
|
||||
|
||||
// SortAbs calls [slices.SortFunc] for a slice of [Absolute].
|
||||
func SortAbs(x []*Absolute) {
|
||||
|
||||
@@ -170,20 +170,20 @@ func TestCodecAbsolute(t *testing.T) {
|
||||
|
||||
{"good", MustAbs("/etc"),
|
||||
nil,
|
||||
"\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\b\xff\x80\x00\x04/etc",
|
||||
",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x06\x00\x00\x00\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\x0f\xff\x84\x01\x04/etc\x01\xfc\xc0\xed\x00\x00\x00",
|
||||
"\t\x7f\x06\x01\x02\xff\x82\x00\x00\x00\b\xff\x80\x00\x04/etc",
|
||||
",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x06\x00\x00\x00\t\x7f\x06\x01\x02\xff\x82\x00\x00\x00\x0f\xff\x84\x01\x04/etc\x01\xfc\xc0\xed\x00\x00\x00",
|
||||
|
||||
`"/etc"`, `{"val":"/etc","magic":3236757504}`},
|
||||
{"not absolute", nil,
|
||||
AbsoluteError("etc"),
|
||||
"\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\a\xff\x80\x00\x03etc",
|
||||
",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x06\x00\x00\x00\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\x0f\xff\x84\x01\x03etc\x01\xfb\x01\x81\xda\x00\x00\x00",
|
||||
"\t\x7f\x06\x01\x02\xff\x82\x00\x00\x00\a\xff\x80\x00\x03etc",
|
||||
",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x06\x00\x00\x00\t\x7f\x06\x01\x02\xff\x82\x00\x00\x00\x0f\xff\x84\x01\x03etc\x01\xfb\x01\x81\xda\x00\x00\x00",
|
||||
|
||||
`"etc"`, `{"val":"etc","magic":3236757504}`},
|
||||
{"zero", nil,
|
||||
new(AbsoluteError),
|
||||
"\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\x04\xff\x80\x00\x00",
|
||||
",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x06\x00\x00\x00\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\f\xff\x84\x01\x00\x01\xfb\x01\x81\xda\x00\x00\x00",
|
||||
"\t\x7f\x06\x01\x02\xff\x82\x00\x00\x00\x04\xff\x80\x00\x00",
|
||||
",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x06\x00\x00\x00\t\x7f\x06\x01\x02\xff\x82\x00\x00\x00\f\xff\x84\x01\x00\x01\xfb\x01\x81\xda\x00\x00\x00",
|
||||
`""`, `{"val":"","magic":3236757504}`},
|
||||
}
|
||||
|
||||
@@ -347,15 +347,6 @@ func TestCodecAbsolute(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("json passthrough", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
wantErr := "invalid character ':' looking for beginning of value"
|
||||
if err := new(Absolute).UnmarshalJSON([]byte(":3")); err == nil || err.Error() != wantErr {
|
||||
t.Errorf("UnmarshalJSON: error = %v, want %s", err, wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestAbsoluteWrap(t *testing.T) {
|
||||
|
||||
@@ -38,8 +38,9 @@ var errSuccess = errors.New("success")
|
||||
|
||||
func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErrs, out io.Writer) command.Command {
|
||||
var (
|
||||
flagVerbose bool
|
||||
flagJSON bool
|
||||
flagVerbose bool
|
||||
flagInsecure bool
|
||||
flagJSON bool
|
||||
)
|
||||
c := command.New(out, log.Printf, "hakurei", func([]string) error {
|
||||
msg.SwapVerbose(flagVerbose)
|
||||
@@ -57,6 +58,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
||||
return nil
|
||||
}).
|
||||
Flag(&flagVerbose, "v", command.BoolFlag(false), "Increase log verbosity").
|
||||
Flag(&flagInsecure, "insecure", command.BoolFlag(false), "Allow use of insecure compatibility options").
|
||||
Flag(&flagJSON, "json", command.BoolFlag(false), "Serialise output in JSON when applicable")
|
||||
|
||||
c.Command("shim", command.UsageInternal, func([]string) error { outcome.Shim(msg); return errSuccess })
|
||||
@@ -75,7 +77,12 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
||||
config.Container.Args = append(config.Container.Args, args[1:]...)
|
||||
}
|
||||
|
||||
outcome.Main(ctx, msg, config, flagIdentifierFile)
|
||||
var flags int
|
||||
if flagInsecure {
|
||||
flags |= hst.VAllowInsecure
|
||||
}
|
||||
|
||||
outcome.Main(ctx, msg, config, flags, flagIdentifierFile)
|
||||
panic("unreachable")
|
||||
}).
|
||||
Flag(&flagIdentifierFile, "identifier-fd", command.IntFlag(-1),
|
||||
@@ -145,7 +152,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
||||
}
|
||||
}
|
||||
|
||||
var et hst.Enablement
|
||||
var et hst.Enablements
|
||||
if flagWayland {
|
||||
et |= hst.EWayland
|
||||
}
|
||||
@@ -163,7 +170,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
||||
ID: flagID,
|
||||
Identity: flagIdentity,
|
||||
Groups: flagGroups,
|
||||
Enablements: hst.NewEnablements(et),
|
||||
Enablements: &et,
|
||||
|
||||
Container: &hst.ContainerConfig{
|
||||
Filesystem: []hst.FilesystemConfigJSON{
|
||||
@@ -282,7 +289,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
||||
}
|
||||
}
|
||||
|
||||
outcome.Main(ctx, msg, &config, -1)
|
||||
outcome.Main(ctx, msg, &config, 0, -1)
|
||||
panic("unreachable")
|
||||
}).
|
||||
Flag(&flagDBusConfigSession, "dbus-config", command.StringFlag("builtin"),
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestHelp(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
"main", []string{}, `
|
||||
Usage: hakurei [-h | --help] [-v] [--json] COMMAND [OPTIONS]
|
||||
Usage: hakurei [-h | --help] [-v] [--insecure] [--json] COMMAND [OPTIONS]
|
||||
|
||||
Commands:
|
||||
run Load and start container from configuration file
|
||||
|
||||
@@ -56,7 +56,7 @@ func printShowInstance(
|
||||
t := newPrinter(output)
|
||||
defer t.MustFlush()
|
||||
|
||||
if err := config.Validate(); err != nil {
|
||||
if err := config.Validate(hst.VAllowInsecure); err != nil {
|
||||
valid = false
|
||||
if m, ok := message.GetMessage(err); ok {
|
||||
mustPrint(output, "Error: "+m+"!\n\n")
|
||||
|
||||
@@ -32,7 +32,7 @@ var (
|
||||
PID: 0xbeef,
|
||||
ShimPID: 0xcafe,
|
||||
Config: &hst.Config{
|
||||
Enablements: hst.NewEnablements(hst.EWayland | hst.EPipeWire),
|
||||
Enablements: new(hst.EWayland | hst.EPipeWire),
|
||||
Identity: 1,
|
||||
Container: &hst.ContainerConfig{
|
||||
Shell: check.MustAbs("/bin/sh"),
|
||||
|
||||
90
cmd/mbf/cache.go
Normal file
90
cmd/mbf/cache.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"hakurei.app/check"
|
||||
"hakurei.app/internal/pkg"
|
||||
"hakurei.app/message"
|
||||
)
|
||||
|
||||
// cache refers to an instance of [pkg.Cache] that might be open.
|
||||
type cache struct {
|
||||
ctx context.Context
|
||||
msg message.Msg
|
||||
|
||||
// Should generally not be used directly.
|
||||
c *pkg.Cache
|
||||
|
||||
cures, jobs int
|
||||
hostAbstract, idle bool
|
||||
|
||||
base string
|
||||
}
|
||||
|
||||
// open opens the underlying [pkg.Cache].
|
||||
func (cache *cache) open() (err error) {
|
||||
if cache.c != nil {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
if cache.base == "" {
|
||||
cache.base = "cache"
|
||||
}
|
||||
var base *check.Absolute
|
||||
if cache.base, err = filepath.Abs(cache.base); err != nil {
|
||||
return
|
||||
} else if base, err = check.NewAbs(cache.base); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var flags int
|
||||
if cache.idle {
|
||||
flags |= pkg.CSchedIdle
|
||||
}
|
||||
if cache.hostAbstract {
|
||||
flags |= pkg.CHostAbstract
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
go func() {
|
||||
select {
|
||||
case <-cache.ctx.Done():
|
||||
os.Exit(2)
|
||||
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
cache.msg.Verbosef("opening cache at %s", base)
|
||||
cache.c, err = pkg.Open(
|
||||
cache.ctx,
|
||||
cache.msg,
|
||||
flags,
|
||||
cache.cures,
|
||||
cache.jobs,
|
||||
base,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Close closes the underlying [pkg.Cache] if it is open.
|
||||
func (cache *cache) Close() {
|
||||
if cache.c != nil {
|
||||
cache.c.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Do calls f on the underlying cache and returns its error value.
|
||||
func (cache *cache) Do(f func(cache *pkg.Cache) error) error {
|
||||
if cache.c == nil {
|
||||
if err := cache.open(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return f(cache.c)
|
||||
}
|
||||
38
cmd/mbf/cache_test.go
Normal file
38
cmd/mbf/cache_test.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/internal/pkg"
|
||||
"hakurei.app/message"
|
||||
)
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cm := cache{
|
||||
ctx: context.Background(),
|
||||
msg: message.New(log.New(os.Stderr, "check: ", 0)),
|
||||
base: t.TempDir(),
|
||||
|
||||
hostAbstract: true, idle: true,
|
||||
}
|
||||
defer cm.Close()
|
||||
cm.Close()
|
||||
|
||||
if err := cm.open(); err != nil {
|
||||
t.Fatalf("open: error = %v", err)
|
||||
}
|
||||
if err := cm.open(); err != os.ErrInvalid {
|
||||
t.Errorf("(duplicate) open: error = %v", err)
|
||||
}
|
||||
|
||||
if err := cm.Do(func(cache *pkg.Cache) error {
|
||||
return cache.Scrub(0)
|
||||
}); err != nil {
|
||||
t.Errorf("Scrub: error = %v", err)
|
||||
}
|
||||
}
|
||||
127
cmd/mbf/info.go
Normal file
127
cmd/mbf/info.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"hakurei.app/internal/pkg"
|
||||
"hakurei.app/internal/rosa"
|
||||
)
|
||||
|
||||
// commandInfo implements the info subcommand.
|
||||
func commandInfo(
|
||||
cm *cache,
|
||||
args []string,
|
||||
w io.Writer,
|
||||
writeStatus bool,
|
||||
reportPath string,
|
||||
) (err error) {
|
||||
if len(args) == 0 {
|
||||
return errors.New("info requires at least 1 argument")
|
||||
}
|
||||
|
||||
var r *rosa.Report
|
||||
if reportPath != "" {
|
||||
if r, err = rosa.OpenReport(reportPath); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if closeErr := r.Close(); err == nil {
|
||||
err = closeErr
|
||||
}
|
||||
}()
|
||||
defer r.HandleAccess(&err)()
|
||||
}
|
||||
|
||||
// recovered by HandleAccess
|
||||
mustPrintln := func(a ...any) {
|
||||
if _, _err := fmt.Fprintln(w, a...); _err != nil {
|
||||
panic(_err)
|
||||
}
|
||||
}
|
||||
mustPrint := func(a ...any) {
|
||||
if _, _err := fmt.Fprint(w, a...); _err != nil {
|
||||
panic(_err)
|
||||
}
|
||||
}
|
||||
|
||||
for i, name := range args {
|
||||
if p, ok := rosa.ResolveName(name); !ok {
|
||||
return fmt.Errorf("unknown artifact %q", name)
|
||||
} else {
|
||||
var suffix string
|
||||
if version := rosa.Std.Version(p); version != rosa.Unversioned {
|
||||
suffix += "-" + version
|
||||
}
|
||||
mustPrintln("name : " + name + suffix)
|
||||
|
||||
meta := rosa.GetMetadata(p)
|
||||
mustPrintln("description : " + meta.Description)
|
||||
if meta.Website != "" {
|
||||
mustPrintln("website : " +
|
||||
strings.TrimSuffix(meta.Website, "/"))
|
||||
}
|
||||
if len(meta.Dependencies) > 0 {
|
||||
mustPrint("depends on :")
|
||||
for _, d := range meta.Dependencies {
|
||||
s := rosa.GetMetadata(d).Name
|
||||
if version := rosa.Std.Version(d); version != rosa.Unversioned {
|
||||
s += "-" + version
|
||||
}
|
||||
mustPrint(" " + s)
|
||||
}
|
||||
mustPrintln()
|
||||
}
|
||||
|
||||
const statusPrefix = "status : "
|
||||
if writeStatus {
|
||||
if r == nil {
|
||||
var f io.ReadSeekCloser
|
||||
err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||
f, err = cache.OpenStatus(rosa.Std.Load(p))
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
mustPrintln(
|
||||
statusPrefix + "not yet cured",
|
||||
)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
mustPrint(statusPrefix)
|
||||
_, err = io.Copy(w, f)
|
||||
if err = errors.Join(err, f.Close()); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
} else if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||
status, n := r.ArtifactOf(cache.Ident(rosa.Std.Load(p)))
|
||||
if status == nil {
|
||||
mustPrintln(
|
||||
statusPrefix + "not in report",
|
||||
)
|
||||
} else {
|
||||
mustPrintln("size :", n)
|
||||
mustPrint(statusPrefix)
|
||||
if _, err = w.Write(status); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if i != len(args)-1 {
|
||||
mustPrintln()
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
170
cmd/mbf/info_test.go
Normal file
170
cmd/mbf/info_test.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
"hakurei.app/internal/pkg"
|
||||
"hakurei.app/internal/rosa"
|
||||
"hakurei.app/message"
|
||||
)
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
status map[string]string
|
||||
report string
|
||||
want string
|
||||
wantErr any
|
||||
}{
|
||||
{"qemu", []string{"qemu"}, nil, "", `
|
||||
name : qemu-` + rosa.Std.Version(rosa.QEMU) + `
|
||||
description : a generic and open source machine emulator and virtualizer
|
||||
website : https://www.qemu.org
|
||||
depends on : glib-` + rosa.Std.Version(rosa.GLib) + ` zstd-` + rosa.Std.Version(rosa.Zstd) + `
|
||||
`, nil},
|
||||
|
||||
{"multi", []string{"hakurei", "hakurei-dist"}, nil, "", `
|
||||
name : hakurei-` + rosa.Std.Version(rosa.Hakurei) + `
|
||||
description : low-level userspace tooling for Rosa OS
|
||||
website : https://hakurei.app
|
||||
|
||||
name : hakurei-dist-` + rosa.Std.Version(rosa.HakureiDist) + `
|
||||
description : low-level userspace tooling for Rosa OS (distribution tarball)
|
||||
website : https://hakurei.app
|
||||
`, nil},
|
||||
|
||||
{"nonexistent", []string{"zlib", "\x00"}, nil, "", `
|
||||
name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
|
||||
description : lossless data-compression library
|
||||
website : https://zlib.net
|
||||
|
||||
`, fmt.Errorf("unknown artifact %q", "\x00")},
|
||||
|
||||
{"status cache", []string{"zlib", "zstd"}, map[string]string{
|
||||
"zstd": "internal/pkg (amd64) on satori\n",
|
||||
"hakurei": "internal/pkg (amd64) on satori\n\n",
|
||||
}, "", `
|
||||
name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
|
||||
description : lossless data-compression library
|
||||
website : https://zlib.net
|
||||
status : not yet cured
|
||||
|
||||
name : zstd-` + rosa.Std.Version(rosa.Zstd) + `
|
||||
description : a fast compression algorithm
|
||||
website : https://facebook.github.io/zstd
|
||||
status : internal/pkg (amd64) on satori
|
||||
`, nil},
|
||||
|
||||
{"status cache perm", []string{"zlib"}, map[string]string{
|
||||
"zlib": "\x00",
|
||||
}, "", `
|
||||
name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
|
||||
description : lossless data-compression library
|
||||
website : https://zlib.net
|
||||
`, func(cm *cache) error {
|
||||
return &os.PathError{
|
||||
Op: "open",
|
||||
Path: filepath.Join(cm.base, "status", pkg.Encode(cm.c.Ident(rosa.Std.Load(rosa.Zlib)).Value())),
|
||||
Err: syscall.EACCES,
|
||||
}
|
||||
}},
|
||||
|
||||
{"status report", []string{"zlib"}, nil, strings.Repeat("\x00", len(pkg.Checksum{})+8), `
|
||||
name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
|
||||
description : lossless data-compression library
|
||||
website : https://zlib.net
|
||||
status : not in report
|
||||
`, nil},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
cm *cache
|
||||
buf strings.Builder
|
||||
rp string
|
||||
)
|
||||
|
||||
if tc.status != nil || tc.report != "" {
|
||||
cm = &cache{
|
||||
ctx: context.Background(),
|
||||
msg: message.New(log.New(os.Stderr, "info: ", 0)),
|
||||
base: t.TempDir(),
|
||||
}
|
||||
defer cm.Close()
|
||||
}
|
||||
|
||||
if tc.report != "" {
|
||||
rp = filepath.Join(t.TempDir(), "report")
|
||||
if err := os.WriteFile(
|
||||
rp,
|
||||
unsafe.Slice(unsafe.StringData(tc.report), len(tc.report)),
|
||||
0400,
|
||||
); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if tc.status != nil {
|
||||
for name, status := range tc.status {
|
||||
p, ok := rosa.ResolveName(name)
|
||||
if !ok {
|
||||
t.Fatalf("invalid name %q", name)
|
||||
}
|
||||
perm := os.FileMode(0400)
|
||||
if status == "\x00" {
|
||||
perm = 0
|
||||
}
|
||||
if err := cm.Do(func(cache *pkg.Cache) error {
|
||||
return os.WriteFile(filepath.Join(
|
||||
cm.base,
|
||||
"status",
|
||||
pkg.Encode(cache.Ident(rosa.Std.Load(p)).Value()),
|
||||
), unsafe.Slice(unsafe.StringData(status), len(status)), perm)
|
||||
}); err != nil {
|
||||
t.Fatalf("Do: error = %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var wantErr error
|
||||
switch c := tc.wantErr.(type) {
|
||||
case error:
|
||||
wantErr = c
|
||||
case func(cm *cache) error:
|
||||
wantErr = c(cm)
|
||||
default:
|
||||
if tc.wantErr != nil {
|
||||
t.Fatalf("invalid wantErr %#v", tc.wantErr)
|
||||
}
|
||||
}
|
||||
|
||||
if err := commandInfo(
|
||||
cm,
|
||||
tc.args,
|
||||
&buf,
|
||||
cm != nil,
|
||||
rp,
|
||||
); !reflect.DeepEqual(err, wantErr) {
|
||||
t.Fatalf("commandInfo: error = %v, want %v", err, wantErr)
|
||||
}
|
||||
|
||||
if got := buf.String(); got != strings.TrimPrefix(tc.want, "\n") {
|
||||
t.Errorf("commandInfo:\n%s\nwant\n%s", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
282
cmd/mbf/main.go
282
cmd/mbf/main.go
@@ -14,6 +14,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -23,7 +24,6 @@ import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
@@ -53,14 +53,13 @@ func main() {
|
||||
log.Fatal("this program must not run as root")
|
||||
}
|
||||
|
||||
var cache *pkg.Cache
|
||||
ctx, stop := signal.NotifyContext(context.Background(),
|
||||
syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
||||
defer stop()
|
||||
|
||||
var cm cache
|
||||
defer func() {
|
||||
if cache != nil {
|
||||
cache.Close()
|
||||
}
|
||||
cm.Close()
|
||||
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println(r)
|
||||
@@ -70,55 +69,34 @@ func main() {
|
||||
|
||||
var (
|
||||
flagQuiet bool
|
||||
flagCures int
|
||||
flagBase string
|
||||
flagIdle bool
|
||||
|
||||
flagHostAbstract bool
|
||||
)
|
||||
c := command.New(os.Stderr, log.Printf, "mbf", func([]string) (err error) {
|
||||
c := command.New(os.Stderr, log.Printf, "mbf", func([]string) error {
|
||||
msg.SwapVerbose(!flagQuiet)
|
||||
|
||||
flagBase = os.ExpandEnv(flagBase)
|
||||
if flagBase == "" {
|
||||
flagBase = "cache"
|
||||
}
|
||||
|
||||
var base *check.Absolute
|
||||
if flagBase, err = filepath.Abs(flagBase); err != nil {
|
||||
return
|
||||
} else if base, err = check.NewAbs(flagBase); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var flags int
|
||||
if flagIdle {
|
||||
flags |= pkg.CSchedIdle
|
||||
}
|
||||
if flagHostAbstract {
|
||||
flags |= pkg.CHostAbstract
|
||||
}
|
||||
cache, err = pkg.Open(ctx, msg, flags, flagCures, base)
|
||||
|
||||
return
|
||||
cm.ctx, cm.msg = ctx, msg
|
||||
cm.base = os.ExpandEnv(cm.base)
|
||||
return nil
|
||||
}).Flag(
|
||||
&flagQuiet,
|
||||
"q", command.BoolFlag(false),
|
||||
"Do not print cure messages",
|
||||
).Flag(
|
||||
&flagCures,
|
||||
&cm.cures,
|
||||
"cures", command.IntFlag(0),
|
||||
"Maximum number of dependencies to cure at any given time",
|
||||
).Flag(
|
||||
&flagBase,
|
||||
&cm.jobs,
|
||||
"jobs", command.IntFlag(0),
|
||||
"Preferred number of jobs to run, when applicable",
|
||||
).Flag(
|
||||
&cm.base,
|
||||
"d", command.StringFlag("$MBF_CACHE_DIR"),
|
||||
"Directory to store cured artifacts",
|
||||
).Flag(
|
||||
&flagIdle,
|
||||
&cm.idle,
|
||||
"sched-idle", command.BoolFlag(false),
|
||||
"Set SCHED_IDLE scheduling policy",
|
||||
).Flag(
|
||||
&flagHostAbstract,
|
||||
&cm.hostAbstract,
|
||||
"host-abstract", command.BoolFlag(
|
||||
os.Getenv("MBF_HOST_ABSTRACT") != "",
|
||||
),
|
||||
@@ -126,6 +104,19 @@ func main() {
|
||||
"abstract UNIX sockets",
|
||||
)
|
||||
|
||||
c.NewCommand(
|
||||
"checksum", "Compute checksum of data read from standard input",
|
||||
func([]string) error {
|
||||
go func() { <-ctx.Done(); os.Exit(1) }()
|
||||
h := sha512.New384()
|
||||
if _, err := io.Copy(h, os.Stdin); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println(pkg.Encode(pkg.Checksum(h.Sum(nil))))
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
{
|
||||
var flagShifts int
|
||||
c.NewCommand(
|
||||
@@ -137,7 +128,9 @@ func main() {
|
||||
if flagShifts < 0 || flagShifts > 31 {
|
||||
flagShifts = 12
|
||||
}
|
||||
return cache.Scrub(runtime.NumCPU() << flagShifts)
|
||||
return cm.Do(func(cache *pkg.Cache) error {
|
||||
return cache.Scrub(runtime.NumCPU() << flagShifts)
|
||||
})
|
||||
},
|
||||
).Flag(
|
||||
&flagShifts,
|
||||
@@ -155,93 +148,7 @@ func main() {
|
||||
"info",
|
||||
"Display out-of-band metadata of an artifact",
|
||||
func(args []string) (err error) {
|
||||
if len(args) == 0 {
|
||||
return errors.New("info requires at least 1 argument")
|
||||
}
|
||||
|
||||
var r *rosa.Report
|
||||
if flagReport != "" {
|
||||
if r, err = rosa.OpenReport(flagReport); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if closeErr := r.Close(); err == nil {
|
||||
err = closeErr
|
||||
}
|
||||
}()
|
||||
defer r.HandleAccess(&err)()
|
||||
}
|
||||
|
||||
for i, name := range args {
|
||||
if p, ok := rosa.ResolveName(name); !ok {
|
||||
return fmt.Errorf("unknown artifact %q", name)
|
||||
} else {
|
||||
var suffix string
|
||||
if version := rosa.Std.Version(p); version != rosa.Unversioned {
|
||||
suffix += "-" + version
|
||||
}
|
||||
fmt.Println("name : " + name + suffix)
|
||||
|
||||
meta := rosa.GetMetadata(p)
|
||||
fmt.Println("description : " + meta.Description)
|
||||
if meta.Website != "" {
|
||||
fmt.Println("website : " +
|
||||
strings.TrimSuffix(meta.Website, "/"))
|
||||
}
|
||||
if len(meta.Dependencies) > 0 {
|
||||
fmt.Print("depends on :")
|
||||
for _, d := range meta.Dependencies {
|
||||
s := rosa.GetMetadata(d).Name
|
||||
if version := rosa.Std.Version(d); version != rosa.Unversioned {
|
||||
s += "-" + version
|
||||
}
|
||||
fmt.Print(" " + s)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
const statusPrefix = "status : "
|
||||
if flagStatus {
|
||||
if r == nil {
|
||||
var f io.ReadSeekCloser
|
||||
f, err = cache.OpenStatus(rosa.Std.Load(p))
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
fmt.Println(
|
||||
statusPrefix + "not yet cured",
|
||||
)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
fmt.Print(statusPrefix)
|
||||
_, err = io.Copy(os.Stdout, f)
|
||||
if err = errors.Join(err, f.Close()); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status, n := r.ArtifactOf(cache.Ident(rosa.Std.Load(p)))
|
||||
if status == nil {
|
||||
fmt.Println(
|
||||
statusPrefix + "not in report",
|
||||
)
|
||||
} else {
|
||||
fmt.Println("size :", n)
|
||||
fmt.Print(statusPrefix)
|
||||
if _, err = os.Stdout.Write(status); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if i != len(args)-1 {
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return commandInfo(&cm, args, os.Stdout, flagStatus, flagReport)
|
||||
},
|
||||
).
|
||||
Flag(
|
||||
@@ -287,7 +194,9 @@ func main() {
|
||||
if ext.Isatty(int(w.Fd())) {
|
||||
return errors.New("output appears to be a terminal")
|
||||
}
|
||||
return rosa.WriteReport(msg, w, cache)
|
||||
return cm.Do(func(cache *pkg.Cache) error {
|
||||
return rosa.WriteReport(msg, w, cache)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
@@ -382,25 +291,37 @@ func main() {
|
||||
rosa.SetGentooStage3(flagGentoo, checksum)
|
||||
}
|
||||
|
||||
_, _, _, stage1 := (t - 2).NewLLVM()
|
||||
_, _, _, stage2 := (t - 1).NewLLVM()
|
||||
_, _, _, stage3 := t.NewLLVM()
|
||||
var (
|
||||
pathname *check.Absolute
|
||||
checksum [2]unique.Handle[pkg.Checksum]
|
||||
)
|
||||
|
||||
if pathname, _, err = cache.Cure(stage1); err != nil {
|
||||
return err
|
||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||
pathname, _, err = cache.Cure(
|
||||
(t - 2).Load(rosa.Clang),
|
||||
)
|
||||
return
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
log.Println("stage1:", pathname)
|
||||
|
||||
if pathname, checksum[0], err = cache.Cure(stage2); err != nil {
|
||||
return err
|
||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||
pathname, checksum[0], err = cache.Cure(
|
||||
(t - 1).Load(rosa.Clang),
|
||||
)
|
||||
return
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
log.Println("stage2:", pathname)
|
||||
if pathname, checksum[1], err = cache.Cure(stage3); err != nil {
|
||||
return err
|
||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||
pathname, checksum[1], err = cache.Cure(
|
||||
t.Load(rosa.Clang),
|
||||
)
|
||||
return
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
log.Println("stage3:", pathname)
|
||||
|
||||
@@ -417,10 +338,13 @@ func main() {
|
||||
}
|
||||
|
||||
if flagStage0 {
|
||||
if pathname, _, err = cache.Cure(
|
||||
t.Load(rosa.Stage0),
|
||||
); err != nil {
|
||||
return err
|
||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||
pathname, _, err = cache.Cure(
|
||||
t.Load(rosa.Stage0),
|
||||
)
|
||||
return
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
log.Println(pathname)
|
||||
}
|
||||
@@ -465,7 +389,11 @@ func main() {
|
||||
|
||||
switch {
|
||||
default:
|
||||
pathname, _, err := cache.Cure(rosa.Std.Load(p))
|
||||
var pathname *check.Absolute
|
||||
err := cm.Do(func(cache *pkg.Cache) (err error) {
|
||||
pathname, _, err = cache.Cure(rosa.Std.Load(p))
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -505,7 +433,9 @@ func main() {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = cache.EncodeAll(f, rosa.Std.Load(p)); err != nil {
|
||||
if err = cm.Do(func(cache *pkg.Cache) error {
|
||||
return cache.EncodeAll(f, rosa.Std.Load(p))
|
||||
}); err != nil {
|
||||
_ = f.Close()
|
||||
return err
|
||||
}
|
||||
@@ -513,13 +443,15 @@ func main() {
|
||||
return f.Close()
|
||||
|
||||
case flagEnter:
|
||||
return cache.EnterExec(
|
||||
ctx,
|
||||
rosa.Std.Load(p),
|
||||
true, os.Stdin, os.Stdout, os.Stderr,
|
||||
rosa.AbsSystem.Append("bin", "mksh"),
|
||||
"sh",
|
||||
)
|
||||
return cm.Do(func(cache *pkg.Cache) error {
|
||||
return cache.EnterExec(
|
||||
ctx,
|
||||
rosa.Std.Load(p),
|
||||
true, os.Stdin, os.Stdout, os.Stderr,
|
||||
rosa.AbsSystem.Append("bin", "mksh"),
|
||||
"sh",
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
).
|
||||
@@ -551,7 +483,7 @@ func main() {
|
||||
"shell",
|
||||
"Interactive shell in the specified Rosa OS environment",
|
||||
func(args []string) error {
|
||||
presets := make([]rosa.PArtifact, len(args))
|
||||
presets := make([]rosa.PArtifact, len(args)+3)
|
||||
for i, arg := range args {
|
||||
p, ok := rosa.ResolveName(arg)
|
||||
if !ok {
|
||||
@@ -559,21 +491,24 @@ func main() {
|
||||
}
|
||||
presets[i] = p
|
||||
}
|
||||
|
||||
base := rosa.Clang
|
||||
if !flagWithToolchain {
|
||||
base = rosa.Musl
|
||||
}
|
||||
presets = append(presets,
|
||||
base,
|
||||
rosa.Mksh,
|
||||
rosa.Toybox,
|
||||
)
|
||||
|
||||
root := make(pkg.Collect, 0, 6+len(args))
|
||||
root = rosa.Std.AppendPresets(root, presets...)
|
||||
|
||||
if flagWithToolchain {
|
||||
musl, compilerRT, runtimes, clang := (rosa.Std - 1).NewLLVM()
|
||||
root = append(root, musl, compilerRT, runtimes, clang)
|
||||
} else {
|
||||
root = append(root, rosa.Std.Load(rosa.Musl))
|
||||
}
|
||||
root = append(root,
|
||||
rosa.Std.Load(rosa.Mksh),
|
||||
rosa.Std.Load(rosa.Toybox),
|
||||
)
|
||||
|
||||
if _, _, err := cache.Cure(&root); err == nil {
|
||||
if err := cm.Do(func(cache *pkg.Cache) error {
|
||||
_, _, err := cache.Cure(&root)
|
||||
return err
|
||||
}); err == nil {
|
||||
return errors.New("unreachable")
|
||||
} else if !pkg.IsCollected(err) {
|
||||
return err
|
||||
@@ -585,11 +520,22 @@ func main() {
|
||||
}
|
||||
cured := make(map[pkg.Artifact]cureRes)
|
||||
for _, a := range root {
|
||||
pathname, checksum, err := cache.Cure(a)
|
||||
if err != nil {
|
||||
if err := cm.Do(func(cache *pkg.Cache) error {
|
||||
pathname, checksum, err := cache.Cure(a)
|
||||
if err == nil {
|
||||
cured[a] = cureRes{pathname, checksum}
|
||||
}
|
||||
return err
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// explicitly open for direct error-free use from this point
|
||||
if cm.c == nil {
|
||||
if err := cm.open(); err != nil {
|
||||
return err
|
||||
}
|
||||
cured[a] = cureRes{pathname, checksum}
|
||||
}
|
||||
|
||||
layers := pkg.PromoteLayers(root, func(a pkg.Artifact) (
|
||||
@@ -599,7 +545,7 @@ func main() {
|
||||
res := cured[a]
|
||||
return res.pathname, res.checksum
|
||||
}, func(i int, d pkg.Artifact) {
|
||||
r := pkg.Encode(cache.Ident(d).Value())
|
||||
r := pkg.Encode(cm.c.Ident(d).Value())
|
||||
if s, ok := d.(fmt.Stringer); ok {
|
||||
if name := s.String(); name != "" {
|
||||
r += "-" + name
|
||||
@@ -689,9 +635,7 @@ func main() {
|
||||
)
|
||||
|
||||
c.MustParse(os.Args[1:], func(err error) {
|
||||
if cache != nil {
|
||||
cache.Close()
|
||||
}
|
||||
cm.Close()
|
||||
if w, ok := err.(interface{ Unwrap() []error }); !ok {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"hakurei.app/container/std"
|
||||
"hakurei.app/ext"
|
||||
"hakurei.app/fhs"
|
||||
"hakurei.app/internal/landlock"
|
||||
"hakurei.app/message"
|
||||
)
|
||||
|
||||
@@ -307,7 +308,7 @@ func (p *Container) Start() error {
|
||||
done <- func() error {
|
||||
// PR_SET_NO_NEW_PRIVS: thread-directed but acts on all processes
|
||||
// created from the calling thread
|
||||
if err := SetNoNewPrivs(); err != nil {
|
||||
if err := setNoNewPrivs(); err != nil {
|
||||
return &StartError{
|
||||
Fatal: true,
|
||||
Step: "prctl(PR_SET_NO_NEW_PRIVS)",
|
||||
@@ -317,12 +318,14 @@ func (p *Container) Start() error {
|
||||
|
||||
// landlock: depends on per-thread state but acts on a process group
|
||||
{
|
||||
rulesetAttr := &RulesetAttr{Scoped: LANDLOCK_SCOPE_SIGNAL}
|
||||
rulesetAttr := &landlock.RulesetAttr{
|
||||
Scoped: landlock.LANDLOCK_SCOPE_SIGNAL,
|
||||
}
|
||||
if !p.HostAbstract {
|
||||
rulesetAttr.Scoped |= LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET
|
||||
rulesetAttr.Scoped |= landlock.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET
|
||||
}
|
||||
|
||||
if abi, err := LandlockGetABI(); err != nil {
|
||||
if abi, err := landlock.GetABI(); err != nil {
|
||||
if p.HostAbstract || !p.HostNet {
|
||||
// landlock can be skipped here as it restricts access
|
||||
// to resources already covered by namespaces (pid, net)
|
||||
@@ -351,7 +354,7 @@ func (p *Container) Start() error {
|
||||
}
|
||||
} else {
|
||||
p.msg.Verbosef("enforcing landlock ruleset %s", rulesetAttr)
|
||||
if err = LandlockRestrictSelf(rulesetFd, 0); err != nil {
|
||||
if err = landlock.RestrictSelf(rulesetFd, 0); err != nil {
|
||||
_ = Close(rulesetFd)
|
||||
return &StartError{
|
||||
Fatal: true,
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"hakurei.app/fhs"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/info"
|
||||
"hakurei.app/internal/landlock"
|
||||
"hakurei.app/internal/params"
|
||||
"hakurei.app/ldd"
|
||||
"hakurei.app/message"
|
||||
@@ -456,7 +457,7 @@ func TestContainer(t *testing.T) {
|
||||
c.RetainSession = tc.session
|
||||
c.HostNet = tc.net
|
||||
if info.CanDegrade {
|
||||
if _, err := container.LandlockGetABI(); err != nil {
|
||||
if _, err := landlock.GetABI(); err != nil {
|
||||
if !errors.Is(err, syscall.ENOSYS) {
|
||||
t.Fatalf("LandlockGetABI: error = %v", err)
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ func (direct) lockOSThread() { runtime.LockOSThread() }
|
||||
|
||||
func (direct) setPtracer(pid uintptr) error { return ext.SetPtracer(pid) }
|
||||
func (direct) setDumpable(dumpable uintptr) error { return ext.SetDumpable(dumpable) }
|
||||
func (direct) setNoNewPrivs() error { return SetNoNewPrivs() }
|
||||
func (direct) setNoNewPrivs() error { return setNoNewPrivs() }
|
||||
|
||||
func (direct) lastcap(msg message.Msg) uintptr { return LastCap(msg) }
|
||||
func (direct) capset(hdrp *capHeader, datap *[2]capData) error { return capset(hdrp, datap) }
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
package container_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
"hakurei.app/container"
|
||||
)
|
||||
|
||||
func TestLandlockString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
rulesetAttr *container.RulesetAttr
|
||||
want string
|
||||
}{
|
||||
{"nil", nil, "NULL"},
|
||||
{"zero", new(container.RulesetAttr), "0"},
|
||||
{"some", &container.RulesetAttr{Scoped: container.LANDLOCK_SCOPE_SIGNAL}, "scoped: signal"},
|
||||
{"set", &container.RulesetAttr{
|
||||
HandledAccessFS: container.LANDLOCK_ACCESS_FS_MAKE_SYM | container.LANDLOCK_ACCESS_FS_IOCTL_DEV | container.LANDLOCK_ACCESS_FS_WRITE_FILE,
|
||||
HandledAccessNet: container.LANDLOCK_ACCESS_NET_BIND_TCP,
|
||||
Scoped: container.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | container.LANDLOCK_SCOPE_SIGNAL,
|
||||
}, "fs: write_file make_sym fs_ioctl_dev, net: bind_tcp, scoped: abstract_unix_socket signal"},
|
||||
{"all", &container.RulesetAttr{
|
||||
HandledAccessFS: container.LANDLOCK_ACCESS_FS_EXECUTE |
|
||||
container.LANDLOCK_ACCESS_FS_WRITE_FILE |
|
||||
container.LANDLOCK_ACCESS_FS_READ_FILE |
|
||||
container.LANDLOCK_ACCESS_FS_READ_DIR |
|
||||
container.LANDLOCK_ACCESS_FS_REMOVE_DIR |
|
||||
container.LANDLOCK_ACCESS_FS_REMOVE_FILE |
|
||||
container.LANDLOCK_ACCESS_FS_MAKE_CHAR |
|
||||
container.LANDLOCK_ACCESS_FS_MAKE_DIR |
|
||||
container.LANDLOCK_ACCESS_FS_MAKE_REG |
|
||||
container.LANDLOCK_ACCESS_FS_MAKE_SOCK |
|
||||
container.LANDLOCK_ACCESS_FS_MAKE_FIFO |
|
||||
container.LANDLOCK_ACCESS_FS_MAKE_BLOCK |
|
||||
container.LANDLOCK_ACCESS_FS_MAKE_SYM |
|
||||
container.LANDLOCK_ACCESS_FS_REFER |
|
||||
container.LANDLOCK_ACCESS_FS_TRUNCATE |
|
||||
container.LANDLOCK_ACCESS_FS_IOCTL_DEV,
|
||||
HandledAccessNet: container.LANDLOCK_ACCESS_NET_BIND_TCP |
|
||||
container.LANDLOCK_ACCESS_NET_CONNECT_TCP,
|
||||
Scoped: container.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
|
||||
container.LANDLOCK_SCOPE_SIGNAL,
|
||||
}, "fs: execute write_file read_file read_dir remove_dir remove_file make_char make_dir make_reg make_sock make_fifo make_block make_sym fs_refer fs_truncate fs_ioctl_dev, net: bind_tcp connect_tcp, scoped: abstract_unix_socket signal"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := tc.rulesetAttr.String(); got != tc.want {
|
||||
t.Errorf("String: %s, want %s", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLandlockAttrSize(t *testing.T) {
|
||||
t.Parallel()
|
||||
want := 24
|
||||
if got := unsafe.Sizeof(container.RulesetAttr{}); got != uintptr(want) {
|
||||
t.Errorf("Sizeof: %d, want %d", got, want)
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"hakurei.app/ext"
|
||||
)
|
||||
|
||||
// SetNoNewPrivs sets the calling thread's no_new_privs attribute.
|
||||
func SetNoNewPrivs() error {
|
||||
// setNoNewPrivs sets the calling thread's no_new_privs attribute.
|
||||
func setNoNewPrivs() error {
|
||||
return ext.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0)
|
||||
}
|
||||
|
||||
|
||||
@@ -140,21 +140,29 @@ var (
|
||||
ErrInsecure = errors.New("configuration is insecure")
|
||||
)
|
||||
|
||||
const (
|
||||
// VAllowInsecure allows use of compatibility options considered insecure
|
||||
// under any configuration, to work around ecosystem-wide flaws.
|
||||
VAllowInsecure = 1 << iota
|
||||
)
|
||||
|
||||
// Validate checks [Config] and returns [AppError] if an invalid value is encountered.
|
||||
func (config *Config) Validate() error {
|
||||
func (config *Config) Validate(flags int) error {
|
||||
const step = "validate configuration"
|
||||
|
||||
if config == nil {
|
||||
return &AppError{Step: "validate configuration", Err: ErrConfigNull,
|
||||
return &AppError{Step: step, Err: ErrConfigNull,
|
||||
Msg: "invalid configuration"}
|
||||
}
|
||||
|
||||
// this is checked again in hsu
|
||||
if config.Identity < IdentityStart || config.Identity > IdentityEnd {
|
||||
return &AppError{Step: "validate configuration", Err: ErrIdentityBounds,
|
||||
return &AppError{Step: step, Err: ErrIdentityBounds,
|
||||
Msg: "identity " + strconv.Itoa(config.Identity) + " out of range"}
|
||||
}
|
||||
|
||||
if config.SchedPolicy < 0 || config.SchedPolicy > ext.SCHED_LAST {
|
||||
return &AppError{Step: "validate configuration", Err: ErrSchedPolicyBounds,
|
||||
return &AppError{Step: step, Err: ErrSchedPolicyBounds,
|
||||
Msg: "scheduling policy " +
|
||||
strconv.Itoa(int(config.SchedPolicy)) +
|
||||
" out of range"}
|
||||
@@ -168,34 +176,51 @@ func (config *Config) Validate() error {
|
||||
}
|
||||
|
||||
if config.Container == nil {
|
||||
return &AppError{Step: "validate configuration", Err: ErrConfigNull,
|
||||
return &AppError{Step: step, Err: ErrConfigNull,
|
||||
Msg: "configuration missing container state"}
|
||||
}
|
||||
if config.Container.Home == nil {
|
||||
return &AppError{Step: "validate configuration", Err: ErrConfigNull,
|
||||
return &AppError{Step: step, Err: ErrConfigNull,
|
||||
Msg: "container configuration missing path to home directory"}
|
||||
}
|
||||
if config.Container.Shell == nil {
|
||||
return &AppError{Step: "validate configuration", Err: ErrConfigNull,
|
||||
return &AppError{Step: step, Err: ErrConfigNull,
|
||||
Msg: "container configuration missing path to shell"}
|
||||
}
|
||||
if config.Container.Path == nil {
|
||||
return &AppError{Step: "validate configuration", Err: ErrConfigNull,
|
||||
return &AppError{Step: step, Err: ErrConfigNull,
|
||||
Msg: "container configuration missing path to initial program"}
|
||||
}
|
||||
|
||||
for key := range config.Container.Env {
|
||||
if strings.IndexByte(key, '=') != -1 || strings.IndexByte(key, 0) != -1 {
|
||||
return &AppError{Step: "validate configuration", Err: ErrEnviron,
|
||||
return &AppError{Step: step, Err: ErrEnviron,
|
||||
Msg: "invalid environment variable " + strconv.Quote(key)}
|
||||
}
|
||||
}
|
||||
|
||||
if et := config.Enablements.Unwrap(); !config.DirectPulse && et&EPulse != 0 {
|
||||
return &AppError{Step: "validate configuration", Err: ErrInsecure,
|
||||
et := config.Enablements.Unwrap()
|
||||
if !config.DirectPulse && et&EPulse != 0 {
|
||||
return &AppError{Step: step, Err: ErrInsecure,
|
||||
Msg: "enablement PulseAudio is insecure and no longer supported"}
|
||||
}
|
||||
|
||||
if flags&VAllowInsecure == 0 {
|
||||
switch {
|
||||
case et&EWayland != 0 && config.DirectWayland:
|
||||
return &AppError{Step: step, Err: ErrInsecure,
|
||||
Msg: "direct_wayland is insecure and no longer supported"}
|
||||
|
||||
case et&EPipeWire != 0 && config.DirectPipeWire:
|
||||
return &AppError{Step: step, Err: ErrInsecure,
|
||||
Msg: "direct_pipewire is insecure and no longer supported"}
|
||||
|
||||
case et&EPulse != 0 && config.DirectPulse:
|
||||
return &AppError{Step: step, Err: ErrInsecure,
|
||||
Msg: "direct_pulse is insecure and no longer supported"}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -14,65 +14,109 @@ func TestConfigValidate(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
config *hst.Config
|
||||
flags int
|
||||
wantErr error
|
||||
}{
|
||||
{"nil", nil, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
{"nil", nil, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
Msg: "invalid configuration"}},
|
||||
{"identity lower", &hst.Config{Identity: -1}, &hst.AppError{Step: "validate configuration", Err: hst.ErrIdentityBounds,
|
||||
|
||||
{"identity lower", &hst.Config{Identity: -1}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrIdentityBounds,
|
||||
Msg: "identity -1 out of range"}},
|
||||
{"identity upper", &hst.Config{Identity: 10000}, &hst.AppError{Step: "validate configuration", Err: hst.ErrIdentityBounds,
|
||||
{"identity upper", &hst.Config{Identity: 10000}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrIdentityBounds,
|
||||
Msg: "identity 10000 out of range"}},
|
||||
{"sched lower", &hst.Config{SchedPolicy: -1}, &hst.AppError{Step: "validate configuration", Err: hst.ErrSchedPolicyBounds,
|
||||
|
||||
{"sched lower", &hst.Config{SchedPolicy: -1}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrSchedPolicyBounds,
|
||||
Msg: "scheduling policy -1 out of range"}},
|
||||
{"sched upper", &hst.Config{SchedPolicy: 0xcafe}, &hst.AppError{Step: "validate configuration", Err: hst.ErrSchedPolicyBounds,
|
||||
{"sched upper", &hst.Config{SchedPolicy: 0xcafe}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrSchedPolicyBounds,
|
||||
Msg: "scheduling policy 51966 out of range"}},
|
||||
{"dbus session", &hst.Config{SessionBus: &hst.BusConfig{See: []string{""}}},
|
||||
|
||||
{"dbus session", &hst.Config{SessionBus: &hst.BusConfig{See: []string{""}}}, 0,
|
||||
&hst.BadInterfaceError{Interface: "", Segment: "session"}},
|
||||
{"dbus system", &hst.Config{SystemBus: &hst.BusConfig{See: []string{""}}},
|
||||
{"dbus system", &hst.Config{SystemBus: &hst.BusConfig{See: []string{""}}}, 0,
|
||||
&hst.BadInterfaceError{Interface: "", Segment: "system"}},
|
||||
{"container", &hst.Config{}, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
|
||||
{"container", &hst.Config{}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
Msg: "configuration missing container state"}},
|
||||
{"home", &hst.Config{Container: &hst.ContainerConfig{}}, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
{"home", &hst.Config{Container: &hst.ContainerConfig{}}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
Msg: "container configuration missing path to home directory"}},
|
||||
{"shell", &hst.Config{Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
}}, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
}}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
Msg: "container configuration missing path to shell"}},
|
||||
{"path", &hst.Config{Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
}}, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
}}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||
Msg: "container configuration missing path to initial program"}},
|
||||
|
||||
{"env equals", &hst.Config{Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
Env: map[string]string{"TERM=": ""},
|
||||
}}, &hst.AppError{Step: "validate configuration", Err: hst.ErrEnviron,
|
||||
}}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrEnviron,
|
||||
Msg: `invalid environment variable "TERM="`}},
|
||||
{"env NUL", &hst.Config{Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
Env: map[string]string{"TERM\x00": ""},
|
||||
}}, &hst.AppError{Step: "validate configuration", Err: hst.ErrEnviron,
|
||||
}}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrEnviron,
|
||||
Msg: `invalid environment variable "TERM\x00"`}},
|
||||
{"insecure pulse", &hst.Config{Enablements: hst.NewEnablements(hst.EPulse), Container: &hst.ContainerConfig{
|
||||
|
||||
{"insecure pulse", &hst.Config{Enablements: new(hst.EPulse), Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
}}, &hst.AppError{Step: "validate configuration", Err: hst.ErrInsecure,
|
||||
}}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrInsecure,
|
||||
Msg: "enablement PulseAudio is insecure and no longer supported"}},
|
||||
|
||||
{"direct wayland", &hst.Config{Enablements: new(hst.EWayland), DirectWayland: true, Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
}}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrInsecure,
|
||||
Msg: "direct_wayland is insecure and no longer supported"}},
|
||||
{"direct wayland allow", &hst.Config{Enablements: new(hst.EWayland), DirectWayland: true, Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
}}, hst.VAllowInsecure, nil},
|
||||
|
||||
{"direct pipewire", &hst.Config{Enablements: new(hst.EPipeWire), DirectPipeWire: true, Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
}}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrInsecure,
|
||||
Msg: "direct_pipewire is insecure and no longer supported"}},
|
||||
{"direct pipewire allow", &hst.Config{Enablements: new(hst.EPipeWire), DirectPipeWire: true, Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
}}, hst.VAllowInsecure, nil},
|
||||
|
||||
{"direct pulse", &hst.Config{Enablements: new(hst.EPulse), DirectPulse: true, Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
}}, 0, &hst.AppError{Step: "validate configuration", Err: hst.ErrInsecure,
|
||||
Msg: "direct_pulse is insecure and no longer supported"}},
|
||||
{"direct pulse allow", &hst.Config{Enablements: new(hst.EPulse), DirectPulse: true, Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
}}, hst.VAllowInsecure, nil},
|
||||
|
||||
{"valid", &hst.Config{Container: &hst.ContainerConfig{
|
||||
Home: fhs.AbsTmp,
|
||||
Shell: fhs.AbsTmp,
|
||||
Path: fhs.AbsTmp,
|
||||
}}, nil},
|
||||
}}, 0, nil},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := tc.config.Validate(); !reflect.DeepEqual(err, tc.wantErr) {
|
||||
if err := tc.config.Validate(tc.flags); !reflect.DeepEqual(err, tc.wantErr) {
|
||||
t.Errorf("Validate: error = %#v, want %#v", err, tc.wantErr)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Enablement represents an optional host service to export to the target user.
|
||||
type Enablement byte
|
||||
// Enablements denotes optional host service to export to the target user.
|
||||
type Enablements byte
|
||||
|
||||
const (
|
||||
// EWayland exposes a Wayland pathname socket via security-context-v1.
|
||||
EWayland Enablement = 1 << iota
|
||||
EWayland Enablements = 1 << iota
|
||||
// EX11 adds the target user via X11 ChangeHosts and exposes the X11
|
||||
// pathname socket.
|
||||
EX11
|
||||
@@ -28,8 +28,8 @@ const (
|
||||
EM
|
||||
)
|
||||
|
||||
// String returns a string representation of the flags set on [Enablement].
|
||||
func (e Enablement) String() string {
|
||||
// String returns a string representation of the flags set on [Enablements].
|
||||
func (e Enablements) String() string {
|
||||
switch e {
|
||||
case 0:
|
||||
return "(no enablements)"
|
||||
@@ -47,7 +47,7 @@ func (e Enablement) String() string {
|
||||
buf := new(strings.Builder)
|
||||
buf.Grow(32)
|
||||
|
||||
for i := Enablement(1); i < EM; i <<= 1 {
|
||||
for i := Enablements(1); i < EM; i <<= 1 {
|
||||
if e&i != 0 {
|
||||
buf.WriteString(", " + i.String())
|
||||
}
|
||||
@@ -60,12 +60,6 @@ func (e Enablement) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// NewEnablements returns the address of [Enablement] as [Enablements].
|
||||
func NewEnablements(e Enablement) *Enablements { return (*Enablements)(&e) }
|
||||
|
||||
// Enablements is the [json] adapter for [Enablement].
|
||||
type Enablements Enablement
|
||||
|
||||
// enablementsJSON is the [json] representation of [Enablements].
|
||||
type enablementsJSON = struct {
|
||||
Wayland bool `json:"wayland,omitempty"`
|
||||
@@ -75,24 +69,21 @@ type enablementsJSON = struct {
|
||||
Pulse bool `json:"pulse,omitempty"`
|
||||
}
|
||||
|
||||
// Unwrap returns the underlying [Enablement].
|
||||
func (e *Enablements) Unwrap() Enablement {
|
||||
// Unwrap returns the value pointed to by e.
|
||||
func (e *Enablements) Unwrap() Enablements {
|
||||
if e == nil {
|
||||
return 0
|
||||
}
|
||||
return Enablement(*e)
|
||||
return *e
|
||||
}
|
||||
|
||||
func (e *Enablements) MarshalJSON() ([]byte, error) {
|
||||
if e == nil {
|
||||
return nil, syscall.EINVAL
|
||||
}
|
||||
func (e Enablements) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(&enablementsJSON{
|
||||
Wayland: Enablement(*e)&EWayland != 0,
|
||||
X11: Enablement(*e)&EX11 != 0,
|
||||
DBus: Enablement(*e)&EDBus != 0,
|
||||
PipeWire: Enablement(*e)&EPipeWire != 0,
|
||||
Pulse: Enablement(*e)&EPulse != 0,
|
||||
Wayland: e&EWayland != 0,
|
||||
X11: e&EX11 != 0,
|
||||
DBus: e&EDBus != 0,
|
||||
PipeWire: e&EPipeWire != 0,
|
||||
Pulse: e&EPulse != 0,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -106,22 +97,21 @@ func (e *Enablements) UnmarshalJSON(data []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var ve Enablement
|
||||
*e = 0
|
||||
if v.Wayland {
|
||||
ve |= EWayland
|
||||
*e |= EWayland
|
||||
}
|
||||
if v.X11 {
|
||||
ve |= EX11
|
||||
*e |= EX11
|
||||
}
|
||||
if v.DBus {
|
||||
ve |= EDBus
|
||||
*e |= EDBus
|
||||
}
|
||||
if v.PipeWire {
|
||||
ve |= EPipeWire
|
||||
*e |= EPipeWire
|
||||
}
|
||||
if v.Pulse {
|
||||
ve |= EPulse
|
||||
*e |= EPulse
|
||||
}
|
||||
*e = Enablements(ve)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ func TestEnablementString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
flags hst.Enablement
|
||||
flags hst.Enablements
|
||||
want string
|
||||
}{
|
||||
{0, "(no enablements)"},
|
||||
@@ -59,13 +59,13 @@ func TestEnablements(t *testing.T) {
|
||||
sData string
|
||||
}{
|
||||
{"nil", nil, "null", `{"value":null,"magic":3236757504}`},
|
||||
{"zero", hst.NewEnablements(0), `{}`, `{"value":{},"magic":3236757504}`},
|
||||
{"wayland", hst.NewEnablements(hst.EWayland), `{"wayland":true}`, `{"value":{"wayland":true},"magic":3236757504}`},
|
||||
{"x11", hst.NewEnablements(hst.EX11), `{"x11":true}`, `{"value":{"x11":true},"magic":3236757504}`},
|
||||
{"dbus", hst.NewEnablements(hst.EDBus), `{"dbus":true}`, `{"value":{"dbus":true},"magic":3236757504}`},
|
||||
{"pipewire", hst.NewEnablements(hst.EPipeWire), `{"pipewire":true}`, `{"value":{"pipewire":true},"magic":3236757504}`},
|
||||
{"pulse", hst.NewEnablements(hst.EPulse), `{"pulse":true}`, `{"value":{"pulse":true},"magic":3236757504}`},
|
||||
{"all", hst.NewEnablements(hst.EM - 1), `{"wayland":true,"x11":true,"dbus":true,"pipewire":true,"pulse":true}`, `{"value":{"wayland":true,"x11":true,"dbus":true,"pipewire":true,"pulse":true},"magic":3236757504}`},
|
||||
{"zero", new(hst.Enablements(0)), `{}`, `{"value":{},"magic":3236757504}`},
|
||||
{"wayland", new(hst.EWayland), `{"wayland":true}`, `{"value":{"wayland":true},"magic":3236757504}`},
|
||||
{"x11", new(hst.EX11), `{"x11":true}`, `{"value":{"x11":true},"magic":3236757504}`},
|
||||
{"dbus", new(hst.EDBus), `{"dbus":true}`, `{"value":{"dbus":true},"magic":3236757504}`},
|
||||
{"pipewire", new(hst.EPipeWire), `{"pipewire":true}`, `{"value":{"pipewire":true},"magic":3236757504}`},
|
||||
{"pulse", new(hst.EPulse), `{"pulse":true}`, `{"value":{"pulse":true},"magic":3236757504}`},
|
||||
{"all", new(hst.EM - 1), `{"wayland":true,"x11":true,"dbus":true,"pipewire":true,"pulse":true}`, `{"value":{"wayland":true,"x11":true,"dbus":true,"pipewire":true,"pulse":true},"magic":3236757504}`},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -137,7 +137,7 @@ func TestEnablements(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("val", func(t *testing.T) {
|
||||
if got := hst.NewEnablements(hst.EWayland | hst.EPulse).Unwrap(); got != hst.EWayland|hst.EPulse {
|
||||
if got := new(hst.EWayland | hst.EPulse).Unwrap(); got != hst.EWayland|hst.EPulse {
|
||||
t.Errorf("Unwrap: %v", got)
|
||||
}
|
||||
})
|
||||
@@ -146,9 +146,6 @@ func TestEnablements(t *testing.T) {
|
||||
t.Run("passthrough", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if _, err := (*hst.Enablements)(nil).MarshalJSON(); !errors.Is(err, syscall.EINVAL) {
|
||||
t.Errorf("MarshalJSON: error = %v", err)
|
||||
}
|
||||
if err := (*hst.Enablements)(nil).UnmarshalJSON(nil); !errors.Is(err, syscall.EINVAL) {
|
||||
t.Errorf("UnmarshalJSON: error = %v", err)
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ func Template() *Config {
|
||||
return &Config{
|
||||
ID: "org.chromium.Chromium",
|
||||
|
||||
Enablements: NewEnablements(EWayland | EDBus | EPipeWire),
|
||||
Enablements: new(EWayland | EDBus | EPipeWire),
|
||||
|
||||
SessionBus: &BusConfig{
|
||||
See: nil,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package container
|
||||
package landlock
|
||||
|
||||
import (
|
||||
"strings"
|
||||
@@ -14,11 +14,11 @@ const (
|
||||
LANDLOCK_CREATE_RULESET_VERSION = 1 << iota
|
||||
)
|
||||
|
||||
// LandlockAccessFS is bitmask of handled filesystem actions.
|
||||
type LandlockAccessFS uint64
|
||||
// AccessFS is bitmask of handled filesystem actions.
|
||||
type AccessFS uint64
|
||||
|
||||
const (
|
||||
LANDLOCK_ACCESS_FS_EXECUTE LandlockAccessFS = 1 << iota
|
||||
LANDLOCK_ACCESS_FS_EXECUTE AccessFS = 1 << iota
|
||||
LANDLOCK_ACCESS_FS_WRITE_FILE
|
||||
LANDLOCK_ACCESS_FS_READ_FILE
|
||||
LANDLOCK_ACCESS_FS_READ_DIR
|
||||
@@ -38,8 +38,8 @@ const (
|
||||
_LANDLOCK_ACCESS_FS_DELIM
|
||||
)
|
||||
|
||||
// String returns a space-separated string of [LandlockAccessFS] flags.
|
||||
func (f LandlockAccessFS) String() string {
|
||||
// String returns a space-separated string of [AccessFS] flags.
|
||||
func (f AccessFS) String() string {
|
||||
switch f {
|
||||
case LANDLOCK_ACCESS_FS_EXECUTE:
|
||||
return "execute"
|
||||
@@ -90,8 +90,8 @@ func (f LandlockAccessFS) String() string {
|
||||
return "fs_ioctl_dev"
|
||||
|
||||
default:
|
||||
var c []LandlockAccessFS
|
||||
for i := LandlockAccessFS(1); i < _LANDLOCK_ACCESS_FS_DELIM; i <<= 1 {
|
||||
var c []AccessFS
|
||||
for i := AccessFS(1); i < _LANDLOCK_ACCESS_FS_DELIM; i <<= 1 {
|
||||
if f&i != 0 {
|
||||
c = append(c, i)
|
||||
}
|
||||
@@ -107,18 +107,18 @@ func (f LandlockAccessFS) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// LandlockAccessNet is bitmask of handled network actions.
|
||||
type LandlockAccessNet uint64
|
||||
// AccessNet is bitmask of handled network actions.
|
||||
type AccessNet uint64
|
||||
|
||||
const (
|
||||
LANDLOCK_ACCESS_NET_BIND_TCP LandlockAccessNet = 1 << iota
|
||||
LANDLOCK_ACCESS_NET_BIND_TCP AccessNet = 1 << iota
|
||||
LANDLOCK_ACCESS_NET_CONNECT_TCP
|
||||
|
||||
_LANDLOCK_ACCESS_NET_DELIM
|
||||
)
|
||||
|
||||
// String returns a space-separated string of [LandlockAccessNet] flags.
|
||||
func (f LandlockAccessNet) String() string {
|
||||
// String returns a space-separated string of [AccessNet] flags.
|
||||
func (f AccessNet) String() string {
|
||||
switch f {
|
||||
case LANDLOCK_ACCESS_NET_BIND_TCP:
|
||||
return "bind_tcp"
|
||||
@@ -127,8 +127,8 @@ func (f LandlockAccessNet) String() string {
|
||||
return "connect_tcp"
|
||||
|
||||
default:
|
||||
var c []LandlockAccessNet
|
||||
for i := LandlockAccessNet(1); i < _LANDLOCK_ACCESS_NET_DELIM; i <<= 1 {
|
||||
var c []AccessNet
|
||||
for i := AccessNet(1); i < _LANDLOCK_ACCESS_NET_DELIM; i <<= 1 {
|
||||
if f&i != 0 {
|
||||
c = append(c, i)
|
||||
}
|
||||
@@ -144,18 +144,18 @@ func (f LandlockAccessNet) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// LandlockScope is bitmask of scopes restricting a Landlock domain from accessing outside resources.
|
||||
type LandlockScope uint64
|
||||
// Scope is bitmask of scopes restricting a Landlock domain from accessing outside resources.
|
||||
type Scope uint64
|
||||
|
||||
const (
|
||||
LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET LandlockScope = 1 << iota
|
||||
LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET Scope = 1 << iota
|
||||
LANDLOCK_SCOPE_SIGNAL
|
||||
|
||||
_LANDLOCK_SCOPE_DELIM
|
||||
)
|
||||
|
||||
// String returns a space-separated string of [LandlockScope] flags.
|
||||
func (f LandlockScope) String() string {
|
||||
// String returns a space-separated string of [Scope] flags.
|
||||
func (f Scope) String() string {
|
||||
switch f {
|
||||
case LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET:
|
||||
return "abstract_unix_socket"
|
||||
@@ -164,8 +164,8 @@ func (f LandlockScope) String() string {
|
||||
return "signal"
|
||||
|
||||
default:
|
||||
var c []LandlockScope
|
||||
for i := LandlockScope(1); i < _LANDLOCK_SCOPE_DELIM; i <<= 1 {
|
||||
var c []Scope
|
||||
for i := Scope(1); i < _LANDLOCK_SCOPE_DELIM; i <<= 1 {
|
||||
if f&i != 0 {
|
||||
c = append(c, i)
|
||||
}
|
||||
@@ -184,12 +184,12 @@ func (f LandlockScope) String() string {
|
||||
// RulesetAttr is equivalent to struct landlock_ruleset_attr.
|
||||
type RulesetAttr struct {
|
||||
// Bitmask of handled filesystem actions.
|
||||
HandledAccessFS LandlockAccessFS
|
||||
HandledAccessFS AccessFS
|
||||
// Bitmask of handled network actions.
|
||||
HandledAccessNet LandlockAccessNet
|
||||
HandledAccessNet AccessNet
|
||||
// Bitmask of scopes restricting a Landlock domain from accessing outside
|
||||
// resources (e.g. IPCs).
|
||||
Scoped LandlockScope
|
||||
Scoped Scope
|
||||
}
|
||||
|
||||
// String returns a user-facing description of [RulesetAttr].
|
||||
@@ -239,13 +239,13 @@ func (rulesetAttr *RulesetAttr) Create(flags uintptr) (fd int, err error) {
|
||||
return fd, nil
|
||||
}
|
||||
|
||||
// LandlockGetABI returns the ABI version supported by the kernel.
|
||||
func LandlockGetABI() (int, error) {
|
||||
// GetABI returns the ABI version supported by the kernel.
|
||||
func GetABI() (int, error) {
|
||||
return (*RulesetAttr)(nil).Create(LANDLOCK_CREATE_RULESET_VERSION)
|
||||
}
|
||||
|
||||
// LandlockRestrictSelf applies a loaded ruleset to the calling thread.
|
||||
func LandlockRestrictSelf(rulesetFd int, flags uintptr) error {
|
||||
// RestrictSelf applies a loaded ruleset to the calling thread.
|
||||
func RestrictSelf(rulesetFd int, flags uintptr) error {
|
||||
r, _, errno := syscall.Syscall(
|
||||
ext.SYS_LANDLOCK_RESTRICT_SELF,
|
||||
uintptr(rulesetFd),
|
||||
65
internal/landlock/landlock_test.go
Normal file
65
internal/landlock/landlock_test.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package landlock_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
"hakurei.app/internal/landlock"
|
||||
)
|
||||
|
||||
func TestLandlockString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
rulesetAttr *landlock.RulesetAttr
|
||||
want string
|
||||
}{
|
||||
{"nil", nil, "NULL"},
|
||||
{"zero", new(landlock.RulesetAttr), "0"},
|
||||
{"some", &landlock.RulesetAttr{Scoped: landlock.LANDLOCK_SCOPE_SIGNAL}, "scoped: signal"},
|
||||
{"set", &landlock.RulesetAttr{
|
||||
HandledAccessFS: landlock.LANDLOCK_ACCESS_FS_MAKE_SYM | landlock.LANDLOCK_ACCESS_FS_IOCTL_DEV | landlock.LANDLOCK_ACCESS_FS_WRITE_FILE,
|
||||
HandledAccessNet: landlock.LANDLOCK_ACCESS_NET_BIND_TCP,
|
||||
Scoped: landlock.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | landlock.LANDLOCK_SCOPE_SIGNAL,
|
||||
}, "fs: write_file make_sym fs_ioctl_dev, net: bind_tcp, scoped: abstract_unix_socket signal"},
|
||||
{"all", &landlock.RulesetAttr{
|
||||
HandledAccessFS: landlock.LANDLOCK_ACCESS_FS_EXECUTE |
|
||||
landlock.LANDLOCK_ACCESS_FS_WRITE_FILE |
|
||||
landlock.LANDLOCK_ACCESS_FS_READ_FILE |
|
||||
landlock.LANDLOCK_ACCESS_FS_READ_DIR |
|
||||
landlock.LANDLOCK_ACCESS_FS_REMOVE_DIR |
|
||||
landlock.LANDLOCK_ACCESS_FS_REMOVE_FILE |
|
||||
landlock.LANDLOCK_ACCESS_FS_MAKE_CHAR |
|
||||
landlock.LANDLOCK_ACCESS_FS_MAKE_DIR |
|
||||
landlock.LANDLOCK_ACCESS_FS_MAKE_REG |
|
||||
landlock.LANDLOCK_ACCESS_FS_MAKE_SOCK |
|
||||
landlock.LANDLOCK_ACCESS_FS_MAKE_FIFO |
|
||||
landlock.LANDLOCK_ACCESS_FS_MAKE_BLOCK |
|
||||
landlock.LANDLOCK_ACCESS_FS_MAKE_SYM |
|
||||
landlock.LANDLOCK_ACCESS_FS_REFER |
|
||||
landlock.LANDLOCK_ACCESS_FS_TRUNCATE |
|
||||
landlock.LANDLOCK_ACCESS_FS_IOCTL_DEV,
|
||||
HandledAccessNet: landlock.LANDLOCK_ACCESS_NET_BIND_TCP |
|
||||
landlock.LANDLOCK_ACCESS_NET_CONNECT_TCP,
|
||||
Scoped: landlock.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
|
||||
landlock.LANDLOCK_SCOPE_SIGNAL,
|
||||
}, "fs: execute write_file read_file read_dir remove_dir remove_file make_char make_dir make_reg make_sock make_fifo make_block make_sym fs_refer fs_truncate fs_ioctl_dev, net: bind_tcp connect_tcp, scoped: abstract_unix_socket signal"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := tc.rulesetAttr.String(); got != tc.want {
|
||||
t.Errorf("String: %s, want %s", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLandlockAttrSize(t *testing.T) {
|
||||
t.Parallel()
|
||||
want := 24
|
||||
if got := unsafe.Sizeof(landlock.RulesetAttr{}); got != uintptr(want) {
|
||||
t.Errorf("Sizeof: %d, want %d", got, want)
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,14 @@ type outcome struct {
|
||||
syscallDispatcher
|
||||
}
|
||||
|
||||
func (k *outcome) finalise(ctx context.Context, msg message.Msg, id *hst.ID, config *hst.Config) error {
|
||||
// finalise prepares an outcome for main.
|
||||
func (k *outcome) finalise(
|
||||
ctx context.Context,
|
||||
msg message.Msg,
|
||||
id *hst.ID,
|
||||
config *hst.Config,
|
||||
flags int,
|
||||
) error {
|
||||
if ctx == nil || id == nil {
|
||||
// unreachable
|
||||
panic("invalid call to finalise")
|
||||
@@ -43,7 +50,7 @@ func (k *outcome) finalise(ctx context.Context, msg message.Msg, id *hst.ID, con
|
||||
}
|
||||
k.ctx = ctx
|
||||
|
||||
if err := config.Validate(); err != nil {
|
||||
if err := config.Validate(flags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ type outcomeStateSys struct {
|
||||
// Copied from [hst.Config]. Safe for read by outcomeOp.toSystem.
|
||||
appId string
|
||||
// Copied from [hst.Config]. Safe for read by outcomeOp.toSystem.
|
||||
et hst.Enablement
|
||||
et hst.Enablements
|
||||
|
||||
// Copied from [hst.Config]. Safe for read by spWaylandOp.toSystem only.
|
||||
directWayland bool
|
||||
|
||||
@@ -297,12 +297,12 @@ func (k *outcome) main(msg message.Msg, identifierFd int) {
|
||||
// accumulate enablements of remaining instances
|
||||
var (
|
||||
// alive enablement bits
|
||||
rt hst.Enablement
|
||||
rt hst.Enablements
|
||||
// alive instance count
|
||||
n int
|
||||
)
|
||||
for eh := range entries {
|
||||
var et hst.Enablement
|
||||
var et hst.Enablements
|
||||
if et, err = eh.Load(nil); err != nil {
|
||||
perror(err, "read state header of instance "+eh.ID.String())
|
||||
} else {
|
||||
|
||||
@@ -18,7 +18,13 @@ import (
|
||||
func IsPollDescriptor(fd uintptr) bool
|
||||
|
||||
// Main runs an app according to [hst.Config] and terminates. Main does not return.
|
||||
func Main(ctx context.Context, msg message.Msg, config *hst.Config, fd int) {
|
||||
func Main(
|
||||
ctx context.Context,
|
||||
msg message.Msg,
|
||||
config *hst.Config,
|
||||
flags int,
|
||||
fd int,
|
||||
) {
|
||||
// avoids runtime internals or standard streams
|
||||
if fd >= 0 {
|
||||
if IsPollDescriptor(uintptr(fd)) || fd < 3 {
|
||||
@@ -34,7 +40,7 @@ func Main(ctx context.Context, msg message.Msg, config *hst.Config, fd int) {
|
||||
k := outcome{syscallDispatcher: direct{msg}}
|
||||
|
||||
finaliseTime := time.Now()
|
||||
if err := k.finalise(ctx, msg, &id, config); err != nil {
|
||||
if err := k.finalise(ctx, msg, &id, config, flags); err != nil {
|
||||
printMessageError(msg.GetLogger().Fatalln, "cannot seal app:", err)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ func TestOutcomeRun(t *testing.T) {
|
||||
},
|
||||
Filter: true,
|
||||
},
|
||||
Enablements: hst.NewEnablements(hst.EWayland | hst.EDBus | hst.EPipeWire | hst.EPulse),
|
||||
Enablements: new(hst.EWayland | hst.EDBus | hst.EPipeWire | hst.EPulse),
|
||||
|
||||
Container: &hst.ContainerConfig{
|
||||
Filesystem: []hst.FilesystemConfigJSON{
|
||||
@@ -427,7 +427,7 @@ func TestOutcomeRun(t *testing.T) {
|
||||
DirectPipeWire: true,
|
||||
|
||||
ID: "org.chromium.Chromium",
|
||||
Enablements: hst.NewEnablements(hst.EWayland | hst.EDBus | hst.EPipeWire | hst.EPulse),
|
||||
Enablements: new(hst.EWayland | hst.EDBus | hst.EPipeWire | hst.EPulse),
|
||||
Container: &hst.ContainerConfig{
|
||||
Env: nil,
|
||||
Filesystem: []hst.FilesystemConfigJSON{
|
||||
|
||||
@@ -21,7 +21,7 @@ func TestSpPulseOp(t *testing.T) {
|
||||
newConfig := func() *hst.Config {
|
||||
config := hst.Template()
|
||||
config.DirectPulse = true
|
||||
config.Enablements = hst.NewEnablements(hst.EPulse)
|
||||
config.Enablements = new(hst.EPulse)
|
||||
return config
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,11 @@ import (
|
||||
// AbsWork is the container pathname [TContext.GetWorkDir] is mounted on.
|
||||
var AbsWork = fhs.AbsRoot.Append("work/")
|
||||
|
||||
// EnvJobs is the name of the environment variable holding a decimal
|
||||
// representation of the preferred job count. Its value must not affect cure
|
||||
// outcome.
|
||||
const EnvJobs = "CURE_JOBS"
|
||||
|
||||
// ExecPath is a slice of [Artifact] and the [check.Absolute] pathname to make
|
||||
// it available at under in the container.
|
||||
type ExecPath struct {
|
||||
@@ -397,7 +402,7 @@ const SeccompPresets = std.PresetStrict &
|
||||
func (a *execArtifact) makeContainer(
|
||||
ctx context.Context,
|
||||
msg message.Msg,
|
||||
flags int,
|
||||
flags, jobs int,
|
||||
hostNet bool,
|
||||
temp, work *check.Absolute,
|
||||
getArtifact GetArtifactFunc,
|
||||
@@ -432,8 +437,8 @@ func (a *execArtifact) makeContainer(
|
||||
z.Hostname = "cure-net"
|
||||
}
|
||||
z.Uid, z.Gid = (1<<10)-1, (1<<10)-1
|
||||
|
||||
z.Dir, z.Env, z.Path, z.Args = a.dir, a.env, a.path, a.args
|
||||
z.Dir, z.Path, z.Args = a.dir, a.path, a.args
|
||||
z.Env = slices.Concat(a.env, []string{EnvJobs + "=" + strconv.Itoa(jobs)})
|
||||
z.Grow(len(a.paths) + 4)
|
||||
|
||||
for i, b := range a.paths {
|
||||
@@ -563,6 +568,7 @@ func (c *Cache) EnterExec(
|
||||
z, err = e.makeContainer(
|
||||
ctx, c.msg,
|
||||
c.flags,
|
||||
c.jobs,
|
||||
hostNet,
|
||||
temp, work,
|
||||
func(a Artifact) (*check.Absolute, unique.Handle[Checksum]) {
|
||||
@@ -602,7 +608,7 @@ func (a *execArtifact) cure(f *FContext, hostNet bool) (err error) {
|
||||
msg := f.GetMessage()
|
||||
var z *container.Container
|
||||
if z, err = a.makeContainer(
|
||||
ctx, msg, f.cache.flags, hostNet,
|
||||
ctx, msg, f.cache.flags, f.GetJobs(), hostNet,
|
||||
f.GetTempDir(), f.GetWorkDir(),
|
||||
f.GetArtifact,
|
||||
f.cache.Ident,
|
||||
|
||||
@@ -188,6 +188,10 @@ func (c *common) Unwrap() context.Context { return c.cache.ctx }
|
||||
// GetMessage returns [message.Msg] held by the underlying [Cache].
|
||||
func (c *common) GetMessage() message.Msg { return c.cache.msg }
|
||||
|
||||
// GetJobs returns the preferred number of jobs to run, when applicable. Its
|
||||
// value must not affect cure outcome.
|
||||
func (c *common) GetJobs() int { return c.cache.jobs }
|
||||
|
||||
// GetWorkDir returns a pathname to a directory which [Artifact] is expected to
|
||||
// write its output to. This is not the final resting place of the [Artifact]
|
||||
// and this pathname should not be directly referred to in the final contents.
|
||||
@@ -552,6 +556,8 @@ type Cache struct {
|
||||
base *check.Absolute
|
||||
// Immutable cure options set by [Open].
|
||||
flags int
|
||||
// Immutable job count, when applicable.
|
||||
jobs int
|
||||
|
||||
// Artifact to [unique.Handle] of identifier cache.
|
||||
artifact sync.Map
|
||||
@@ -1818,7 +1824,7 @@ func (c *Cache) Close() {
|
||||
// caller-supplied value, however direct calls to [Cache.Cure] is not subject
|
||||
// to this limitation.
|
||||
//
|
||||
// A cures value of 0 or lower is equivalent to the value returned by
|
||||
// A cures or jobs value of 0 or lower is equivalent to the value returned by
|
||||
// [runtime.NumCPU].
|
||||
//
|
||||
// A successful call to Open guarantees exclusive access to the on-filesystem
|
||||
@@ -1828,10 +1834,10 @@ func (c *Cache) Close() {
|
||||
func Open(
|
||||
ctx context.Context,
|
||||
msg message.Msg,
|
||||
flags, cures int,
|
||||
flags, cures, jobs int,
|
||||
base *check.Absolute,
|
||||
) (*Cache, error) {
|
||||
return open(ctx, msg, flags, cures, base, true)
|
||||
return open(ctx, msg, flags, cures, jobs, base, true)
|
||||
}
|
||||
|
||||
// open implements Open but allows omitting the [lockedfile] lock when called
|
||||
@@ -1839,13 +1845,16 @@ func Open(
|
||||
func open(
|
||||
ctx context.Context,
|
||||
msg message.Msg,
|
||||
flags, cures int,
|
||||
flags, cures, jobs int,
|
||||
base *check.Absolute,
|
||||
lock bool,
|
||||
) (*Cache, error) {
|
||||
if cures < 1 {
|
||||
cures = runtime.NumCPU()
|
||||
}
|
||||
if jobs < 1 {
|
||||
jobs = runtime.NumCPU()
|
||||
}
|
||||
|
||||
for _, name := range []string{
|
||||
dirIdentifier,
|
||||
@@ -1862,6 +1871,7 @@ func open(
|
||||
c := Cache{
|
||||
cures: make(chan struct{}, cures),
|
||||
flags: flags,
|
||||
jobs: jobs,
|
||||
|
||||
msg: msg,
|
||||
base: base,
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/fhs"
|
||||
"hakurei.app/internal/info"
|
||||
"hakurei.app/internal/landlock"
|
||||
"hakurei.app/internal/pkg"
|
||||
"hakurei.app/internal/stub"
|
||||
"hakurei.app/message"
|
||||
@@ -34,7 +35,7 @@ import (
|
||||
func unsafeOpen(
|
||||
ctx context.Context,
|
||||
msg message.Msg,
|
||||
flags, cures int,
|
||||
flags, cures, jobs int,
|
||||
base *check.Absolute,
|
||||
lock bool,
|
||||
) (*pkg.Cache, error)
|
||||
@@ -229,7 +230,7 @@ func TestIdent(t *testing.T) {
|
||||
var cache *pkg.Cache
|
||||
if a, err := check.NewAbs(t.TempDir()); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if cache, err = pkg.Open(t.Context(), msg, 0, 0, a); err != nil {
|
||||
} else if cache, err = pkg.Open(t.Context(), msg, 0, 0, 0, a); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(cache.Close)
|
||||
@@ -293,7 +294,7 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
|
||||
flags := tc.flags
|
||||
|
||||
if info.CanDegrade {
|
||||
if _, err := container.LandlockGetABI(); err != nil {
|
||||
if _, err := landlock.GetABI(); err != nil {
|
||||
if !errors.Is(err, syscall.ENOSYS) {
|
||||
t.Fatalf("LandlockGetABI: error = %v", err)
|
||||
}
|
||||
@@ -303,7 +304,7 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
|
||||
}
|
||||
|
||||
var scrubFunc func() error // scrub after hashing
|
||||
if c, err := pkg.Open(t.Context(), msg, flags, 1<<4, base); err != nil {
|
||||
if c, err := pkg.Open(t.Context(), msg, flags, 1<<4, 0, base); err != nil {
|
||||
t.Fatalf("Open: error = %v", err)
|
||||
} else {
|
||||
t.Cleanup(c.Close)
|
||||
@@ -605,7 +606,7 @@ func TestCache(t *testing.T) {
|
||||
if c0, err := unsafeOpen(
|
||||
t.Context(),
|
||||
message.New(nil),
|
||||
0, 0, base, false,
|
||||
0, 0, 0, base, false,
|
||||
); err != nil {
|
||||
t.Fatalf("open: error = %v", err)
|
||||
} else {
|
||||
@@ -1262,7 +1263,7 @@ func TestNew(t *testing.T) {
|
||||
if _, err := pkg.Open(
|
||||
t.Context(),
|
||||
message.New(nil),
|
||||
0, 0, check.MustAbs(container.Nonexistent),
|
||||
0, 0, 0, check.MustAbs(container.Nonexistent),
|
||||
); !reflect.DeepEqual(err, wantErr) {
|
||||
t.Errorf("Open: error = %#v, want %#v", err, wantErr)
|
||||
}
|
||||
@@ -1290,7 +1291,7 @@ func TestNew(t *testing.T) {
|
||||
if _, err := pkg.Open(
|
||||
t.Context(),
|
||||
message.New(nil),
|
||||
0, 0, tempDir.Append("cache"),
|
||||
0, 0, 0, tempDir.Append("cache"),
|
||||
); !reflect.DeepEqual(err, wantErr) {
|
||||
t.Errorf("Open: error = %#v, want %#v", err, wantErr)
|
||||
}
|
||||
|
||||
@@ -43,8 +43,7 @@ var _ fmt.Stringer = new(tarArtifactNamed)
|
||||
func (a *tarArtifactNamed) String() string { return a.name + "-unpack" }
|
||||
|
||||
// NewTar returns a new [Artifact] backed by the supplied [Artifact] and
|
||||
// compression method. The source [Artifact] must be compatible with
|
||||
// [TContext.Open].
|
||||
// compression method. The source [Artifact] must be a [FileArtifact].
|
||||
func NewTar(a Artifact, compression uint32) Artifact {
|
||||
ta := tarArtifact{a, compression}
|
||||
if s, ok := a.(fmt.Stringer); ok {
|
||||
|
||||
12
internal/pkg/testdata/main.go
vendored
12
internal/pkg/testdata/main.go
vendored
@@ -9,7 +9,9 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"hakurei.app/check"
|
||||
@@ -21,6 +23,10 @@ func main() {
|
||||
log.SetFlags(0)
|
||||
log.SetPrefix("testtool: ")
|
||||
|
||||
environ := slices.DeleteFunc(slices.Clone(os.Environ()), func(s string) bool {
|
||||
return s == "CURE_JOBS="+strconv.Itoa(runtime.NumCPU())
|
||||
})
|
||||
|
||||
var hostNet, layers, promote bool
|
||||
if len(os.Args) == 2 && os.Args[0] == "testtool" {
|
||||
switch os.Args[1] {
|
||||
@@ -48,15 +54,15 @@ func main() {
|
||||
|
||||
var overlayRoot bool
|
||||
wantEnv := []string{"HAKUREI_TEST=1"}
|
||||
if len(os.Environ()) == 2 {
|
||||
if len(environ) == 2 {
|
||||
overlayRoot = true
|
||||
if !layers && !promote {
|
||||
log.SetPrefix("testtool(overlay root): ")
|
||||
}
|
||||
wantEnv = []string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"}
|
||||
}
|
||||
if !slices.Equal(wantEnv, os.Environ()) {
|
||||
log.Fatalf("Environ: %q, want %q", os.Environ(), wantEnv)
|
||||
if !slices.Equal(wantEnv, environ) {
|
||||
log.Fatalf("Environ: %q, want %q", environ, wantEnv)
|
||||
}
|
||||
|
||||
var overlayWork bool
|
||||
|
||||
@@ -7,10 +7,10 @@ func (t Toolchain) newAttr() (pkg.Artifact, string) {
|
||||
version = "2.5.2"
|
||||
checksum = "YWEphrz6vg1sUMmHHVr1CRo53pFXRhq_pjN-AlG8UgwZK1y6m7zuDhxqJhD0SV0l"
|
||||
)
|
||||
return t.NewPackage("attr", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://download.savannah.nongnu.org/releases/attr/"+
|
||||
return t.NewPackage("attr", version, newTar(
|
||||
"https://download.savannah.nongnu.org/releases/attr/"+
|
||||
"attr-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Patches: []KV{
|
||||
@@ -81,10 +81,10 @@ func (t Toolchain) newACL() (pkg.Artifact, string) {
|
||||
version = "2.3.2"
|
||||
checksum = "-fY5nwH4K8ZHBCRXrzLdguPkqjKI6WIiGu4dBtrZ1o0t6AIU73w8wwJz_UyjIS0P"
|
||||
)
|
||||
return t.NewPackage("acl", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://download.savannah.nongnu.org/releases/acl/"+
|
||||
return t.NewPackage("acl", version, newTar(
|
||||
"https://download.savannah.nongnu.org/releases/acl/"+
|
||||
"acl-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MakeHelper{
|
||||
// makes assumptions about uid_map/gid_map
|
||||
|
||||
@@ -16,9 +16,9 @@ import (
|
||||
type PArtifact int
|
||||
|
||||
const (
|
||||
LLVMCompilerRT PArtifact = iota
|
||||
CompilerRT PArtifact = iota
|
||||
LLVMRuntimes
|
||||
LLVMClang
|
||||
Clang
|
||||
|
||||
// EarlyInit is the Rosa OS init program.
|
||||
EarlyInit
|
||||
@@ -64,6 +64,7 @@ const (
|
||||
GenInitCPIO
|
||||
Gettext
|
||||
Git
|
||||
Glslang
|
||||
GnuTLS
|
||||
Go
|
||||
Gperf
|
||||
@@ -76,13 +77,17 @@ const (
|
||||
LibXau
|
||||
Libbsd
|
||||
Libcap
|
||||
Libclc
|
||||
Libdrm
|
||||
Libev
|
||||
Libexpat
|
||||
Libffi
|
||||
Libgd
|
||||
Libglvnd
|
||||
Libiconv
|
||||
Libmd
|
||||
Libmnl
|
||||
Libpciaccess
|
||||
Libnftnl
|
||||
Libpsl
|
||||
Libseccomp
|
||||
@@ -119,15 +124,18 @@ const (
|
||||
PerlTermReadKey
|
||||
PerlTextCharWidth
|
||||
PerlTextWrapI18N
|
||||
PerlUnicodeGCString
|
||||
PerlUnicodeLineBreak
|
||||
PerlYAMLTiny
|
||||
PkgConfig
|
||||
Procps
|
||||
Python
|
||||
PythonIniConfig
|
||||
PythonMako
|
||||
PythonMarkupSafe
|
||||
PythonPackaging
|
||||
PythonPluggy
|
||||
PythonPyTest
|
||||
PythonPyYAML
|
||||
PythonPygments
|
||||
QEMU
|
||||
Rdfind
|
||||
@@ -135,6 +143,8 @@ const (
|
||||
Rsync
|
||||
Sed
|
||||
Setuptools
|
||||
SPIRVHeaders
|
||||
SPIRVTools
|
||||
SquashfsTools
|
||||
Strace
|
||||
TamaGo
|
||||
@@ -148,15 +158,17 @@ const (
|
||||
WaylandProtocols
|
||||
XCB
|
||||
XCBProto
|
||||
Xproto
|
||||
XDGDBusProxy
|
||||
XZ
|
||||
Xproto
|
||||
Zlib
|
||||
Zstd
|
||||
|
||||
// PresetUnexportedStart is the first unexported preset.
|
||||
PresetUnexportedStart
|
||||
|
||||
buildcatrust = iota - 1
|
||||
llvmSource = iota - 1
|
||||
buildcatrust
|
||||
utilMacros
|
||||
|
||||
// Musl is a standalone libc that does not depend on the toolchain.
|
||||
|
||||
@@ -7,10 +7,10 @@ func (t Toolchain) newArgpStandalone() (pkg.Artifact, string) {
|
||||
version = "1.3"
|
||||
checksum = "vtW0VyO2pJ-hPyYmDI2zwSLS8QL0sPAUKC1t3zNYbwN2TmsaE-fADhaVtNd3eNFl"
|
||||
)
|
||||
return t.NewPackage("argp-standalone", version, pkg.NewHTTPGetTar(
|
||||
nil, "http://www.lysator.liu.se/~nisse/misc/"+
|
||||
return t.NewPackage("argp-standalone", version, newTar(
|
||||
"http://www.lysator.liu.se/~nisse/misc/"+
|
||||
"argp-standalone-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Env: []string{
|
||||
|
||||
@@ -7,9 +7,9 @@ func (t Toolchain) newBzip2() (pkg.Artifact, string) {
|
||||
version = "1.0.8"
|
||||
checksum = "cTLykcco7boom-s05H1JVsQi1AtChYL84nXkg_92Dm1Xt94Ob_qlMg_-NSguIK-c"
|
||||
)
|
||||
return t.NewPackage("bzip2", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://sourceware.org/pub/bzip2/bzip2-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("bzip2", version, newTar(
|
||||
"https://sourceware.org/pub/bzip2/bzip2-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
|
||||
@@ -13,10 +13,11 @@ func (t Toolchain) newCMake() (pkg.Artifact, string) {
|
||||
version = "4.3.1"
|
||||
checksum = "RHpzZiM1kJ5bwLjo9CpXSeHJJg3hTtV9QxBYpQoYwKFtRh5YhGWpShrqZCSOzQN6"
|
||||
)
|
||||
return t.NewPackage("cmake", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/Kitware/CMake/releases/download/"+
|
||||
"v"+version+"/cmake-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("cmake", version, newFromGitHubRelease(
|
||||
"Kitware/CMake",
|
||||
"v"+version,
|
||||
"cmake-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
// test suite expects writable source tree
|
||||
@@ -90,7 +91,7 @@ index 2ead810437..f85cbb8b1c 100644
|
||||
ConfigureName: "/usr/src/cmake/bootstrap",
|
||||
Configure: []KV{
|
||||
{"prefix", "/system"},
|
||||
{"parallel", `"$(nproc)"`},
|
||||
{"parallel", jobsE},
|
||||
{"--"},
|
||||
{"-DCMAKE_USE_OPENSSL", "OFF"},
|
||||
{"-DCMake_TEST_NO_NETWORK", "ON"},
|
||||
@@ -118,9 +119,6 @@ func init() {
|
||||
|
||||
// CMakeHelper is the [CMake] build system helper.
|
||||
type CMakeHelper struct {
|
||||
// Joined with name with a dash if non-empty.
|
||||
Variant string
|
||||
|
||||
// Path elements joined with source.
|
||||
Append []string
|
||||
|
||||
@@ -135,14 +133,6 @@ type CMakeHelper struct {
|
||||
|
||||
var _ Helper = new(CMakeHelper)
|
||||
|
||||
// name returns its arguments and an optional variant string joined with '-'.
|
||||
func (attr *CMakeHelper) name(name, version string) string {
|
||||
if attr != nil && attr.Variant != "" {
|
||||
name += "-" + attr.Variant
|
||||
}
|
||||
return name + "-" + version
|
||||
}
|
||||
|
||||
// extra returns a hardcoded slice of [CMake] and [Ninja].
|
||||
func (attr *CMakeHelper) extra(int) P {
|
||||
if attr != nil && attr.Make {
|
||||
@@ -180,10 +170,8 @@ func (attr *CMakeHelper) script(name string) string {
|
||||
}
|
||||
|
||||
generate := "Ninja"
|
||||
jobs := ""
|
||||
if attr.Make {
|
||||
generate = "'Unix Makefiles'"
|
||||
jobs += ` "--parallel=$(nproc)"`
|
||||
}
|
||||
|
||||
return `
|
||||
@@ -201,7 +189,7 @@ cmake -G ` + generate + ` \
|
||||
}), " \\\n\t") + ` \
|
||||
-DCMAKE_INSTALL_PREFIX=/system \
|
||||
'/usr/src/` + name + `/` + filepath.Join(attr.Append...) + `'
|
||||
cmake --build .` + jobs + `
|
||||
cmake --build . --parallel=` + jobsE + `
|
||||
cmake --install . --prefix=/work/system
|
||||
` + attr.Script
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ func (t Toolchain) newConnman() (pkg.Artifact, string) {
|
||||
version = "2.0"
|
||||
checksum = "MhVTdJOhndnZn2SWd8URKo_Pj7Zvc14tntEbrVOf9L3yVWJvpb3v3Q6104tWJgtW"
|
||||
)
|
||||
return t.NewPackage("connman", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://git.kernel.org/pub/scm/network/connman/connman.git/"+
|
||||
return t.NewPackage("connman", version, newTar(
|
||||
"https://git.kernel.org/pub/scm/network/connman/connman.git/"+
|
||||
"snapshot/connman-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Patches: []KV{
|
||||
|
||||
@@ -7,15 +7,15 @@ func (t Toolchain) newCurl() (pkg.Artifact, string) {
|
||||
version = "8.19.0"
|
||||
checksum = "YHuVLVVp8q_Y7-JWpID5ReNjq2Zk6t7ArHB6ngQXilp_R5l3cubdxu3UKo-xDByv"
|
||||
)
|
||||
return t.NewPackage("curl", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://curl.se/download/curl-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("curl", version, newTar(
|
||||
"https://curl.se/download/curl-"+version+".tar.bz2",
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), &PackageAttr{
|
||||
// remove broken test
|
||||
Writable: true,
|
||||
ScriptEarly: `
|
||||
chmod +w tests/data && rm tests/data/test459
|
||||
chmod +w tests/data && rm -f tests/data/test459
|
||||
`,
|
||||
}, &MakeHelper{
|
||||
Configure: []KV{
|
||||
@@ -25,7 +25,7 @@ chmod +w tests/data && rm tests/data/test459
|
||||
{"disable-smb"},
|
||||
},
|
||||
Check: []string{
|
||||
`TFLAGS="-j$(expr "$(nproc)" '*' 2)"`,
|
||||
"TFLAGS=" + jobsLFlagE,
|
||||
"test-nonflaky",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -7,11 +7,11 @@ func (t Toolchain) newDBus() (pkg.Artifact, string) {
|
||||
version = "1.16.2"
|
||||
checksum = "INwOuNdrDG7XW5ilW_vn8JSxEa444rRNc5ho97i84I1CNF09OmcFcV-gzbF4uCyg"
|
||||
)
|
||||
return t.NewPackage("dbus", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://gitlab.freedesktop.org/dbus/dbus/-/archive/"+
|
||||
"dbus-"+version+"/dbus-dbus-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
pkg.TarBzip2,
|
||||
return t.NewPackage("dbus", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"dbus/dbus",
|
||||
"dbus-"+version,
|
||||
checksum,
|
||||
), &PackageAttr{
|
||||
// OSError: [Errno 30] Read-only file system: '/usr/src/dbus/subprojects/packagecache'
|
||||
Writable: true,
|
||||
@@ -44,3 +44,38 @@ func init() {
|
||||
ID: 5356,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newXDGDBusProxy() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.1.7"
|
||||
checksum = "UW5Pe-TP-XAaN-kTbxrkOQ7eYdmlAQlr2pdreLtPT0uwdAz-7rzDP8V_8PWuZBup"
|
||||
)
|
||||
return t.NewPackage("xdg-dbus-proxy", version, newFromGitHub(
|
||||
"flatpak/xdg-dbus-proxy",
|
||||
version,
|
||||
checksum,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
{"Dman", "disabled"},
|
||||
},
|
||||
},
|
||||
DBus,
|
||||
|
||||
GLib,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[XDGDBusProxy] = Metadata{
|
||||
f: Toolchain.newXDGDBusProxy,
|
||||
|
||||
Name: "xdg-dbus-proxy",
|
||||
Description: "a filtering proxy for D-Bus connections",
|
||||
Website: "https://github.com/flatpak/xdg-dbus-proxy",
|
||||
|
||||
Dependencies: P{
|
||||
GLib,
|
||||
},
|
||||
|
||||
ID: 58434,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ func (t Toolchain) newDTC() (pkg.Artifact, string) {
|
||||
version = "1.7.2"
|
||||
checksum = "vUoiRynPyYRexTpS6USweT5p4SVHvvVJs8uqFkkVD-YnFjwf6v3elQ0-Etrh00Dt"
|
||||
)
|
||||
return t.NewPackage("dtc", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://git.kernel.org/pub/scm/utils/dtc/dtc.git/snapshot/"+
|
||||
return t.NewPackage("dtc", version, newTar(
|
||||
"https://git.kernel.org/pub/scm/utils/dtc/dtc.git/snapshot/"+
|
||||
"dtc-v"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
// works around buggy test:
|
||||
|
||||
@@ -7,10 +7,10 @@ func (t Toolchain) newElfutils() (pkg.Artifact, string) {
|
||||
version = "0.194"
|
||||
checksum = "Q3XUygUPv9vR1TkWucwUsQ8Kb1_F6gzk-KMPELr3cC_4AcTrprhVPMvN0CKkiYRa"
|
||||
)
|
||||
return t.NewPackage("elfutils", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://sourceware.org/elfutils/ftp/"+
|
||||
return t.NewPackage("elfutils", version, newTar(
|
||||
"https://sourceware.org/elfutils/ftp/"+
|
||||
version+"/elfutils-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), &PackageAttr{
|
||||
Env: []string{
|
||||
|
||||
@@ -135,10 +135,11 @@ func newIANAEtc() pkg.Artifact {
|
||||
version = "20251215"
|
||||
checksum = "kvKz0gW_rGG5QaNK9ZWmWu1IEgYAdmhj_wR7DYrh3axDfIql_clGRHmelP7525NJ"
|
||||
)
|
||||
return pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/Mic92/iana-etc/releases/download/"+
|
||||
version+"/iana-etc-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return newFromGitHubRelease(
|
||||
"Mic92/iana-etc",
|
||||
version,
|
||||
"iana-etc-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ func (t Toolchain) newFakeroot() (pkg.Artifact, string) {
|
||||
version = "1.37.2"
|
||||
checksum = "4ve-eDqVspzQ6VWDhPS0NjW3aSenBJcPAJq_BFT7OOFgUdrQzoTBxZWipDAGWxF8"
|
||||
)
|
||||
return t.NewPackage("fakeroot", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://salsa.debian.org/clint/fakeroot/-/archive/upstream/"+
|
||||
version+"/fakeroot-upstream-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
pkg.TarBzip2,
|
||||
return t.NewPackage("fakeroot", version, newFromGitLab(
|
||||
"salsa.debian.org",
|
||||
"clint/fakeroot",
|
||||
"upstream/"+version,
|
||||
checksum,
|
||||
), &PackageAttr{
|
||||
Patches: []KV{
|
||||
{"remove-broken-docs", `diff --git a/doc/Makefile.am b/doc/Makefile.am
|
||||
|
||||
@@ -9,10 +9,11 @@ func (t Toolchain) newFlex() (pkg.Artifact, string) {
|
||||
version = "2.6.4"
|
||||
checksum = "p9POjQU7VhgOf3x5iFro8fjhy0NOanvA7CTeuWS_veSNgCixIJshTrWVkc5XLZkB"
|
||||
)
|
||||
return t.NewPackage("flex", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/westes/flex/releases/download/"+
|
||||
"v"+version+"/flex-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("flex", version, newFromGitHubRelease(
|
||||
"westes/flex",
|
||||
"v"+version,
|
||||
"flex-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
M4,
|
||||
|
||||
@@ -7,10 +7,11 @@ func (t Toolchain) newFuse() (pkg.Artifact, string) {
|
||||
version = "3.18.2"
|
||||
checksum = "iL-7b7eUtmlVSf5cSq0dzow3UiqSjBmzV3cI_ENPs1tXcHdktkG45j1V12h-4jZe"
|
||||
)
|
||||
return t.NewPackage("fuse", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/libfuse/libfuse/releases/download/"+
|
||||
"fuse-"+version+"/fuse-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("fuse", version, newFromGitHubRelease(
|
||||
"libfuse/libfuse",
|
||||
"fuse-"+version,
|
||||
"fuse-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
|
||||
@@ -12,10 +12,10 @@ func (t Toolchain) newGit() (pkg.Artifact, string) {
|
||||
version = "2.53.0"
|
||||
checksum = "rlqSTeNgSeVKJA7nvzGqddFH8q3eFEPB4qRZft-4zth8wTHnbTbm7J90kp_obHGm"
|
||||
)
|
||||
return t.NewPackage("git", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://www.kernel.org/pub/software/scm/git/"+
|
||||
return t.NewPackage("git", version, newTar(
|
||||
"https://www.kernel.org/pub/software/scm/git/"+
|
||||
"git-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
ScriptEarly: `
|
||||
@@ -58,7 +58,7 @@ disable_test t2200-add-update
|
||||
"prove",
|
||||
},
|
||||
Install: `make \
|
||||
"-j$(nproc)" \
|
||||
` + jobsFlagE + ` \
|
||||
DESTDIR=/work \
|
||||
NO_INSTALL_HARDLINKS=1 \
|
||||
install`,
|
||||
@@ -114,3 +114,8 @@ git \
|
||||
rm -rf /work/.git
|
||||
`, resolvconf())
|
||||
}
|
||||
|
||||
// newTagRemote is a helper around NewViaGit for a tag on a git remote.
|
||||
func (t Toolchain) newTagRemote(url, tag, checksum string) pkg.Artifact {
|
||||
return t.NewViaGit(url, "refs/tags/"+tag, mustDecode(checksum))
|
||||
}
|
||||
|
||||
130
internal/rosa/glslang.go
Normal file
130
internal/rosa/glslang.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package rosa
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"hakurei.app/internal/pkg"
|
||||
)
|
||||
|
||||
func (t Toolchain) newSPIRVHeaders() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.4.341.0"
|
||||
checksum = "0PL43-19Iaw4k7_D8J8BvoJ-iLgCVSYZ2ThgDPGfAJwIJFtre7l0cnQtLjcY-JvD"
|
||||
)
|
||||
return t.NewPackage("spirv-headers", version, newFromGitHub(
|
||||
"KhronosGroup/SPIRV-Headers",
|
||||
"vulkan-sdk-"+version,
|
||||
checksum,
|
||||
), nil, &CMakeHelper{
|
||||
Cache: []KV{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
},
|
||||
}), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[SPIRVHeaders] = Metadata{
|
||||
f: Toolchain.newSPIRVHeaders,
|
||||
|
||||
Name: "spirv-headers",
|
||||
Description: "machine-readable files for the SPIR-V Registry",
|
||||
Website: "https://github.com/KhronosGroup/SPIRV-Headers",
|
||||
|
||||
ID: 230542,
|
||||
|
||||
// upstream changed version scheme, anitya incapable of filtering them
|
||||
latest: func(v *Versions) string {
|
||||
for _, s := range v.Stable {
|
||||
fields := strings.SplitN(s, ".", 4)
|
||||
if len(fields) != 4 {
|
||||
continue
|
||||
}
|
||||
if slices.ContainsFunc(fields, func(f string) bool {
|
||||
return slices.ContainsFunc([]byte(f), func(d byte) bool {
|
||||
return d < '0' || d > '9'
|
||||
})
|
||||
}) {
|
||||
continue
|
||||
}
|
||||
return s
|
||||
}
|
||||
return v.Latest
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newSPIRVTools() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "2026.1"
|
||||
checksum = "ZSQPQx8NltCDzQLk4qlaVxyWRWeI_JtsjEpeFt3kezTanl9DTHfLixSUCezMFBjv"
|
||||
)
|
||||
return t.NewPackage("spirv-tools", version, newFromGitHub(
|
||||
"KhronosGroup/SPIRV-Tools",
|
||||
"v"+version,
|
||||
checksum,
|
||||
), nil, &CMakeHelper{
|
||||
Cache: []KV{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
{"SPIRV-Headers_SOURCE_DIR", "/system"},
|
||||
},
|
||||
},
|
||||
Python,
|
||||
|
||||
SPIRVHeaders,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[SPIRVTools] = Metadata{
|
||||
f: Toolchain.newSPIRVTools,
|
||||
|
||||
Name: "spirv-tools",
|
||||
Description: "an API and commands for processing SPIR-V modules",
|
||||
Website: "https://github.com/KhronosGroup/SPIRV-Tools",
|
||||
|
||||
Dependencies: P{
|
||||
SPIRVHeaders,
|
||||
},
|
||||
|
||||
ID: 14894,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newGlslang() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "16.2.0"
|
||||
checksum = "6_UuF9reLRDaVkgO-9IfB3kMwme3lQZM8LL8YsJwPdUFkrjzxJtf2A9X3w9nFxj2"
|
||||
)
|
||||
return t.NewPackage("glslang", version, newFromGitHub(
|
||||
"KhronosGroup/glslang",
|
||||
version,
|
||||
checksum,
|
||||
), &PackageAttr{
|
||||
// test suite writes to source
|
||||
Writable: true,
|
||||
Chmod: true,
|
||||
}, &CMakeHelper{
|
||||
Cache: []KV{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
{"BUILD_SHARED_LIBS", "ON"},
|
||||
{"ALLOW_EXTERNAL_SPIRV_TOOLS", "ON"},
|
||||
},
|
||||
Script: "ctest",
|
||||
},
|
||||
Python,
|
||||
Bash,
|
||||
Diffutils,
|
||||
|
||||
SPIRVTools,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Glslang] = Metadata{
|
||||
f: Toolchain.newGlslang,
|
||||
|
||||
Name: "glslang",
|
||||
Description: "reference front end for GLSL/ESSL",
|
||||
Website: "https://github.com/KhronosGroup/glslang",
|
||||
|
||||
ID: 205796,
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,9 @@ func (t Toolchain) newM4() (pkg.Artifact, string) {
|
||||
version = "1.4.21"
|
||||
checksum = "pPa6YOo722Jw80l1OsH1tnUaklnPFjFT-bxGw5iAVrZTm1P8FQaWao_NXop46-pm"
|
||||
)
|
||||
return t.NewPackage("m4", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/m4/m4-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("m4", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/m4/m4-"+version+".tar.bz2",
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
@@ -43,9 +43,9 @@ func (t Toolchain) newBison() (pkg.Artifact, string) {
|
||||
version = "3.8.2"
|
||||
checksum = "BhRM6K7URj1LNOkIDCFDctSErLS-Xo5d9ba9seg10o6ACrgC1uNhED7CQPgIY29Y"
|
||||
)
|
||||
return t.NewPackage("bison", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/bison/bison-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("bison", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/bison/bison-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
M4,
|
||||
@@ -70,9 +70,9 @@ func (t Toolchain) newSed() (pkg.Artifact, string) {
|
||||
version = "4.9"
|
||||
checksum = "pe7HWH4PHNYrazOTlUoE1fXmhn2GOPFN_xE62i0llOr3kYGrH1g2_orDz0UtZ9Nt"
|
||||
)
|
||||
return t.NewPackage("sed", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/sed/sed-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("sed", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/sed/sed-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
Diffutils,
|
||||
@@ -95,15 +95,15 @@ func (t Toolchain) newAutoconf() (pkg.Artifact, string) {
|
||||
version = "2.73"
|
||||
checksum = "yGabDTeOfaCUB0JX-h3REYLYzMzvpDwFmFFzHNR7QilChCUNE4hR6q7nma4viDYg"
|
||||
)
|
||||
return t.NewPackage("autoconf", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/autoconf/autoconf-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("autoconf", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/autoconf/autoconf-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Flag: TExclusive,
|
||||
}, &MakeHelper{
|
||||
Check: []string{
|
||||
`TESTSUITEFLAGS="-j$(nproc)"`,
|
||||
"TESTSUITEFLAGS=" + jobsFlagE,
|
||||
"check",
|
||||
},
|
||||
},
|
||||
@@ -135,9 +135,9 @@ func (t Toolchain) newAutomake() (pkg.Artifact, string) {
|
||||
version = "1.18.1"
|
||||
checksum = "FjvLG_GdQP7cThTZJLDMxYpRcKdpAVG-YDs1Fj1yaHlSdh_Kx6nRGN14E0r_BjcG"
|
||||
)
|
||||
return t.NewPackage("automake", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/automake/automake-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("automake", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/automake/automake-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
@@ -179,13 +179,13 @@ func (t Toolchain) newLibtool() (pkg.Artifact, string) {
|
||||
version = "2.5.4"
|
||||
checksum = "pa6LSrQggh8mSJHQfwGjysAApmZlGJt8wif2cCLzqAAa2jpsTY0jZ-6stS3BWZ2Q"
|
||||
)
|
||||
return t.NewPackage("libtool", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/libtool/libtool-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libtool", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/libtool/libtool-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MakeHelper{
|
||||
Check: []string{
|
||||
`TESTSUITEFLAGS="-j$(nproc)"`,
|
||||
"TESTSUITEFLAGS=" + jobsFlagE,
|
||||
"check",
|
||||
},
|
||||
},
|
||||
@@ -210,9 +210,9 @@ func (t Toolchain) newGzip() (pkg.Artifact, string) {
|
||||
version = "1.14"
|
||||
checksum = "NWhjUavnNfTDFkZJyAUonL9aCOak8GVajWX2OMlzpFnuI0ErpBFyj88mz2xSjz0q"
|
||||
)
|
||||
return t.NewPackage("gzip", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/gzip/gzip-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("gzip", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/gzip/gzip-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MakeHelper{
|
||||
// dependency loop
|
||||
@@ -236,9 +236,9 @@ func (t Toolchain) newGettext() (pkg.Artifact, string) {
|
||||
version = "1.0"
|
||||
checksum = "3MasKeEdPeFEgWgzsBKk7JqWqql1wEMbgPmzAfs-mluyokoW0N8oQVxPQoOnSdgC"
|
||||
)
|
||||
return t.NewPackage("gettext", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/gettext/gettext-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("gettext", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/gettext/gettext-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
@@ -282,9 +282,9 @@ func (t Toolchain) newDiffutils() (pkg.Artifact, string) {
|
||||
version = "3.12"
|
||||
checksum = "9J5VAq5oA7eqwzS1Yvw-l3G5o-TccUrNQR3PvyB_lgdryOFAfxtvQfKfhdpquE44"
|
||||
)
|
||||
return t.NewPackage("diffutils", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/diffutils/diffutils-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("diffutils", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/diffutils/diffutils-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
@@ -315,9 +315,9 @@ func (t Toolchain) newPatch() (pkg.Artifact, string) {
|
||||
version = "2.8"
|
||||
checksum = "MA0BQc662i8QYBD-DdGgyyfTwaeALZ1K0yusV9rAmNiIsQdX-69YC4t9JEGXZkeR"
|
||||
)
|
||||
return t.NewPackage("patch", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/patch/patch-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("patch", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/patch/patch-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
@@ -347,9 +347,9 @@ func (t Toolchain) newBash() (pkg.Artifact, string) {
|
||||
version = "5.3"
|
||||
checksum = "4LQ_GRoB_ko-Ih8QPf_xRKA02xAm_TOxQgcJLmFDT6udUPxTAWrsj-ZNeuTusyDq"
|
||||
)
|
||||
return t.NewPackage("bash", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/bash/bash-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("bash", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/bash/bash-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Flag: TEarly,
|
||||
@@ -377,9 +377,9 @@ func (t Toolchain) newCoreutils() (pkg.Artifact, string) {
|
||||
version = "9.10"
|
||||
checksum = "o-B9wssRnZySzJUI1ZJAgw-bZtj1RC67R9po2AcM2OjjS8FQIl16IRHpC6IwO30i"
|
||||
)
|
||||
return t.NewPackage("coreutils", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/coreutils/coreutils-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("coreutils", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/coreutils/coreutils-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
@@ -516,9 +516,9 @@ func (t Toolchain) newTexinfo() (pkg.Artifact, string) {
|
||||
version = "7.3"
|
||||
checksum = "RRmC8Xwdof7JuZJeWGAQ_GeASIHAuJFQMbNONXBz5InooKIQGmqmWRjGNGEr5n4-"
|
||||
)
|
||||
return t.NewPackage("texinfo", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/texinfo/texinfo-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("texinfo", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/texinfo/texinfo-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MakeHelper{
|
||||
// nonstandard glibc extension
|
||||
@@ -549,9 +549,9 @@ func (t Toolchain) newGperf() (pkg.Artifact, string) {
|
||||
version = "3.3"
|
||||
checksum = "RtIy9pPb_Bb8-31J2Nw-rRGso2JlS-lDlVhuNYhqR7Nt4xM_nObznxAlBMnarJv7"
|
||||
)
|
||||
return t.NewPackage("gperf", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gperf/gperf-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("gperf", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gperf/gperf-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
Diffutils,
|
||||
@@ -574,9 +574,9 @@ func (t Toolchain) newGawk() (pkg.Artifact, string) {
|
||||
version = "5.4.0"
|
||||
checksum = "m0RkIolC-PI7EY5q8pcx5Y-0twlIW0Yp3wXXmV-QaHorSdf8BhZ7kW9F8iWomz0C"
|
||||
)
|
||||
return t.NewPackage("gawk", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/gawk/gawk-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("gawk", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/gawk/gawk-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Flag: TEarly,
|
||||
@@ -602,9 +602,9 @@ func (t Toolchain) newGrep() (pkg.Artifact, string) {
|
||||
version = "3.12"
|
||||
checksum = "qMB4RjaPNRRYsxix6YOrjE8gyAT1zVSTy4nW4wKW9fqa0CHYAuWgPwDTirENzm_1"
|
||||
)
|
||||
return t.NewPackage("grep", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/grep/grep-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("grep", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/grep/grep-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
@@ -639,7 +639,6 @@ func (t Toolchain) newFindutils() (pkg.Artifact, string) {
|
||||
nil, "https://ftpmirror.gnu.org/gnu/findutils/findutils-"+version+".tar.xz",
|
||||
mustDecode(checksum),
|
||||
), &PackageAttr{
|
||||
SourceKind: SourceKindTarXZ,
|
||||
ScriptEarly: `
|
||||
echo '#!/bin/sh' > gnulib-tests/test-c32ispunct.sh
|
||||
echo 'int main(){return 0;}' > tests/xargs/test-sigusr.c
|
||||
@@ -667,9 +666,9 @@ func (t Toolchain) newBC() (pkg.Artifact, string) {
|
||||
version = "1.08.2"
|
||||
checksum = "8h6f3hjV80XiFs6v9HOPF2KEyg1kuOgn5eeFdVspV05ODBVQss-ey5glc8AmneLy"
|
||||
)
|
||||
return t.NewPackage("bc", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/bc/bc-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("bc", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/bc/bc-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
// source expected to be writable
|
||||
@@ -696,9 +695,9 @@ func (t Toolchain) newLibiconv() (pkg.Artifact, string) {
|
||||
version = "1.19"
|
||||
checksum = "UibB6E23y4MksNqYmCCrA3zTFO6vJugD1DEDqqWYFZNuBsUWMVMcncb_5pPAr88x"
|
||||
)
|
||||
return t.NewPackage("libiconv", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/libiconv/libiconv-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libiconv", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/libiconv/libiconv-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil)), version
|
||||
}
|
||||
@@ -719,9 +718,9 @@ func (t Toolchain) newTar() (pkg.Artifact, string) {
|
||||
version = "1.35"
|
||||
checksum = "zSaoSlVUDW0dSfm4sbL4FrXLFR8U40Fh3zY5DWhR5NCIJ6GjU6Kc4VZo2-ZqpBRA"
|
||||
)
|
||||
return t.NewPackage("tar", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/tar/tar-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("tar", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/tar/tar-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MakeHelper{
|
||||
Configure: []KV{
|
||||
@@ -733,7 +732,7 @@ func (t Toolchain) newTar() (pkg.Artifact, string) {
|
||||
// very expensive
|
||||
"TARTEST_SKIP_LARGE_FILES=1",
|
||||
|
||||
`TESTSUITEFLAGS="-j$(nproc)"`,
|
||||
"TESTSUITEFLAGS=" + jobsFlagE,
|
||||
"check",
|
||||
},
|
||||
},
|
||||
@@ -761,9 +760,9 @@ func (t Toolchain) newParallel() (pkg.Artifact, string) {
|
||||
version = "20260322"
|
||||
checksum = "gHoPmFkOO62ev4xW59HqyMlodhjp8LvTsBOwsVKHUUdfrt7KwB8koXmSVqQ4VOrB"
|
||||
)
|
||||
return t.NewPackage("parallel", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/parallel/parallel-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("parallel", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/parallel/parallel-"+version+".tar.bz2",
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
Perl,
|
||||
@@ -790,9 +789,9 @@ func (t Toolchain) newLibunistring() (pkg.Artifact, string) {
|
||||
version = "1.4.2"
|
||||
checksum = "iW9BbfLoVlXjWoLTZ4AekQSu4cFBnLcZ4W8OHWbv0AhJNgD3j65_zqaLMzFKylg2"
|
||||
)
|
||||
return t.NewPackage("libunistring", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftp.gnu.org/gnu/libunistring/libunistring-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libunistring", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/libunistring/libunistring-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
@@ -823,9 +822,9 @@ func (t Toolchain) newLibtasn1() (pkg.Artifact, string) {
|
||||
version = "4.21.0"
|
||||
checksum = "9DYI3UYbfYLy8JsKUcY6f0irskbfL0fHZA91Q-JEOA3kiUwpodyjemRsYRjUpjuq"
|
||||
)
|
||||
return t.NewPackage("libtasn1", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/libtasn1/libtasn1-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libtasn1", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/libtasn1/libtasn1-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil)), version
|
||||
}
|
||||
@@ -846,9 +845,9 @@ func (t Toolchain) newReadline() (pkg.Artifact, string) {
|
||||
version = "8.3"
|
||||
checksum = "r-lcGRJq_MvvBpOq47Z2Y1OI2iqrmtcqhTLVXR0xWo37ZpC2uT_md7gKq5o_qTMV"
|
||||
)
|
||||
return t.NewPackage("readline", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftp.gnu.org/gnu/readline/readline-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("readline", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/readline/readline-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MakeHelper{
|
||||
Configure: []KV{
|
||||
@@ -889,10 +888,9 @@ func (t Toolchain) newGnuTLS() (pkg.Artifact, string) {
|
||||
}
|
||||
}
|
||||
|
||||
return t.NewPackage("gnutls", version, t.NewViaGit(
|
||||
return t.NewPackage("gnutls", version, t.newTagRemote(
|
||||
"https://gitlab.com/gnutls/gnutls.git",
|
||||
"refs/tags/"+version,
|
||||
mustDecode(checksum),
|
||||
version, checksum,
|
||||
), &PackageAttr{
|
||||
Patches: []KV{
|
||||
{"bootstrap-remove-gtk-doc", `diff --git a/bootstrap.conf b/bootstrap.conf
|
||||
@@ -1062,9 +1060,9 @@ func (t Toolchain) newBinutils() (pkg.Artifact, string) {
|
||||
version = "2.46.0"
|
||||
checksum = "4kK1_EXQipxSqqyvwD4LbiMLFKCUApjq6PeG4XJP4dzxYGqDeqXfh8zLuTyOuOVR"
|
||||
)
|
||||
return t.NewPackage("binutils", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/binutils/binutils-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("binutils", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/binutils/binutils-"+version+".tar.bz2",
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
Bash,
|
||||
@@ -1087,12 +1085,16 @@ func (t Toolchain) newGMP() (pkg.Artifact, string) {
|
||||
version = "6.3.0"
|
||||
checksum = "yrgbgEDWKDdMWVHh7gPbVl56-sRtVVhfvv0M_LX7xMUUk_mvZ1QOJEAnt7g4i3k5"
|
||||
)
|
||||
return t.NewPackage("gmp", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://gcc.gnu.org/pub/gcc/infrastructure/"+
|
||||
return t.NewPackage("gmp", version, newTar(
|
||||
"https://gcc.gnu.org/pub/gcc/infrastructure/"+
|
||||
"gmp-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
), &PackageAttr{
|
||||
Env: []string{
|
||||
"CC=cc",
|
||||
},
|
||||
}, (*MakeHelper)(nil),
|
||||
M4,
|
||||
), version
|
||||
}
|
||||
@@ -1113,10 +1115,10 @@ func (t Toolchain) newMPFR() (pkg.Artifact, string) {
|
||||
version = "4.2.2"
|
||||
checksum = "wN3gx0zfIuCn9r3VAn_9bmfvAYILwrRfgBjYSD1IjLqyLrLojNN5vKyQuTE9kA-B"
|
||||
)
|
||||
return t.NewPackage("mpfr", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://gcc.gnu.org/pub/gcc/infrastructure/"+
|
||||
return t.NewPackage("mpfr", version, newTar(
|
||||
"https://gcc.gnu.org/pub/gcc/infrastructure/"+
|
||||
"mpfr-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
GMP,
|
||||
@@ -1143,10 +1145,9 @@ func (t Toolchain) newMPC() (pkg.Artifact, string) {
|
||||
version = "1.4.0"
|
||||
checksum = "TbrxLiE3ipQrHz_F3Xzz4zqBAnkMWyjhNwIK6wh9360RZ39xMt8rxfW3LxA9SnvU"
|
||||
)
|
||||
return t.NewPackage("mpc", version, t.NewViaGit(
|
||||
return t.NewPackage("mpc", version, t.newTagRemote(
|
||||
"https://gitlab.inria.fr/mpc/mpc.git",
|
||||
"refs/tags/"+version,
|
||||
mustDecode(checksum),
|
||||
version, checksum,
|
||||
), &PackageAttr{
|
||||
// does not find mpc-impl.h otherwise
|
||||
EnterSource: true,
|
||||
@@ -1182,10 +1183,17 @@ func (t Toolchain) newGCC() (pkg.Artifact, string) {
|
||||
version = "15.2.0"
|
||||
checksum = "TXJ5WrbXlGLzy1swghQTr4qxgDCyIZFgJry51XEPTBZ8QYbVmFeB4lZbSMtPJ-a1"
|
||||
)
|
||||
return t.NewPackage("gcc", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"+
|
||||
|
||||
var configureExtra []KV
|
||||
switch runtime.GOARCH {
|
||||
case "amd64", "arm64":
|
||||
configureExtra = append(configureExtra, KV{"with-multilib-list", "''"})
|
||||
}
|
||||
|
||||
return t.NewPackage("gcc", version, newTar(
|
||||
"https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"+
|
||||
"gcc-"+version+"/gcc-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Patches: []KV{
|
||||
@@ -1347,9 +1355,8 @@ ln -s system/lib /work/
|
||||
// it also saturates the CPU for a consequential amount of time.
|
||||
Flag: TExclusive,
|
||||
}, &MakeHelper{
|
||||
Configure: []KV{
|
||||
Configure: append([]KV{
|
||||
{"disable-multilib"},
|
||||
{"with-multilib-list", `""`},
|
||||
{"enable-default-pie"},
|
||||
{"disable-nls"},
|
||||
{"with-gnu-as"},
|
||||
@@ -1357,7 +1364,7 @@ ln -s system/lib /work/
|
||||
{"with-system-zlib"},
|
||||
{"enable-languages", "c,c++,go"},
|
||||
{"with-native-system-header-dir", "/system/include"},
|
||||
},
|
||||
}, configureExtra...),
|
||||
Make: []string{
|
||||
"BOOT_CFLAGS='-O2 -g'",
|
||||
"bootstrap",
|
||||
|
||||
@@ -21,9 +21,9 @@ cd /work/system/go/src
|
||||
chmod -R +w ..
|
||||
|
||||
./make.bash
|
||||
`, pkg.Path(AbsUsrSrc.Append("go"), false, pkg.NewHTTPGetTar(
|
||||
nil, "https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz",
|
||||
mustDecode(checksum),
|
||||
`, pkg.Path(AbsUsrSrc.Append("go"), false, newTar(
|
||||
"https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
)))
|
||||
}
|
||||
@@ -55,9 +55,9 @@ ln -s \
|
||||
../go/bin/go \
|
||||
../go/bin/gofmt \
|
||||
/work/system/bin
|
||||
`, pkg.Path(AbsUsrSrc.Append("go"), false, pkg.NewHTTPGetTar(
|
||||
nil, "https://go.dev/dl/go"+version+".src.tar.gz",
|
||||
mustDecode(checksum),
|
||||
`, pkg.Path(AbsUsrSrc.Append("go"), false, newTar(
|
||||
"https://go.dev/dl/go"+version+".src.tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
)))
|
||||
}
|
||||
@@ -141,8 +141,8 @@ rm \
|
||||
)
|
||||
|
||||
const (
|
||||
version = "1.26.1"
|
||||
checksum = "DdC5Ea-aCYPUHNObQh_09uWU0vn4e-8Ben850Vq-5OoamDRrXhuYI4YQ_BOFgaT0"
|
||||
version = "1.26.2"
|
||||
checksum = "v-6BE89_1g3xYf-9oIYpJKFXlo3xKHYJj2_VGkaUq8ZVkIVQmLwrto-xGG03OISH"
|
||||
)
|
||||
return t.newGo(
|
||||
version,
|
||||
|
||||
@@ -10,10 +10,9 @@ func (t Toolchain) newGLib() (pkg.Artifact, string) {
|
||||
version = "2.88.0"
|
||||
checksum = "T79Cg4z6j-sDZ2yIwvbY4ccRv2-fbwbqgcw59F5NQ6qJT6z4v261vbYp3dHO6Ma3"
|
||||
)
|
||||
return t.NewPackage("glib", version, t.NewViaGit(
|
||||
return t.NewPackage("glib", version, t.newTagRemote(
|
||||
"https://gitlab.gnome.org/GNOME/glib.git",
|
||||
"refs/tags/"+version,
|
||||
mustDecode(checksum),
|
||||
version, checksum,
|
||||
), &PackageAttr{
|
||||
Paths: []pkg.ExecPath{
|
||||
pkg.Path(fhs.AbsEtc.Append(
|
||||
|
||||
@@ -99,7 +99,7 @@ mkdir -p /work/system/bin/
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
return t.newHakurei("-dist", `
|
||||
export HAKUREI_VERSION
|
||||
DESTDIR=/work /usr/src/hakurei/dist/release.sh
|
||||
DESTDIR=/work /usr/src/hakurei/all.sh
|
||||
`, true), hakureiVersion
|
||||
},
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@ package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
const hakureiVersion = "0.3.7"
|
||||
const hakureiVersion = "0.4.0"
|
||||
|
||||
// hakureiSource is the source code of a hakurei release.
|
||||
var hakureiSource = pkg.NewHTTPGetTar(
|
||||
nil, "https://git.gensokyo.uk/rosa/hakurei/archive/"+
|
||||
var hakureiSource = newTar(
|
||||
"https://git.gensokyo.uk/rosa/hakurei/archive/"+
|
||||
"v"+hakureiVersion+".tar.gz",
|
||||
mustDecode("Xh_sdITOATEAQN5_UuaOyrWsgboxorqRO9bml3dGm8GAxF8NFpB7MqhSZgjJxAl2"),
|
||||
"wfQ9DqCW0Fw9o91wj-I55waoqzB-UqzzuC0_2h-P-1M78SgZ1WHSPCDJMth6EyC2",
|
||||
pkg.TarGzip,
|
||||
)
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@ package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
const kernelVersion = "6.12.80"
|
||||
const kernelVersion = "6.12.81"
|
||||
|
||||
var kernelSource = pkg.NewHTTPGetTar(
|
||||
nil, "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/"+
|
||||
var kernelSource = newTar(
|
||||
"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/"+
|
||||
"snapshot/linux-"+kernelVersion+".tar.gz",
|
||||
mustDecode("_iJEAYoQISJxefuWZYfv0RPWUmHHIjHQw33Fapix-irXrEIREP5ruK37UJW4uMZO"),
|
||||
"fBkNwf82DQXh74in6gaF2Jot7Vg-Vlcp9BUtCEipL9mvcM1EXLVFdV7FcrO20Eve",
|
||||
pkg.TarGzip,
|
||||
)
|
||||
|
||||
@@ -1221,7 +1221,7 @@ install -Dm0500 \
|
||||
/sbin/depmod
|
||||
|
||||
make \
|
||||
"-j$(nproc)" \
|
||||
` + jobsFlagE + ` \
|
||||
-f /usr/src/kernel/Makefile \
|
||||
O=/tmp/kbuild \
|
||||
LLVM=1 \
|
||||
@@ -1282,14 +1282,14 @@ func init() {
|
||||
|
||||
func (t Toolchain) newFirmware() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "20260309"
|
||||
checksum = "M1az8BxSiOEH3LA11Trc5VAlakwAHhP7-_LKWg6k-SVIzU3xclMDO4Tiujw1gQrC"
|
||||
version = "20260410"
|
||||
checksum = "J8PdQlGqwrivpskPzbL6xacqR6mlKtXpe5RpzFfVzKPAgG81ZRXsc3qrxwdGJbil"
|
||||
)
|
||||
return t.NewPackage("firmware", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://gitlab.com/kernel-firmware/linux-firmware/-/"+
|
||||
"archive/"+version+"/linux-firmware-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
pkg.TarBzip2,
|
||||
return t.NewPackage("firmware", version, newFromGitLab(
|
||||
"gitlab.com",
|
||||
"kernel-firmware/linux-firmware",
|
||||
version,
|
||||
checksum,
|
||||
), &PackageAttr{
|
||||
// dedup creates temporary file
|
||||
Writable: true,
|
||||
@@ -1309,7 +1309,7 @@ func (t Toolchain) newFirmware() (pkg.Artifact, string) {
|
||||
"install-zst",
|
||||
},
|
||||
SkipCheck: true, // requires pre-commit
|
||||
Install: `make "-j$(nproc)" DESTDIR=/work/system dedup`,
|
||||
Install: "make " + jobsFlagE + " DESTDIR=/work/system dedup",
|
||||
},
|
||||
Parallel,
|
||||
Rdfind,
|
||||
|
||||
@@ -7,10 +7,10 @@ func (t Toolchain) newKmod() (pkg.Artifact, string) {
|
||||
version = "34.2"
|
||||
checksum = "0K7POeTKxMhExsaTsnKAC6LUNsRSfe6sSZxWONPbOu-GI_pXOw3toU_BIoqfBhJV"
|
||||
)
|
||||
return t.NewPackage("kmod", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://www.kernel.org/pub/linux/utils/kernel/"+
|
||||
return t.NewPackage("kmod", version, newTar(
|
||||
"https://www.kernel.org/pub/linux/utils/kernel/"+
|
||||
"kmod/kmod-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
|
||||
@@ -7,10 +7,9 @@ func (t Toolchain) newLibmd() (pkg.Artifact, string) {
|
||||
version = "1.1.0"
|
||||
checksum = "9apYqPPZm0j5HQT8sCsVIhnVIqRD7XgN7kPIaTwTqnTuUq5waUAMq4M7ev8CODJ1"
|
||||
)
|
||||
return t.NewPackage("libmd", version, t.NewViaGit(
|
||||
return t.NewPackage("libmd", version, t.newTagRemote(
|
||||
"https://git.hadrons.org/git/libmd.git",
|
||||
"refs/tags/"+version,
|
||||
mustDecode(checksum),
|
||||
version, checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "echo '" + version + "' > .dist-version && ./autogen",
|
||||
ScriptMakeEarly: `
|
||||
@@ -38,10 +37,9 @@ func (t Toolchain) newLibbsd() (pkg.Artifact, string) {
|
||||
version = "0.12.2"
|
||||
checksum = "NVS0xFLTwSP8JiElEftsZ-e1_C-IgJhHrHE77RwKt5178M7r087waO-zYx2_dfGX"
|
||||
)
|
||||
return t.NewPackage("libbsd", version, t.NewViaGit(
|
||||
return t.NewPackage("libbsd", version, t.newTagRemote(
|
||||
"https://gitlab.freedesktop.org/libbsd/libbsd.git",
|
||||
"refs/tags/"+version,
|
||||
mustDecode(checksum),
|
||||
version, checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "echo '" + version + "' > .dist-version && ./autogen",
|
||||
},
|
||||
|
||||
@@ -4,13 +4,13 @@ import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newLibcap() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "2.77"
|
||||
checksum = "2GOTFU4cl2QoS7Dv5wh0c9-hxsQwIzMB9Y_gfAo5xKHqcM13fiHt1RbPkfemzjmB"
|
||||
version = "2.78"
|
||||
checksum = "wFdUkBhFMD9InPnrBZyegWrlPSAg_9JiTBC-eSFyWWlmbzL2qjh2mKxr9Kx2a8ut"
|
||||
)
|
||||
return t.NewPackage("libcap", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://git.kernel.org/pub/scm/libs/libcap/libcap.git/"+
|
||||
return t.NewPackage("libcap", version, newTar(
|
||||
"https://git.kernel.org/pub/scm/libs/libcap/libcap.git/"+
|
||||
"snapshot/libcap-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
// uses source tree as scratch space
|
||||
|
||||
@@ -7,9 +7,9 @@ func (t Toolchain) newLibev() (pkg.Artifact, string) {
|
||||
version = "4.33"
|
||||
checksum = "774eSXV_4k8PySRprUDChbEwsw-kzjIFnJ3MpNOl5zDpamBRvC3BqPyRxvkwcL6_"
|
||||
)
|
||||
return t.NewPackage("libev", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://dist.schmorp.de/libev/Attic/libev-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libev", version, newTar(
|
||||
"https://dist.schmorp.de/libev/Attic/libev-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil)), version
|
||||
}
|
||||
|
||||
@@ -11,11 +11,11 @@ func (t Toolchain) newLibexpat() (pkg.Artifact, string) {
|
||||
version = "2.7.5"
|
||||
checksum = "vTRUjjg-qbHSXUBYKXgzVHkUO7UNyuhrkSYrE7ikApQm0g-OvQ8tspw4w55M-1Tp"
|
||||
)
|
||||
return t.NewPackage("libexpat", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/libexpat/libexpat/releases/download/"+
|
||||
"R_"+strings.ReplaceAll(version, ".", "_")+"/"+
|
||||
"expat-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libexpat", version, newFromGitHubRelease(
|
||||
"libexpat/libexpat",
|
||||
"R_"+strings.ReplaceAll(version, ".", "_"),
|
||||
"expat-"+version+".tar.bz2",
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
Bash,
|
||||
|
||||
@@ -7,10 +7,11 @@ func (t Toolchain) newLibffi() (pkg.Artifact, string) {
|
||||
version = "3.5.2"
|
||||
checksum = "2_Q-ZNBBbVhltfL5zEr0wljxPegUimTK4VeMSiwJEGksls3n4gj3lV0Ly3vviSFH"
|
||||
)
|
||||
return t.NewPackage("libffi", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/libffi/libffi/releases/download/"+
|
||||
"v"+version+"/libffi-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libffi", version, newFromGitHubRelease(
|
||||
"libffi/libffi",
|
||||
"v"+version,
|
||||
"libffi-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
KernelHeaders,
|
||||
|
||||
@@ -7,10 +7,10 @@ func (t Toolchain) newLibgd() (pkg.Artifact, string) {
|
||||
version = "2.3.3"
|
||||
checksum = "8T-sh1_FJT9K9aajgxzh8ot6vWIF-xxjcKAHvTak9MgGUcsFfzP8cAvvv44u2r36"
|
||||
)
|
||||
return t.NewPackage("libgd", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/libgd/libgd/releases/download/"+
|
||||
"gd-"+version+"/libgd-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libgd", version, newFromGitHubRelease(
|
||||
"libgd/libgd",
|
||||
"gd-"+version,
|
||||
"libgd-"+version+".tar.gz", checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Env: []string{
|
||||
|
||||
@@ -7,10 +7,11 @@ func (t Toolchain) newLibpsl() (pkg.Artifact, string) {
|
||||
version = "0.21.5"
|
||||
checksum = "XjfxSzh7peG2Vg4vJlL8z4JZJLcXqbuP6pLWkrGCmRxlnYUFTKNBqWGHCxEOlCad"
|
||||
)
|
||||
return t.NewPackage("libpsl", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/rockdaboot/libpsl/releases/download/"+
|
||||
version+"/libpsl-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libpsl", version, newFromGitHubRelease(
|
||||
"rockdaboot/libpsl",
|
||||
version,
|
||||
"libpsl-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
|
||||
@@ -7,10 +7,11 @@ func (t Toolchain) newLibseccomp() (pkg.Artifact, string) {
|
||||
version = "2.6.0"
|
||||
checksum = "mMu-iR71guPjFbb31u-YexBaanKE_nYPjPux-vuBiPfS_0kbwJdfCGlkofaUm-EY"
|
||||
)
|
||||
return t.NewPackage("libseccomp", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/seccomp/libseccomp/releases/download/"+
|
||||
"v"+version+"/libseccomp-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("libseccomp", version, newFromGitHubRelease(
|
||||
"seccomp/libseccomp",
|
||||
"v"+version,
|
||||
"libseccomp-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
ScriptEarly: `
|
||||
|
||||
@@ -7,11 +7,10 @@ func (t Toolchain) newLibucontext() (pkg.Artifact, string) {
|
||||
version = "1.5"
|
||||
checksum = "Ggk7FMmDNBdCx1Z9PcNWWW6LSpjGYssn2vU0GK5BLXJYw7ZxZbA2m_eSgT9TFnIG"
|
||||
)
|
||||
return t.NewPackage("libucontext", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/kaniini/libucontext/archive/refs/tags/"+
|
||||
"libucontext-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.NewPackage("libucontext", version, newFromGitHub(
|
||||
"kaniini/libucontext",
|
||||
"libucontext-"+version,
|
||||
checksum,
|
||||
), &PackageAttr{
|
||||
// uses source tree as scratch space
|
||||
Writable: true,
|
||||
|
||||
@@ -7,10 +7,9 @@ func (t Toolchain) newLibxml2() (pkg.Artifact, string) {
|
||||
version = "2.15.2"
|
||||
checksum = "zwQvCIBnjzUFY-inX5ckfNT3mIezsCRV55C_Iztde5OnRTB3u33lfO5h03g7DK_8"
|
||||
)
|
||||
return t.NewPackage("libxml2", version, t.NewViaGit(
|
||||
return t.NewPackage("libxml2", version, t.newTagRemote(
|
||||
"https://gitlab.gnome.org/GNOME/libxml2.git",
|
||||
"refs/tags/v"+version,
|
||||
mustDecode(checksum),
|
||||
"v"+version, checksum,
|
||||
), &PackageAttr{
|
||||
// can't create shell.out: Read-only file system
|
||||
Writable: true,
|
||||
|
||||
@@ -7,10 +7,9 @@ func (t Toolchain) newLibxslt() (pkg.Artifact, string) {
|
||||
version = "1.1.45"
|
||||
checksum = "MZc_dyUWpHChkWDKa5iycrECxBsRd4ZMbYfL4VojTbung593mlH2tHGmxYB6NFYT"
|
||||
)
|
||||
return t.NewPackage("libxslt", version, t.NewViaGit(
|
||||
return t.NewPackage("libxslt", version, t.newTagRemote(
|
||||
"https://gitlab.gnome.org/GNOME/libxslt.git",
|
||||
"refs/tags/v"+version,
|
||||
mustDecode(checksum),
|
||||
"v"+version, checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "NOCONFIGURE=1 ./autogen.sh",
|
||||
|
||||
|
||||
@@ -1,239 +1,48 @@
|
||||
package rosa
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
"hakurei.app/internal/pkg"
|
||||
)
|
||||
func init() {
|
||||
artifactsM[llvmSource] = Metadata{
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
return t.NewPatchedSource("llvm", llvmVersion, newFromGitHub(
|
||||
"llvm/llvm-project",
|
||||
"llvmorg-"+llvmVersion,
|
||||
llvmChecksum,
|
||||
), true, llvmPatches...), llvmVersion
|
||||
},
|
||||
|
||||
// llvmAttr holds the attributes that will be applied to a new [pkg.Artifact]
|
||||
// containing a LLVM variant.
|
||||
type llvmAttr struct {
|
||||
// Passed through to PackageAttr.Flag.
|
||||
flags int
|
||||
Name: "llvm-project",
|
||||
Description: "LLVM monorepo with Rosa OS patches",
|
||||
|
||||
// Concatenated with default environment for PackageAttr.Env.
|
||||
env []string
|
||||
// Concatenated with generated entries for CMakeHelper.Cache.
|
||||
cmake []KV
|
||||
// Override CMakeHelper.Append.
|
||||
append []string
|
||||
// Passed through to PackageAttr.NonStage0.
|
||||
nonStage0 []pkg.Artifact
|
||||
// Passed through to PackageAttr.Paths.
|
||||
paths []pkg.ExecPath
|
||||
// Concatenated with default fixup for CMakeHelper.Script.
|
||||
script string
|
||||
|
||||
// Patch name and body pairs.
|
||||
patches []KV
|
||||
}
|
||||
|
||||
const (
|
||||
llvmProjectClang = 1 << iota
|
||||
llvmProjectLld
|
||||
|
||||
llvmProjectAll = 1<<iota - 1
|
||||
|
||||
llvmRuntimeCompilerRT = 1 << iota
|
||||
llvmRuntimeLibunwind
|
||||
llvmRuntimeLibc
|
||||
llvmRuntimeLibcxx
|
||||
llvmRuntimeLibcxxABI
|
||||
|
||||
llvmAll = 1<<iota - 1
|
||||
llvmRuntimeAll = llvmAll - (2 * llvmProjectAll) - 1
|
||||
)
|
||||
|
||||
// llvmFlagName resolves a llvmAttr.flags project or runtime flag to its name.
|
||||
func llvmFlagName(flag int) string {
|
||||
switch flag {
|
||||
case llvmProjectClang:
|
||||
return "clang"
|
||||
case llvmProjectLld:
|
||||
return "lld"
|
||||
|
||||
case llvmRuntimeCompilerRT:
|
||||
return "compiler-rt"
|
||||
case llvmRuntimeLibunwind:
|
||||
return "libunwind"
|
||||
case llvmRuntimeLibc:
|
||||
return "libc"
|
||||
case llvmRuntimeLibcxx:
|
||||
return "libcxx"
|
||||
case llvmRuntimeLibcxxABI:
|
||||
return "libcxxabi"
|
||||
|
||||
default:
|
||||
panic("invalid flag " + strconv.Itoa(flag))
|
||||
ID: 1830,
|
||||
}
|
||||
}
|
||||
|
||||
// newLLVMVariant returns a [pkg.Artifact] containing a LLVM variant.
|
||||
func (t Toolchain) newLLVMVariant(variant string, attr *llvmAttr) pkg.Artifact {
|
||||
|
||||
if attr == nil {
|
||||
panic("LLVM attr must be non-nil")
|
||||
}
|
||||
|
||||
var projects, runtimes []string
|
||||
for i := 1; i < llvmProjectAll; i <<= 1 {
|
||||
if attr.flags&i != 0 {
|
||||
projects = append(projects, llvmFlagName(i))
|
||||
}
|
||||
}
|
||||
for i := (llvmProjectAll + 1) << 1; i < llvmRuntimeAll; i <<= 1 {
|
||||
if attr.flags&i != 0 {
|
||||
runtimes = append(runtimes, llvmFlagName(i))
|
||||
}
|
||||
}
|
||||
|
||||
var script string
|
||||
|
||||
cache := []KV{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
|
||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
}
|
||||
if len(projects) > 0 {
|
||||
cache = append(cache, []KV{
|
||||
{"LLVM_ENABLE_PROJECTS", `"${ROSA_LLVM_PROJECTS}"`},
|
||||
}...)
|
||||
}
|
||||
if len(runtimes) > 0 {
|
||||
cache = append(cache, []KV{
|
||||
{"LLVM_ENABLE_RUNTIMES", `"${ROSA_LLVM_RUNTIMES}"`},
|
||||
}...)
|
||||
}
|
||||
|
||||
cmakeAppend := []string{"llvm"}
|
||||
if attr.append != nil {
|
||||
cmakeAppend = attr.append
|
||||
} else {
|
||||
cache = append(cache, []KV{
|
||||
{"LLVM_ENABLE_LIBCXX", "ON"},
|
||||
{"LLVM_USE_LINKER", "lld"},
|
||||
|
||||
{"LLVM_INSTALL_BINUTILS_SYMLINKS", "ON"},
|
||||
{"LLVM_INSTALL_CCTOOLS_SYMLINKS", "ON"},
|
||||
|
||||
{"LLVM_LIT_ARGS", "'--verbose'"},
|
||||
}...)
|
||||
}
|
||||
|
||||
if attr.flags&llvmProjectClang != 0 {
|
||||
cache = append(cache, []KV{
|
||||
{"CLANG_DEFAULT_LINKER", "lld"},
|
||||
{"CLANG_DEFAULT_CXX_STDLIB", "libc++"},
|
||||
{"CLANG_DEFAULT_RTLIB", "compiler-rt"},
|
||||
{"CLANG_DEFAULT_UNWINDLIB", "libunwind"},
|
||||
}...)
|
||||
}
|
||||
if attr.flags&llvmProjectLld != 0 {
|
||||
script += `
|
||||
ln -s ld.lld /work/system/bin/ld
|
||||
`
|
||||
}
|
||||
if attr.flags&llvmRuntimeCompilerRT != 0 {
|
||||
if attr.append == nil {
|
||||
cache = append(cache, []KV{
|
||||
{"COMPILER_RT_USE_LLVM_UNWINDER", "ON"},
|
||||
}...)
|
||||
}
|
||||
}
|
||||
if attr.flags&llvmRuntimeLibunwind != 0 {
|
||||
cache = append(cache, []KV{
|
||||
{"LIBUNWIND_USE_COMPILER_RT", "ON"},
|
||||
}...)
|
||||
}
|
||||
if attr.flags&llvmRuntimeLibcxx != 0 {
|
||||
cache = append(cache, []KV{
|
||||
{"LIBCXX_HAS_MUSL_LIBC", "ON"},
|
||||
{"LIBCXX_USE_COMPILER_RT", "ON"},
|
||||
}...)
|
||||
}
|
||||
if attr.flags&llvmRuntimeLibcxxABI != 0 {
|
||||
cache = append(cache, []KV{
|
||||
{"LIBCXXABI_USE_COMPILER_RT", "ON"},
|
||||
{"LIBCXXABI_USE_LLVM_UNWINDER", "ON"},
|
||||
}...)
|
||||
}
|
||||
|
||||
return t.NewPackage("llvm", llvmVersion, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/llvm/llvm-project/archive/refs/tags/"+
|
||||
"llvmorg-"+llvmVersion+".tar.gz",
|
||||
mustDecode(llvmChecksum),
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Patches: attr.patches,
|
||||
NonStage0: attr.nonStage0,
|
||||
|
||||
Env: slices.Concat([]string{
|
||||
"ROSA_LLVM_PROJECTS=" + strings.Join(projects, ";"),
|
||||
"ROSA_LLVM_RUNTIMES=" + strings.Join(runtimes, ";"),
|
||||
}, attr.env),
|
||||
|
||||
Paths: attr.paths,
|
||||
Flag: TExclusive,
|
||||
}, &CMakeHelper{
|
||||
Variant: variant,
|
||||
|
||||
Cache: slices.Concat(cache, attr.cmake),
|
||||
Append: cmakeAppend,
|
||||
Script: script + attr.script,
|
||||
},
|
||||
Python,
|
||||
Perl,
|
||||
Diffutils,
|
||||
Bash,
|
||||
Gawk,
|
||||
Coreutils,
|
||||
Findutils,
|
||||
|
||||
KernelHeaders,
|
||||
)
|
||||
}
|
||||
|
||||
// newLLVM returns LLVM toolchain across multiple [pkg.Artifact].
|
||||
func (t Toolchain) newLLVM() (musl, compilerRT, runtimes, clang pkg.Artifact) {
|
||||
var target string
|
||||
switch runtime.GOARCH {
|
||||
case "386", "amd64":
|
||||
target = "X86"
|
||||
case "arm64":
|
||||
target = "AArch64"
|
||||
case "riscv64":
|
||||
target = "RISCV"
|
||||
|
||||
default:
|
||||
panic("unsupported target " + runtime.GOARCH)
|
||||
}
|
||||
|
||||
minimalDeps := []KV{
|
||||
{"LLVM_ENABLE_ZLIB", "OFF"},
|
||||
{"LLVM_ENABLE_ZSTD", "OFF"},
|
||||
{"LLVM_ENABLE_LIBXML2", "OFF"},
|
||||
}
|
||||
|
||||
muslHeaders, _ := t.newMusl(true, []string{
|
||||
"CC=clang",
|
||||
})
|
||||
|
||||
compilerRT = t.newLLVMVariant("compiler-rt", &llvmAttr{
|
||||
env: stage0ExclConcat(t, []string{},
|
||||
func (t Toolchain) newCompilerRT() (pkg.Artifact, string) {
|
||||
muslHeaders, _ := t.newMusl(true)
|
||||
return t.NewPackage("compiler-rt", llvmVersion, t.Load(llvmSource), &PackageAttr{
|
||||
NonStage0: []pkg.Artifact{
|
||||
muslHeaders,
|
||||
},
|
||||
Env: stage0ExclConcat(t, []string{},
|
||||
"LDFLAGS="+earlyLDFLAGS(false),
|
||||
),
|
||||
cmake: []KV{
|
||||
Flag: TExclusive,
|
||||
}, &CMakeHelper{
|
||||
Append: []string{"compiler-rt"},
|
||||
|
||||
Cache: []KV{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
|
||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
|
||||
// libc++ not yet available
|
||||
{"CMAKE_CXX_COMPILER_TARGET", ""},
|
||||
|
||||
{"COMPILER_RT_BUILD_BUILTINS", "ON"},
|
||||
{"COMPILER_RT_DEFAULT_TARGET_ONLY", "ON"},
|
||||
{"COMPILER_RT_DEFAULT_TARGET_ONLY", "OFF"},
|
||||
{"COMPILER_RT_SANITIZERS_TO_BUILD", "asan"},
|
||||
{"LLVM_ENABLE_PER_TARGET_RUNTIME_DIR", "ON"},
|
||||
|
||||
@@ -244,11 +53,7 @@ func (t Toolchain) newLLVM() (musl, compilerRT, runtimes, clang pkg.Artifact) {
|
||||
{"COMPILER_RT_BUILD_PROFILE", "OFF"},
|
||||
{"COMPILER_RT_BUILD_XRAY", "OFF"},
|
||||
},
|
||||
append: []string{"compiler-rt"},
|
||||
nonStage0: []pkg.Artifact{
|
||||
muslHeaders,
|
||||
},
|
||||
script: `
|
||||
Script: `
|
||||
mkdir -p "/work/system/lib/clang/` + llvmVersionMajor + `/lib/"
|
||||
ln -s \
|
||||
"../../../${ROSA_TRIPLE}" \
|
||||
@@ -261,286 +66,179 @@ ln -s \
|
||||
"clang_rt.crtend-` + linuxArch() + `.o" \
|
||||
"/work/system/lib/${ROSA_TRIPLE}/crtendS.o"
|
||||
`,
|
||||
})
|
||||
|
||||
musl, _ = t.newMusl(false, stage0ExclConcat(t, []string{
|
||||
"CC=clang",
|
||||
"LIBCC=/system/lib/clang/" + llvmVersionMajor + "/lib/" +
|
||||
triplet() + "/libclang_rt.builtins.a",
|
||||
"AR=ar",
|
||||
"RANLIB=ranlib",
|
||||
},
|
||||
"LDFLAGS="+earlyLDFLAGS(false),
|
||||
), compilerRT)
|
||||
Python,
|
||||
|
||||
runtimes = t.newLLVMVariant("runtimes", &llvmAttr{
|
||||
env: stage0ExclConcat(t, []string{},
|
||||
KernelHeaders,
|
||||
), llvmVersion
|
||||
}
|
||||
func init() {
|
||||
artifactsM[CompilerRT] = Metadata{
|
||||
f: Toolchain.newCompilerRT,
|
||||
|
||||
Name: "compiler-rt",
|
||||
Description: "LLVM runtime: compiler-rt",
|
||||
Website: "https://llvm.org/",
|
||||
|
||||
Dependencies: P{
|
||||
Musl,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLLVMRuntimes() (pkg.Artifact, string) {
|
||||
return t.NewPackage("llvm-runtimes", llvmVersion, t.Load(llvmSource), &PackageAttr{
|
||||
NonStage0: t.AppendPresets(nil, CompilerRT),
|
||||
Env: stage0ExclConcat(t, []string{},
|
||||
"LDFLAGS="+earlyLDFLAGS(false),
|
||||
),
|
||||
flags: llvmRuntimeLibunwind | llvmRuntimeLibcxx | llvmRuntimeLibcxxABI,
|
||||
cmake: slices.Concat([]KV{
|
||||
Flag: TExclusive,
|
||||
}, &CMakeHelper{
|
||||
Append: []string{"runtimes"},
|
||||
|
||||
Cache: []KV{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
|
||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
{"LLVM_ENABLE_RUNTIMES", "'libunwind;libcxx;libcxxabi'"},
|
||||
|
||||
{"LIBUNWIND_USE_COMPILER_RT", "ON"},
|
||||
{"LIBCXX_HAS_MUSL_LIBC", "ON"},
|
||||
{"LIBCXX_USE_COMPILER_RT", "ON"},
|
||||
{"LIBCXXABI_USE_COMPILER_RT", "ON"},
|
||||
{"LIBCXXABI_USE_LLVM_UNWINDER", "ON"},
|
||||
|
||||
// libc++ not yet available
|
||||
{"CMAKE_CXX_COMPILER_WORKS", "ON"},
|
||||
|
||||
{"LIBCXX_HAS_ATOMIC_LIB", "OFF"},
|
||||
{"LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL", "OFF"},
|
||||
}, minimalDeps),
|
||||
append: []string{"runtimes"},
|
||||
nonStage0: []pkg.Artifact{
|
||||
compilerRT,
|
||||
musl,
|
||||
|
||||
{"LLVM_ENABLE_ZLIB", "OFF"},
|
||||
{"LLVM_ENABLE_ZSTD", "OFF"},
|
||||
{"LLVM_ENABLE_LIBXML2", "OFF"},
|
||||
},
|
||||
})
|
||||
},
|
||||
Python,
|
||||
|
||||
clang = t.newLLVMVariant("clang", &llvmAttr{
|
||||
flags: llvmProjectClang | llvmProjectLld,
|
||||
env: stage0ExclConcat(t, []string{},
|
||||
"CFLAGS="+earlyCFLAGS,
|
||||
"CXXFLAGS="+earlyCXXFLAGS(),
|
||||
"LDFLAGS="+earlyLDFLAGS(false),
|
||||
),
|
||||
cmake: slices.Concat([]KV{
|
||||
{"LLVM_TARGETS_TO_BUILD", target},
|
||||
{"CMAKE_CROSSCOMPILING", "OFF"},
|
||||
{"CXX_SUPPORTS_CUSTOM_LINKER", "ON"},
|
||||
}, minimalDeps),
|
||||
nonStage0: []pkg.Artifact{
|
||||
musl,
|
||||
compilerRT,
|
||||
runtimes,
|
||||
},
|
||||
script: `
|
||||
ln -s clang /work/system/bin/cc
|
||||
ln -s clang++ /work/system/bin/c++
|
||||
|
||||
ninja check-all
|
||||
`,
|
||||
|
||||
patches: slices.Concat([]KV{
|
||||
{"add-rosa-vendor", `diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
|
||||
index 9c83abeeb3b1..5acfe5836a23 100644
|
||||
--- a/llvm/include/llvm/TargetParser/Triple.h
|
||||
+++ b/llvm/include/llvm/TargetParser/Triple.h
|
||||
@@ -190,6 +190,7 @@ public:
|
||||
|
||||
Apple,
|
||||
PC,
|
||||
+ Rosa,
|
||||
SCEI,
|
||||
Freescale,
|
||||
IBM,
|
||||
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
|
||||
index a4f9dd42c0fe..cb5a12387034 100644
|
||||
--- a/llvm/lib/TargetParser/Triple.cpp
|
||||
+++ b/llvm/lib/TargetParser/Triple.cpp
|
||||
@@ -279,6 +279,7 @@ StringRef Triple::getVendorTypeName(VendorType Kind) {
|
||||
case NVIDIA: return "nvidia";
|
||||
case OpenEmbedded: return "oe";
|
||||
case PC: return "pc";
|
||||
+ case Rosa: return "rosa";
|
||||
case SCEI: return "scei";
|
||||
case SUSE: return "suse";
|
||||
case Meta:
|
||||
@@ -689,6 +690,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) {
|
||||
return StringSwitch<Triple::VendorType>(VendorName)
|
||||
.Case("apple", Triple::Apple)
|
||||
.Case("pc", Triple::PC)
|
||||
+ .Case("rosa", Triple::Rosa)
|
||||
.Case("scei", Triple::SCEI)
|
||||
.Case("sie", Triple::SCEI)
|
||||
.Case("fsl", Triple::Freescale)
|
||||
`},
|
||||
|
||||
{"xfail-broken-tests", `diff --git a/clang/test/Modules/timestamps.c b/clang/test/Modules/timestamps.c
|
||||
index 50fdce630255..4b4465a75617 100644
|
||||
--- a/clang/test/Modules/timestamps.c
|
||||
+++ b/clang/test/Modules/timestamps.c
|
||||
@@ -1,3 +1,5 @@
|
||||
+// XFAIL: target={{.*-rosa-linux-musl}}
|
||||
+
|
||||
/// Verify timestamps that gets embedded in the module
|
||||
#include <c-header.h>
|
||||
|
||||
`},
|
||||
|
||||
{"path-system-include", `diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
index 8ac8d4eb9181..e46b04a898ca 100644
|
||||
--- a/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
@@ -671,6 +671,12 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
addExternCSystemInclude(
|
||||
DriverArgs, CC1Args,
|
||||
concat(SysRoot, "/usr/include", MultiarchIncludeDir));
|
||||
+ if (!MultiarchIncludeDir.empty() &&
|
||||
+ D.getVFS().exists(concat(SysRoot, "/system/include", MultiarchIncludeDir)))
|
||||
+ addExternCSystemInclude(
|
||||
+ DriverArgs, CC1Args,
|
||||
+ concat(SysRoot, "/system/include", MultiarchIncludeDir));
|
||||
+
|
||||
|
||||
if (getTriple().getOS() == llvm::Triple::RTEMS)
|
||||
return;
|
||||
@@ -681,6 +687,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include"));
|
||||
|
||||
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include"));
|
||||
+ addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/system/include"));
|
||||
|
||||
if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl())
|
||||
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
|
||||
`},
|
||||
|
||||
{"path-system-libraries", `diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
index 8ac8d4eb9181..f4d1347ab64d 100644
|
||||
--- a/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
@@ -282,6 +282,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||
const bool IsHexagon = Arch == llvm::Triple::hexagon;
|
||||
const bool IsRISCV = Triple.isRISCV();
|
||||
const bool IsCSKY = Triple.isCSKY();
|
||||
+ const bool IsRosa = Triple.getVendor() == llvm::Triple::Rosa;
|
||||
|
||||
if (IsCSKY && !SelectedMultilibs.empty())
|
||||
SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
|
||||
@@ -318,12 +319,23 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||
const std::string OSLibDir = std::string(getOSLibDir(Triple, Args));
|
||||
const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
|
||||
|
||||
+ if (IsRosa) {
|
||||
+ ExtraOpts.push_back("-rpath");
|
||||
+ ExtraOpts.push_back("/system/lib");
|
||||
+ ExtraOpts.push_back("-rpath");
|
||||
+ ExtraOpts.push_back(concat("/system/lib", MultiarchTriple));
|
||||
+ }
|
||||
+
|
||||
// mips32: Debian multilib, we use /libo32, while in other case, /lib is
|
||||
// used. We need add both libo32 and /lib.
|
||||
if (Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel) {
|
||||
Generic_GCC::AddMultilibPaths(D, SysRoot, "libo32", MultiarchTriple, Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/libo32"), Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr/libo32"), Paths);
|
||||
+ if (!IsRosa) {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/libo32"), Paths);
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr/libo32"), Paths);
|
||||
+ } else {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system/libo32"), Paths);
|
||||
+ }
|
||||
}
|
||||
Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths);
|
||||
|
||||
@@ -341,18 +353,30 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||
Paths);
|
||||
}
|
||||
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);
|
||||
+ if (!IsRosa) {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths);
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);
|
||||
+ } else {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system/lib", MultiarchTriple), Paths);
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system", OSLibDir), Paths);
|
||||
+ }
|
||||
if (IsRISCV) {
|
||||
StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
|
||||
addPathIfExists(D, concat(SysRoot, "/", OSLibDir, ABIName), Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir, ABIName), Paths);
|
||||
+ if (!IsRosa)
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir, ABIName), Paths);
|
||||
+ else
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system", OSLibDir, ABIName), Paths);
|
||||
}
|
||||
|
||||
Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths);
|
||||
|
||||
- addPathIfExists(D, concat(SysRoot, "/lib"), Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths);
|
||||
+ if (!IsRosa) {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/lib"), Paths);
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths);
|
||||
+ } else {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system/lib"), Paths);
|
||||
+ }
|
||||
}
|
||||
|
||||
ToolChain::RuntimeLibType Linux::GetDefaultRuntimeLibType() const {
|
||||
@@ -457,6 +481,9 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
|
||||
return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
|
||||
}
|
||||
if (Triple.isMusl()) {
|
||||
+ if (Triple.getVendor() == llvm::Triple::Rosa)
|
||||
+ return "/system/bin/linker";
|
||||
+
|
||||
std::string ArchName;
|
||||
bool IsArm = false;
|
||||
|
||||
diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp
|
||||
index 64324a3f8b01..15ce70b68217 100644
|
||||
--- a/clang/tools/clang-installapi/Options.cpp
|
||||
+++ b/clang/tools/clang-installapi/Options.cpp
|
||||
@@ -515,7 +515,7 @@ bool Options::processFrontendOptions(InputArgList &Args) {
|
||||
FEOpts.FwkPaths = std::move(FrameworkPaths);
|
||||
|
||||
// Add default framework/library paths.
|
||||
- PathSeq DefaultLibraryPaths = {"/usr/lib", "/usr/local/lib"};
|
||||
+ PathSeq DefaultLibraryPaths = {"/usr/lib", "/system/lib", "/usr/local/lib"};
|
||||
PathSeq DefaultFrameworkPaths = {"/Library/Frameworks",
|
||||
"/System/Library/Frameworks"};
|
||||
|
||||
`},
|
||||
}, clangPatches),
|
||||
})
|
||||
|
||||
return
|
||||
KernelHeaders,
|
||||
), llvmVersion
|
||||
}
|
||||
func init() {
|
||||
artifactsM[LLVMCompilerRT] = Metadata{
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
_, compilerRT, _, _ := t.newLLVM()
|
||||
return compilerRT, llvmVersion
|
||||
},
|
||||
|
||||
Name: "llvm-compiler-rt",
|
||||
Description: "LLVM runtime: compiler-rt",
|
||||
Website: "https://llvm.org/",
|
||||
}
|
||||
|
||||
artifactsM[LLVMRuntimes] = Metadata{
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
_, _, runtimes, _ := t.newLLVM()
|
||||
return runtimes, llvmVersion
|
||||
},
|
||||
f: Toolchain.newLLVMRuntimes,
|
||||
|
||||
Name: "llvm-runtimes",
|
||||
Description: "LLVM runtimes: libunwind, libcxx, libcxxabi",
|
||||
Website: "https://llvm.org/",
|
||||
|
||||
Dependencies: P{
|
||||
CompilerRT,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newClang() (pkg.Artifact, string) {
|
||||
target := "'AArch64;RISCV;X86'"
|
||||
if t.isStage0() {
|
||||
target = "Native"
|
||||
}
|
||||
|
||||
artifactsM[LLVMClang] = Metadata{
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
_, _, _, clang := t.newLLVM()
|
||||
return clang, llvmVersion
|
||||
return t.NewPackage("clang", llvmVersion, t.Load(llvmSource), &PackageAttr{
|
||||
NonStage0: t.AppendPresets(nil, LLVMRuntimes),
|
||||
Env: stage0ExclConcat(t, []string{},
|
||||
"CFLAGS="+earlyCFLAGS,
|
||||
"CXXFLAGS="+earlyCXXFLAGS(),
|
||||
"LDFLAGS="+earlyLDFLAGS(false),
|
||||
),
|
||||
Flag: TExclusive,
|
||||
}, &CMakeHelper{
|
||||
Append: []string{"llvm"},
|
||||
|
||||
Cache: []KV{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
|
||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
{"LLVM_ENABLE_PROJECTS", "'clang;lld'"},
|
||||
|
||||
{"LLVM_ENABLE_LIBCXX", "ON"},
|
||||
{"LLVM_USE_LINKER", "lld"},
|
||||
|
||||
{"LLVM_INSTALL_BINUTILS_SYMLINKS", "ON"},
|
||||
{"LLVM_INSTALL_CCTOOLS_SYMLINKS", "ON"},
|
||||
|
||||
{"LLVM_LIT_ARGS", "'--verbose'"},
|
||||
|
||||
{"CLANG_DEFAULT_LINKER", "lld"},
|
||||
{"CLANG_DEFAULT_CXX_STDLIB", "libc++"},
|
||||
{"CLANG_DEFAULT_RTLIB", "compiler-rt"},
|
||||
{"CLANG_DEFAULT_UNWINDLIB", "libunwind"},
|
||||
|
||||
{"LLVM_TARGETS_TO_BUILD", target},
|
||||
{"CMAKE_CROSSCOMPILING", "OFF"},
|
||||
{"CXX_SUPPORTS_CUSTOM_LINKER", "ON"},
|
||||
|
||||
{"LLVM_ENABLE_ZLIB", "OFF"},
|
||||
{"LLVM_ENABLE_ZSTD", "OFF"},
|
||||
{"LLVM_ENABLE_LIBXML2", "OFF"},
|
||||
},
|
||||
Script: `
|
||||
ln -s ld.lld /work/system/bin/ld
|
||||
|
||||
ln -s clang /work/system/bin/cc
|
||||
ln -s clang++ /work/system/bin/c++
|
||||
|
||||
ninja ` + jobsFlagE + ` check-all
|
||||
`,
|
||||
},
|
||||
Python,
|
||||
Perl,
|
||||
Diffutils,
|
||||
Bash,
|
||||
Gawk,
|
||||
Coreutils,
|
||||
Findutils,
|
||||
|
||||
KernelHeaders,
|
||||
), llvmVersion
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Clang] = Metadata{
|
||||
f: Toolchain.newClang,
|
||||
|
||||
Name: "clang",
|
||||
Description: `an "LLVM native" C/C++/Objective-C compiler`,
|
||||
Website: "https://llvm.org/",
|
||||
|
||||
ID: 1830,
|
||||
Dependencies: P{
|
||||
LLVMRuntimes,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// llvm stores the result of Toolchain.newLLVM.
|
||||
llvm [_toolchainEnd][4]pkg.Artifact
|
||||
// llvmOnce is for lazy initialisation of llvm.
|
||||
llvmOnce [_toolchainEnd]sync.Once
|
||||
)
|
||||
func (t Toolchain) newLibclc() (pkg.Artifact, string) {
|
||||
return t.NewPackage("libclc", llvmVersion, t.Load(llvmSource), nil, &CMakeHelper{
|
||||
Append: []string{"libclc"},
|
||||
|
||||
// NewLLVM returns LLVM toolchain across multiple [pkg.Artifact].
|
||||
func (t Toolchain) NewLLVM() (musl, compilerRT, runtimes, clang pkg.Artifact) {
|
||||
llvmOnce[t].Do(func() {
|
||||
llvm[t][0], llvm[t][1], llvm[t][2], llvm[t][3] = t.newLLVM()
|
||||
})
|
||||
return llvm[t][0], llvm[t][1], llvm[t][2], llvm[t][3]
|
||||
Cache: []KV{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
|
||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||
|
||||
{"LIBCLC_TARGETS_TO_BUILD", "all"},
|
||||
},
|
||||
Script: "ninja " + jobsFlagE + " test",
|
||||
}), llvmVersion
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Libclc] = Metadata{
|
||||
f: Toolchain.newLibclc,
|
||||
|
||||
Name: "libclc",
|
||||
Description: "an open source, BSD/MIT dual licensed implementation of the library requirements of the OpenCL C programming language",
|
||||
Website: "https://libclc.llvm.org/",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package rosa
|
||||
|
||||
// clangPatches are patches applied to the LLVM source tree for building clang.
|
||||
var clangPatches []KV
|
||||
@@ -1,12 +0,0 @@
|
||||
package rosa
|
||||
|
||||
// clangPatches are patches applied to the LLVM source tree for building clang.
|
||||
var clangPatches []KV
|
||||
|
||||
// one version behind, latest fails 5 tests with 2 flaky on arm64
|
||||
const (
|
||||
llvmVersionMajor = "21"
|
||||
llvmVersion = llvmVersionMajor + ".1.8"
|
||||
|
||||
llvmChecksum = "8SUpqDkcgwOPsqHVtmf9kXfFeVmjVxl4LMn-qSE1AI_Xoeju-9HaoPNGtidyxyka"
|
||||
)
|
||||
@@ -1,11 +1,9 @@
|
||||
//go:build !arm64
|
||||
|
||||
package rosa
|
||||
|
||||
// latest version of LLVM, conditional to temporarily avoid broken new releases
|
||||
const (
|
||||
llvmVersionMajor = "22"
|
||||
llvmVersion = llvmVersionMajor + ".1.2"
|
||||
llvmVersion = llvmVersionMajor + ".1.3"
|
||||
|
||||
llvmChecksum = "FwsmurWDVyYYQlOowowFjekwIGSB5__aKTpW_VGP3eWoZGXvBny-bOn1DuQ1U5xE"
|
||||
llvmChecksum = "CUwnpzua_y28HZ9oI0NmcKL2wClsSjFpgY9do5-7cCZJHI5KNF64vfwGvY0TYyR3"
|
||||
)
|
||||
|
||||
191
internal/rosa/llvm_patches_latest.go
Normal file
191
internal/rosa/llvm_patches_latest.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package rosa
|
||||
|
||||
// llvmPatches are centralised patches against latest LLVM monorepo.
|
||||
var llvmPatches = []KV{
|
||||
{"increase-stack-size-unconditional", `diff --git a/llvm/lib/Support/Threading.cpp b/llvm/lib/Support/Threading.cpp
|
||||
index 9da357a7ebb9..b2931510c1ae 100644
|
||||
--- a/llvm/lib/Support/Threading.cpp
|
||||
+++ b/llvm/lib/Support/Threading.cpp
|
||||
@@ -80,7 +80,7 @@ unsigned llvm::ThreadPoolStrategy::compute_thread_count() const {
|
||||
// keyword.
|
||||
#include "llvm/Support/thread.h"
|
||||
|
||||
-#if defined(__APPLE__)
|
||||
+#if defined(__APPLE__) || 1
|
||||
// Darwin's default stack size for threads except the main one is only 512KB,
|
||||
// which is not enough for some/many normal LLVM compilations. This implements
|
||||
// the same interface as std::thread but requests the same stack size as the
|
||||
`},
|
||||
|
||||
{"add-rosa-vendor", `diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
|
||||
index 9c83abeeb3b1..5acfe5836a23 100644
|
||||
--- a/llvm/include/llvm/TargetParser/Triple.h
|
||||
+++ b/llvm/include/llvm/TargetParser/Triple.h
|
||||
@@ -190,6 +190,7 @@ public:
|
||||
|
||||
Apple,
|
||||
PC,
|
||||
+ Rosa,
|
||||
SCEI,
|
||||
Freescale,
|
||||
IBM,
|
||||
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
|
||||
index a4f9dd42c0fe..cb5a12387034 100644
|
||||
--- a/llvm/lib/TargetParser/Triple.cpp
|
||||
+++ b/llvm/lib/TargetParser/Triple.cpp
|
||||
@@ -279,6 +279,7 @@ StringRef Triple::getVendorTypeName(VendorType Kind) {
|
||||
case NVIDIA: return "nvidia";
|
||||
case OpenEmbedded: return "oe";
|
||||
case PC: return "pc";
|
||||
+ case Rosa: return "rosa";
|
||||
case SCEI: return "scei";
|
||||
case SUSE: return "suse";
|
||||
case Meta:
|
||||
@@ -689,6 +690,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) {
|
||||
return StringSwitch<Triple::VendorType>(VendorName)
|
||||
.Case("apple", Triple::Apple)
|
||||
.Case("pc", Triple::PC)
|
||||
+ .Case("rosa", Triple::Rosa)
|
||||
.Case("scei", Triple::SCEI)
|
||||
.Case("sie", Triple::SCEI)
|
||||
.Case("fsl", Triple::Freescale)
|
||||
`},
|
||||
|
||||
{"xfail-broken-tests", `diff --git a/clang/test/Modules/timestamps.c b/clang/test/Modules/timestamps.c
|
||||
index 50fdce630255..4b4465a75617 100644
|
||||
--- a/clang/test/Modules/timestamps.c
|
||||
+++ b/clang/test/Modules/timestamps.c
|
||||
@@ -1,3 +1,5 @@
|
||||
+// XFAIL: target={{.*-rosa-linux-musl}}
|
||||
+
|
||||
/// Verify timestamps that gets embedded in the module
|
||||
#include <c-header.h>
|
||||
|
||||
`},
|
||||
|
||||
{"path-system-include", `diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
index 8ac8d4eb9181..e46b04a898ca 100644
|
||||
--- a/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
@@ -671,6 +671,12 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
addExternCSystemInclude(
|
||||
DriverArgs, CC1Args,
|
||||
concat(SysRoot, "/usr/include", MultiarchIncludeDir));
|
||||
+ if (!MultiarchIncludeDir.empty() &&
|
||||
+ D.getVFS().exists(concat(SysRoot, "/system/include", MultiarchIncludeDir)))
|
||||
+ addExternCSystemInclude(
|
||||
+ DriverArgs, CC1Args,
|
||||
+ concat(SysRoot, "/system/include", MultiarchIncludeDir));
|
||||
+
|
||||
|
||||
if (getTriple().getOS() == llvm::Triple::RTEMS)
|
||||
return;
|
||||
@@ -681,6 +687,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include"));
|
||||
|
||||
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include"));
|
||||
+ addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/system/include"));
|
||||
|
||||
if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl())
|
||||
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
|
||||
`},
|
||||
|
||||
{"path-system-libraries", `diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
index 8ac8d4eb9181..f4d1347ab64d 100644
|
||||
--- a/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||
@@ -282,6 +282,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||
const bool IsHexagon = Arch == llvm::Triple::hexagon;
|
||||
const bool IsRISCV = Triple.isRISCV();
|
||||
const bool IsCSKY = Triple.isCSKY();
|
||||
+ const bool IsRosa = Triple.getVendor() == llvm::Triple::Rosa;
|
||||
|
||||
if (IsCSKY && !SelectedMultilibs.empty())
|
||||
SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
|
||||
@@ -318,12 +319,23 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||
const std::string OSLibDir = std::string(getOSLibDir(Triple, Args));
|
||||
const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
|
||||
|
||||
+ if (IsRosa) {
|
||||
+ ExtraOpts.push_back("-rpath");
|
||||
+ ExtraOpts.push_back("/system/lib");
|
||||
+ ExtraOpts.push_back("-rpath");
|
||||
+ ExtraOpts.push_back(concat("/system/lib", MultiarchTriple));
|
||||
+ }
|
||||
+
|
||||
// mips32: Debian multilib, we use /libo32, while in other case, /lib is
|
||||
// used. We need add both libo32 and /lib.
|
||||
if (Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel) {
|
||||
Generic_GCC::AddMultilibPaths(D, SysRoot, "libo32", MultiarchTriple, Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/libo32"), Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr/libo32"), Paths);
|
||||
+ if (!IsRosa) {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/libo32"), Paths);
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr/libo32"), Paths);
|
||||
+ } else {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system/libo32"), Paths);
|
||||
+ }
|
||||
}
|
||||
Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths);
|
||||
|
||||
@@ -341,18 +353,30 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||
Paths);
|
||||
}
|
||||
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);
|
||||
+ if (!IsRosa) {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths);
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);
|
||||
+ } else {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system/lib", MultiarchTriple), Paths);
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system", OSLibDir), Paths);
|
||||
+ }
|
||||
if (IsRISCV) {
|
||||
StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
|
||||
addPathIfExists(D, concat(SysRoot, "/", OSLibDir, ABIName), Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir, ABIName), Paths);
|
||||
+ if (!IsRosa)
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir, ABIName), Paths);
|
||||
+ else
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system", OSLibDir, ABIName), Paths);
|
||||
}
|
||||
|
||||
Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths);
|
||||
|
||||
- addPathIfExists(D, concat(SysRoot, "/lib"), Paths);
|
||||
- addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths);
|
||||
+ if (!IsRosa) {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/lib"), Paths);
|
||||
+ addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths);
|
||||
+ } else {
|
||||
+ addPathIfExists(D, concat(SysRoot, "/system/lib"), Paths);
|
||||
+ }
|
||||
}
|
||||
|
||||
ToolChain::RuntimeLibType Linux::GetDefaultRuntimeLibType() const {
|
||||
@@ -457,6 +481,9 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
|
||||
return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
|
||||
}
|
||||
if (Triple.isMusl()) {
|
||||
+ if (Triple.getVendor() == llvm::Triple::Rosa)
|
||||
+ return "/system/bin/linker";
|
||||
+
|
||||
std::string ArchName;
|
||||
bool IsArm = false;
|
||||
|
||||
diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp
|
||||
index 64324a3f8b01..15ce70b68217 100644
|
||||
--- a/clang/tools/clang-installapi/Options.cpp
|
||||
+++ b/clang/tools/clang-installapi/Options.cpp
|
||||
@@ -515,7 +515,7 @@ bool Options::processFrontendOptions(InputArgList &Args) {
|
||||
FEOpts.FwkPaths = std::move(FrameworkPaths);
|
||||
|
||||
// Add default framework/library paths.
|
||||
- PathSeq DefaultLibraryPaths = {"/usr/lib", "/usr/local/lib"};
|
||||
+ PathSeq DefaultLibraryPaths = {"/usr/lib", "/system/lib", "/usr/local/lib"};
|
||||
PathSeq DefaultFrameworkPaths = {"/Library/Frameworks",
|
||||
"/System/Library/Frameworks"};
|
||||
|
||||
`},
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package rosa
|
||||
|
||||
// clangPatches are patches applied to the LLVM source tree for building clang.
|
||||
var clangPatches []KV
|
||||
@@ -20,9 +20,9 @@ cd "$(mktemp -d)"
|
||||
--disable-dependency-tracking
|
||||
./build.sh
|
||||
./make DESTDIR=/work install check
|
||||
`, pkg.Path(AbsUsrSrc.Append("make"), false, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/make/make-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
`, pkg.Path(AbsUsrSrc.Append("make"), false, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/make/make-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
))), version
|
||||
}
|
||||
@@ -78,11 +78,6 @@ type MakeHelper struct {
|
||||
|
||||
var _ Helper = new(MakeHelper)
|
||||
|
||||
// name returns its arguments joined with '-'.
|
||||
func (*MakeHelper) name(name, version string) string {
|
||||
return name + "-" + version
|
||||
}
|
||||
|
||||
// extra returns make and other optional dependencies.
|
||||
func (attr *MakeHelper) extra(flag int) P {
|
||||
extra := P{Make}
|
||||
@@ -176,7 +171,10 @@ func (attr *MakeHelper) script(name string) string {
|
||||
s = "-" + s
|
||||
}
|
||||
if v[1] != "" {
|
||||
s += "=" + v[1]
|
||||
if v[0] != "" {
|
||||
s += "="
|
||||
}
|
||||
s += v[1]
|
||||
}
|
||||
if !yield(s) {
|
||||
return
|
||||
@@ -190,7 +188,7 @@ func (attr *MakeHelper) script(name string) string {
|
||||
|
||||
scriptMake := `
|
||||
make \
|
||||
"-j$(nproc)"`
|
||||
` + jobsFlagE
|
||||
if len(attr.Make) > 0 {
|
||||
scriptMake += " \\\n\t" + strings.Join(attr.Make, " \\\n\t")
|
||||
}
|
||||
@@ -198,7 +196,7 @@ make \
|
||||
|
||||
if !attr.SkipCheck {
|
||||
scriptMake += attr.ScriptCheckEarly + `make \
|
||||
"-j$(nproc)" \
|
||||
` + jobsFlagE + ` \
|
||||
`
|
||||
if len(attr.Check) > 0 {
|
||||
scriptMake += strings.Join(attr.Check, " \\\n\t")
|
||||
|
||||
66
internal/rosa/mesa.go
Normal file
66
internal/rosa/mesa.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newLibglvnd() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.7.0"
|
||||
checksum = "eIQJK2sgFQDHdeFkQO87TrSUaZRFG4y2DrwA8Ut-sGboI59uw1OOiIVqq2AIwnGY"
|
||||
)
|
||||
return t.NewPackage("libglvnd", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"glvnd/libglvnd",
|
||||
"v"+version,
|
||||
checksum,
|
||||
), nil, (*MesonHelper)(nil),
|
||||
Binutils, // symbols check fail with llvm nm
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Libglvnd] = Metadata{
|
||||
f: Toolchain.newLibglvnd,
|
||||
|
||||
Name: "libglvnd",
|
||||
Description: "The GL Vendor-Neutral Dispatch library",
|
||||
Website: "https://gitlab.freedesktop.org/glvnd/libglvnd",
|
||||
|
||||
ID: 12098,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibdrm() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "2.4.131"
|
||||
checksum = "riHPSpvTnvCPbR-iT4jt7_X-z4rpwm6oNh9ZN2zP6RBFkFVxBRKmedG4eEXSADIh"
|
||||
)
|
||||
return t.NewPackage("libdrm", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"mesa/libdrm",
|
||||
"libdrm-"+version,
|
||||
checksum,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
{"Dintel", "enabled"},
|
||||
},
|
||||
},
|
||||
Binutils, // symbols check fail with llvm nm
|
||||
|
||||
Libpciaccess,
|
||||
KernelHeaders,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Libdrm] = Metadata{
|
||||
f: Toolchain.newLibdrm,
|
||||
|
||||
Name: "libdrm",
|
||||
Description: "a userspace library for accessing the DRM",
|
||||
Website: "https://dri.freedesktop.org/",
|
||||
|
||||
Dependencies: P{
|
||||
Libpciaccess,
|
||||
},
|
||||
|
||||
ID: 1596,
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
|
||||
func (t Toolchain) newMeson() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.10.2"
|
||||
checksum = "18VmKUVKuXCwtawkYCeYHseC3cKpi86OhnIPaV878wjY0rkXH8XnQwUyymnxFgcl"
|
||||
version = "1.11.0"
|
||||
checksum = "b7oo3U_cklhzsTfsyYsjPGyeEufiS-Pm06JPLzodseS125Ach62ZBly7R6dSDiAc"
|
||||
)
|
||||
return t.New("meson-"+version, 0, []pkg.Artifact{
|
||||
t.Load(Zlib),
|
||||
@@ -23,10 +23,11 @@ python3 setup.py \
|
||||
install \
|
||||
--prefix=/system \
|
||||
--root=/work
|
||||
`, pkg.Path(AbsUsrSrc.Append("meson"), true, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/mesonbuild/meson/releases/download/"+
|
||||
version+"/meson-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
`, pkg.Path(AbsUsrSrc.Append("meson"), true, newFromGitHubRelease(
|
||||
"mesonbuild/meson",
|
||||
version,
|
||||
"meson-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
))), version
|
||||
}
|
||||
@@ -66,11 +67,6 @@ type MesonHelper struct {
|
||||
|
||||
var _ Helper = new(MesonHelper)
|
||||
|
||||
// name returns its arguments joined with '-'.
|
||||
func (*MesonHelper) name(name, version string) string {
|
||||
return name + "-" + version
|
||||
}
|
||||
|
||||
// extra returns hardcoded meson runtime dependencies.
|
||||
func (*MesonHelper) extra(int) P { return P{Meson} }
|
||||
|
||||
|
||||
@@ -26,10 +26,9 @@ cp -v lksh /work/system/bin/sh
|
||||
|
||||
mkdir -p /work/bin/
|
||||
ln -vs ../system/bin/sh /work/bin/
|
||||
`, pkg.Path(AbsUsrSrc.Append("mksh"), false, pkg.NewHTTPGetTar(
|
||||
nil,
|
||||
`, pkg.Path(AbsUsrSrc.Append("mksh"), false, newTar(
|
||||
"https://mbsd.evolvis.org/MirOS/dist/mir/mksh/mksh-R"+version+".tgz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
))), version
|
||||
}
|
||||
|
||||
@@ -7,11 +7,10 @@ func (t Toolchain) newMuslFts() (pkg.Artifact, string) {
|
||||
version = "1.2.7"
|
||||
checksum = "N_p_ZApX3eHt7xoDCw1hLf6XdJOw7ZSx7xPvpvAP0knG2zgU0zeN5w8tt5Pg60XJ"
|
||||
)
|
||||
return t.NewPackage("musl-fts", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/void-linux/musl-fts/archive/refs/tags/"+
|
||||
"v"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.NewPackage("musl-fts", version, newFromGitHub(
|
||||
"void-linux/musl-fts",
|
||||
"v"+version,
|
||||
checksum,
|
||||
), &PackageAttr{
|
||||
Env: []string{
|
||||
"CC=cc -fPIC",
|
||||
|
||||
@@ -7,11 +7,10 @@ func (t Toolchain) newMuslObstack() (pkg.Artifact, string) {
|
||||
version = "1.2.3"
|
||||
checksum = "tVRY_KjIlkkMszcaRlkKdBVQHIXTT_T_TiMxbwErlILXrOBosocg8KklppZhNdCG"
|
||||
)
|
||||
return t.NewPackage("musl-obstack", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/void-linux/musl-obstack/archive/refs/tags/"+
|
||||
"v"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.NewPackage("musl-obstack", version, newFromGitHub(
|
||||
"void-linux/musl-obstack",
|
||||
"v"+version,
|
||||
checksum,
|
||||
), &PackageAttr{
|
||||
Env: []string{
|
||||
"CC=cc -fPIC",
|
||||
|
||||
@@ -4,7 +4,6 @@ import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newMusl(
|
||||
headers bool,
|
||||
env []string,
|
||||
extra ...pkg.Artifact,
|
||||
) (pkg.Artifact, string) {
|
||||
const (
|
||||
@@ -37,9 +36,9 @@ rmdir -v /work/lib
|
||||
helper.Script = ""
|
||||
}
|
||||
|
||||
return t.NewPackage(name, version, pkg.NewHTTPGetTar(
|
||||
nil, "https://musl.libc.org/releases/musl-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage(name, version, newTar(
|
||||
"https://musl.libc.org/releases/musl-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
NonStage0: extra,
|
||||
@@ -47,7 +46,15 @@ rmdir -v /work/lib
|
||||
// expected to be writable in copies
|
||||
Chmod: true,
|
||||
|
||||
Env: env,
|
||||
Env: stage0ExclConcat(t, []string{
|
||||
"CC=clang",
|
||||
"LIBCC=/system/lib/clang/" + llvmVersionMajor + "/lib/" +
|
||||
triplet() + "/libclang_rt.builtins.a",
|
||||
"AR=ar",
|
||||
"RANLIB=ranlib",
|
||||
},
|
||||
"LDFLAGS="+earlyLDFLAGS(false),
|
||||
),
|
||||
}, &helper,
|
||||
Coreutils,
|
||||
), version
|
||||
@@ -55,7 +62,7 @@ rmdir -v /work/lib
|
||||
func init() {
|
||||
artifactsM[Musl] = Metadata{
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
return t.newMusl(false, nil)
|
||||
return t.newMusl(false, t.Load(CompilerRT))
|
||||
},
|
||||
|
||||
Name: "musl",
|
||||
|
||||
@@ -7,9 +7,9 @@ func (t Toolchain) newNcurses() (pkg.Artifact, string) {
|
||||
version = "6.6"
|
||||
checksum = "XvWp4xi6hR_hH8XUoGY26L_pqBSDapJYulhzZqPuR0KNklqypqNc1yNXU-nOjf5w"
|
||||
)
|
||||
return t.NewPackage("ncurses", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/ncurses/ncurses-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("ncurses", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/ncurses/ncurses-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MakeHelper{
|
||||
// "tests" are actual demo programs, not a test suite.
|
||||
|
||||
@@ -7,10 +7,10 @@ func (t Toolchain) newLibmnl() (pkg.Artifact, string) {
|
||||
version = "1.0.5"
|
||||
checksum = "DN-vbbvQDpxXJm0TJ6xlluILvfrB86avrCTX50XyE9SEFSAZ_o8nuKc5Gu0Am7-u"
|
||||
)
|
||||
return t.NewPackage("libmnl", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://www.netfilter.org/projects/libmnl/files/"+
|
||||
return t.NewPackage("libmnl", version, newTar(
|
||||
"https://www.netfilter.org/projects/libmnl/files/"+
|
||||
"libmnl-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), &PackageAttr{
|
||||
Patches: []KV{
|
||||
@@ -55,10 +55,9 @@ func (t Toolchain) newLibnftnl() (pkg.Artifact, string) {
|
||||
version = "1.3.1"
|
||||
checksum = "91ou66K-I17iX6DB6hiQkhhC_v4DFW5iDGzwjVRNbJNEmKqowLZBlh3FY-ZDO0r9"
|
||||
)
|
||||
return t.NewPackage("libnftnl", version, t.NewViaGit(
|
||||
return t.NewPackage("libnftnl", version, t.newTagRemote(
|
||||
"https://git.netfilter.org/libnftnl",
|
||||
"refs/tags/libnftnl-"+version,
|
||||
mustDecode(checksum),
|
||||
"libnftnl-"+version, checksum,
|
||||
), &PackageAttr{
|
||||
Env: []string{
|
||||
"CFLAGS=-D_GNU_SOURCE",
|
||||
@@ -98,10 +97,9 @@ func (t Toolchain) newIPTables() (pkg.Artifact, string) {
|
||||
version = "1.8.13"
|
||||
checksum = "TUA-cFIAsiMvtRR-XzQvXzoIhJUOc9J2gQDJCbBRjmgmVfGfPTCf58wL7e-cUKVQ"
|
||||
)
|
||||
return t.NewPackage("iptables", version, t.NewViaGit(
|
||||
return t.NewPackage("iptables", version, t.newTagRemote(
|
||||
"https://git.netfilter.org/iptables",
|
||||
"refs/tags/v"+version,
|
||||
mustDecode(checksum),
|
||||
"v"+version, checksum,
|
||||
), &PackageAttr{
|
||||
ScriptEarly: `
|
||||
rm \
|
||||
|
||||
@@ -7,9 +7,9 @@ func (t Toolchain) newNettle() (pkg.Artifact, string) {
|
||||
version = "4.0"
|
||||
checksum = "6agC-vHzzoqAlaX3K9tX8yHgrm03HLqPZzVzq8jh_ePbuPMIvpxereu_uRJFmQK7"
|
||||
)
|
||||
return t.NewPackage("nettle", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/nettle/nettle-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("nettle", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/nettle/nettle-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
M4,
|
||||
|
||||
@@ -7,9 +7,9 @@ func (t Toolchain) newNettle3() (pkg.Artifact, string) {
|
||||
version = "3.10.2"
|
||||
checksum = "07aXlj10X5llf67jIqRQAA1pgLSgb0w_JYggZVPuKNoc-B-_usb5Kr8FrfBe7g1S"
|
||||
)
|
||||
return t.NewPackage("nettle", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/nettle/nettle-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("nettle", version, newTar(
|
||||
"https://ftpmirror.gnu.org/gnu/nettle/nettle-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
M4,
|
||||
|
||||
@@ -13,25 +13,26 @@ func (t Toolchain) newNinja() (pkg.Artifact, string) {
|
||||
}, nil, nil, `
|
||||
cd "$(mktemp -d)"
|
||||
python3 /usr/src/ninja/configure.py \
|
||||
--verbose \
|
||||
--bootstrap \
|
||||
--gtest-source-dir=/usr/src/googletest
|
||||
./ninja all
|
||||
./ninja `+jobsFlagE+` all
|
||||
./ninja_test
|
||||
|
||||
mkdir -p /work/system/bin/
|
||||
cp ninja /work/system/bin/
|
||||
`, pkg.Path(AbsUsrSrc.Append("googletest"), false,
|
||||
pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/google/googletest/releases/download/"+
|
||||
"v1.16.0/googletest-1.16.0.tar.gz",
|
||||
mustDecode("NjLGvSbgPy_B-y-o1hdanlzEzaYeStFcvFGxpYV3KYlhrWWFRcugYhM3ZMzOA9B_"),
|
||||
newFromGitHubRelease(
|
||||
"google/googletest",
|
||||
"v1.16.0",
|
||||
"googletest-1.16.0.tar.gz",
|
||||
"NjLGvSbgPy_B-y-o1hdanlzEzaYeStFcvFGxpYV3KYlhrWWFRcugYhM3ZMzOA9B_",
|
||||
pkg.TarGzip,
|
||||
)), pkg.Path(AbsUsrSrc.Append("ninja"), true, t.NewPatchedSource(
|
||||
"ninja", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/ninja-build/ninja/archive/refs/tags/"+
|
||||
"v"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
"ninja", version, newFromGitHub(
|
||||
"ninja-build/ninja",
|
||||
"v"+version,
|
||||
checksum,
|
||||
), false,
|
||||
))), version
|
||||
}
|
||||
|
||||
@@ -8,17 +8,16 @@ import (
|
||||
|
||||
func (t Toolchain) newNSS() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "3.122"
|
||||
checksum = "QvC6TBO4BAUEh6wmgUrb1hwH5podQAN-QdcAaWL32cWEppmZs6oKkZpD9GvZf59S"
|
||||
version = "3.122.1"
|
||||
checksum = "DyKZJj-Dkkx874rY8vNE59fXpwQfeJt7M1XcCinnNJIAK856FTFvuFYA0TwdMVCK"
|
||||
|
||||
version0 = "4_38_2"
|
||||
checksum0 = "25x2uJeQnOHIiq_zj17b4sYqKgeoU8-IsySUptoPcdHZ52PohFZfGuIisBreWzx0"
|
||||
)
|
||||
return t.NewPackage("nss", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/nss-dev/nss/archive/refs/tags/"+
|
||||
"NSS_"+strings.Join(strings.SplitN(version, ".", 2), "_")+"_RTM.tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.NewPackage("nss", version, newFromGitHub(
|
||||
"nss-dev/nss",
|
||||
"NSS_"+strings.Join(strings.SplitN(version, ".", 3), "_")+"_RTM",
|
||||
checksum,
|
||||
), &PackageAttr{
|
||||
Paths: []pkg.ExecPath{
|
||||
pkg.Path(AbsUsrSrc.Append("nspr.zip"), false, pkg.NewHTTPGet(
|
||||
@@ -83,16 +82,30 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
const version = "0.4.0"
|
||||
artifactsM[buildcatrust] = newViaPip(
|
||||
"buildcatrust",
|
||||
"transform certificate stores between formats",
|
||||
version, "py3", "none", "any",
|
||||
"k_FGzkRCLjbTWBkuBLzQJ1S8FPAz19neJZlMHm0t10F2Y0hElmvVwdSBRc03Rjo1",
|
||||
"https://github.com/nix-community/buildcatrust/"+
|
||||
"releases/download/v"+version+"/",
|
||||
func (t Toolchain) newBuildCATrust() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.5.1"
|
||||
checksum = "g9AqIksz-hvCUceSR7ZKwfqf8Y_UsJU_3_zLUIdc4IkxFVkgdv9kKVvhFjE4s1-7"
|
||||
)
|
||||
return t.newViaPip("buildcatrust", version,
|
||||
"https://github.com/nix-community/buildcatrust/releases/"+
|
||||
"download/v"+version+"/buildcatrust-"+version+"-py3-none-any.whl",
|
||||
checksum), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[buildcatrust] = Metadata{
|
||||
f: Toolchain.newBuildCATrust,
|
||||
|
||||
Name: "buildcatrust",
|
||||
Description: "transform certificate stores between formats",
|
||||
Website: "https://github.com/nix-community/buildcatrust",
|
||||
|
||||
Dependencies: P{
|
||||
Python,
|
||||
},
|
||||
|
||||
ID: 233988,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newNSSCACert() (pkg.Artifact, string) {
|
||||
|
||||
@@ -4,13 +4,14 @@ import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newOpenSSL() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "3.6.1"
|
||||
checksum = "boMAj2SIVIFXHswZva3qHJuFEpc32rxCCu07wjMPsVe9nn_976BGMmW_5P1zthgg"
|
||||
version = "3.6.2"
|
||||
checksum = "jH004dXTiE01Hp0kyShkWXwrSHEksZi4i_3v47D9H9Uz9LQ1aMwF7mrl2Tb4t_XA"
|
||||
)
|
||||
return t.NewPackage("openssl", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/openssl/openssl/releases/download/"+
|
||||
"openssl-"+version+"/openssl-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("openssl", version, newFromGitHubRelease(
|
||||
"openssl/openssl",
|
||||
"openssl-"+version,
|
||||
"openssl-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Env: []string{
|
||||
@@ -24,9 +25,10 @@ func (t Toolchain) newOpenSSL() (pkg.Artifact, string) {
|
||||
{"prefix", "/system"},
|
||||
{"libdir", "lib"},
|
||||
{"openssldir", "etc/ssl"},
|
||||
{"", "no-docs"},
|
||||
},
|
||||
Check: []string{
|
||||
`HARNESS_JOBS="$(expr "$(nproc)" '*' 2)"`,
|
||||
"HARNESS_JOBS=" + jobsE,
|
||||
"test",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -7,9 +7,9 @@ func (t Toolchain) newP11Kit() (pkg.Artifact, string) {
|
||||
version = "0.26.2"
|
||||
checksum = "3ei-6DUVtYzrRVe-SubtNgRlweXd6H2qHmUu-_5qVyIn6gSTvZbGS2u79Y8IFb2N"
|
||||
)
|
||||
return t.NewPackage("p11-kit", version, t.NewViaGit(
|
||||
return t.NewPackage("p11-kit", version, t.newTagRemote(
|
||||
"https://github.com/p11-glue/p11-kit.git",
|
||||
"refs/tags/"+version, mustDecode(checksum),
|
||||
version, checksum,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
{"Dsystemd", "disabled"},
|
||||
|
||||
@@ -9,10 +9,11 @@ func (t Toolchain) newPCRE2() (pkg.Artifact, string) {
|
||||
version = "10.47"
|
||||
checksum = "IbC24vVayju6nB9EhrBPSDexk22wDecdpyrjgC3nCZXkwTnUjq4CD2q5sopqu6CW"
|
||||
)
|
||||
return t.NewPackage("pcre2", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/PCRE2Project/pcre2/releases/download/"+
|
||||
"pcre2-"+version+"/pcre2-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("pcre2", version, newFromGitHubRelease(
|
||||
"PCRE2Project/pcre2",
|
||||
"pcre2-"+version,
|
||||
"pcre2-"+version+".tar.bz2",
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), &PackageAttr{
|
||||
ScriptEarly: `
|
||||
|
||||
@@ -2,6 +2,7 @@ package rosa
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"hakurei.app/internal/pkg"
|
||||
)
|
||||
@@ -11,9 +12,9 @@ func (t Toolchain) newPerl() (pkg.Artifact, string) {
|
||||
version = "5.42.2"
|
||||
checksum = "Me_xFfgkRnVyG0sE6a74TktK2OUq9Z1LVJNEu_9RdZG3S2fbjfzNiuk2SJqHAgbm"
|
||||
)
|
||||
return t.NewPackage("perl", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://www.cpan.org/src/5.0/perl-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("perl", version, newTar(
|
||||
"https://www.cpan.org/src/5.0/perl-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
// uses source tree as scratch space
|
||||
@@ -42,7 +43,7 @@ rm -f /system/bin/ps # perl does not like toybox ps
|
||||
{"Duseshrplib"},
|
||||
},
|
||||
Check: []string{
|
||||
"TEST_JOBS=256",
|
||||
"TEST_JOBS=" + jobsLE,
|
||||
"test_harness",
|
||||
},
|
||||
Install: `LD_LIBRARY_PATH="$PWD" ./perl -Ilib -I. installperl --destdir=/work`,
|
||||
@@ -91,10 +92,10 @@ func (t Toolchain) newPerlModuleBuild() (pkg.Artifact, string) {
|
||||
version = "0.4234"
|
||||
checksum = "ZKxEFG4hE1rqZt52zBL2LRZBMkYzhjb5-cTBXcsyA52EbPeeYyVxU176yAea8-Di"
|
||||
)
|
||||
return t.newViaPerlModuleBuild("Module-Build", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/L/LE/LEONT/"+
|
||||
return t.newViaPerlModuleBuild("Module-Build", version, newTar(
|
||||
"https://cpan.metacpan.org/authors/id/L/LE/LEONT/"+
|
||||
"Module-Build-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil), version
|
||||
}
|
||||
@@ -145,11 +146,11 @@ func (t Toolchain) newPerlLocaleGettext() (pkg.Artifact, string) {
|
||||
version = "1.07"
|
||||
checksum = "cFq4BKFD1MWSoa7lsrPjpdo9kzPqd0jlRcBFUyL1L1isw8m3D_Sge_ff0MAu_9J3"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("Locale::gettext", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/P/PV/PVANDRY/"+
|
||||
"Locale-gettext-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.newViaPerlMakeMaker("Locale::gettext", version, newFromCPAN(
|
||||
"PVANDRY",
|
||||
"Locale-gettext",
|
||||
version,
|
||||
checksum,
|
||||
), nil), version
|
||||
}
|
||||
func init() {
|
||||
@@ -159,6 +160,8 @@ func init() {
|
||||
Name: "perl-Locale::gettext",
|
||||
Description: "message handling functions",
|
||||
Website: "https://metacpan.org/release/Locale-gettext",
|
||||
|
||||
ID: 7523,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,11 +170,11 @@ func (t Toolchain) newPerlPodParser() (pkg.Artifact, string) {
|
||||
version = "1.67"
|
||||
checksum = "RdURu9mOfExk_loCp6abxlcQV3FycSNbTqhRS9i6JUqnYfGGEgercK30g0gjYyqe"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("Pod::Parser", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/M/MA/MAREKR/"+
|
||||
"Pod-Parser-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.newViaPerlMakeMaker("Pod::Parser", version, newFromCPAN(
|
||||
"MAREKR",
|
||||
"Pod-Parser",
|
||||
version,
|
||||
checksum,
|
||||
), nil), version
|
||||
}
|
||||
func init() {
|
||||
@@ -181,6 +184,8 @@ func init() {
|
||||
Name: "perl-Pod::Parser",
|
||||
Description: "base class for creating POD filters and translators",
|
||||
Website: "https://metacpan.org/release/Pod-Parser",
|
||||
|
||||
ID: 3244,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,11 +194,11 @@ func (t Toolchain) newPerlSGMLS() (pkg.Artifact, string) {
|
||||
version = "1.1"
|
||||
checksum = "aZijn4MUqD-wfyZgdcCruCwl4SgDdu25cNmJ4_UvdAk9a7uz4gzMQdoeB6DQ6QOy"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("SGMLS", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/R/RA/RAAB/"+
|
||||
"SGMLSpm-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.newViaPerlMakeMaker("SGMLS", version, newFromCPAN(
|
||||
"RAAB",
|
||||
"SGMLSpm",
|
||||
version,
|
||||
checksum,
|
||||
), nil), version
|
||||
}
|
||||
func init() {
|
||||
@@ -203,6 +208,22 @@ func init() {
|
||||
Name: "perl-SGMLS",
|
||||
Description: "class for postprocessing the output from the sgmls and nsgmls parsers",
|
||||
Website: "https://metacpan.org/release/RAAB/SGMLSpm-1.1",
|
||||
|
||||
ID: 389576,
|
||||
|
||||
latest: func(v *Versions) string {
|
||||
for _, s := range v.Stable {
|
||||
_, m, ok := strings.Cut(s, ".")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if len(m) > 1 && m[0] == '0' {
|
||||
continue
|
||||
}
|
||||
return s
|
||||
}
|
||||
return v.Latest
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,11 +232,11 @@ func (t Toolchain) newPerlTermReadKey() (pkg.Artifact, string) {
|
||||
version = "2.38"
|
||||
checksum = "qerL8Xo7kD0f42PZoiEbmE8Roc_S9pOa27LXelY4DN_0UNy_u5wLrGHI8utNlaiI"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("Term::ReadKey", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/J/JS/JSTOWE/"+
|
||||
"TermReadKey-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.newViaPerlMakeMaker("Term::ReadKey", version, newFromCPAN(
|
||||
"JSTOWE",
|
||||
"TermReadKey",
|
||||
version,
|
||||
checksum,
|
||||
), nil), version
|
||||
}
|
||||
func init() {
|
||||
@@ -225,6 +246,8 @@ func init() {
|
||||
Name: "perl-Term::ReadKey",
|
||||
Description: "a perl module for simple terminal control",
|
||||
Website: "https://metacpan.org/release/TermReadKey",
|
||||
|
||||
ID: 3372,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,11 +256,11 @@ func (t Toolchain) newPerlTextCharWidth() (pkg.Artifact, string) {
|
||||
version = "0.04"
|
||||
checksum = "G2p5RHU4_HiZ23ZusBA_enTlVMxz0J4esUx4CGcOPhY6xYTbp-aXWRN6lYZpzBw2"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("Text::CharWidth", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/K/KU/KUBOTA/"+
|
||||
"Text-CharWidth-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.newViaPerlMakeMaker("Text::CharWidth", version, newFromCPAN(
|
||||
"KUBOTA",
|
||||
"Text-CharWidth",
|
||||
version,
|
||||
checksum,
|
||||
), nil), version
|
||||
}
|
||||
func init() {
|
||||
@@ -247,6 +270,8 @@ func init() {
|
||||
Name: "perl-Text::CharWidth",
|
||||
Description: "get number of occupied columns of a string on terminal",
|
||||
Website: "https://metacpan.org/release/Text-CharWidth",
|
||||
|
||||
ID: 14380,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,11 +280,11 @@ func (t Toolchain) newPerlTextWrapI18N() (pkg.Artifact, string) {
|
||||
version = "0.06"
|
||||
checksum = "Vmo89qLgxUqyQ6QmWJVqu60aQAUjrNKRjFQSXGnvClxofzRjiCa6idzPgJ4VkixM"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("Text::WrapI18N", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/K/KU/KUBOTA/"+
|
||||
"Text-WrapI18N-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.newViaPerlMakeMaker("Text::WrapI18N", version, newFromCPAN(
|
||||
"KUBOTA",
|
||||
"Text-WrapI18N",
|
||||
version,
|
||||
checksum,
|
||||
), nil,
|
||||
PerlTextCharWidth,
|
||||
), version
|
||||
@@ -275,6 +300,8 @@ func init() {
|
||||
Dependencies: P{
|
||||
PerlTextCharWidth,
|
||||
},
|
||||
|
||||
ID: 14385,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,11 +310,11 @@ func (t Toolchain) newPerlMIMECharset() (pkg.Artifact, string) {
|
||||
version = "1.013.1"
|
||||
checksum = "Ou_ukcrOa1cgtE3mptinb-os3bdL1SXzbRDFZQF3prrJj-drc3rp_huay7iDLJol"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("MIME::Charset", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/N/NE/NEZUMI/"+
|
||||
"MIME-Charset-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.newViaPerlMakeMaker("MIME::Charset", version, newFromCPAN(
|
||||
"NEZUMI",
|
||||
"MIME-Charset",
|
||||
version,
|
||||
checksum,
|
||||
), nil), version
|
||||
}
|
||||
func init() {
|
||||
@@ -297,34 +324,38 @@ func init() {
|
||||
Name: "perl-MIME::Charset",
|
||||
Description: "Charset Information for MIME",
|
||||
Website: "https://metacpan.org/release/MIME-Charset",
|
||||
|
||||
ID: 3070,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newPerlUnicodeGCString() (pkg.Artifact, string) {
|
||||
func (t Toolchain) newPerlUnicodeLineBreak() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "2019.001"
|
||||
checksum = "ZHVkh7EDgAUHnTpvXsnPAuWpgNoBImtY_9_8TIbo2co_WgUwEb0MtXPhI8pAZ5OH"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("Unicode::GCString", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/N/NE/NEZUMI/"+
|
||||
"Unicode-LineBreak-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.newViaPerlMakeMaker("Unicode::LineBreak", version, newFromCPAN(
|
||||
"NEZUMI",
|
||||
"Unicode-LineBreak",
|
||||
version,
|
||||
checksum,
|
||||
), nil,
|
||||
PerlMIMECharset,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[PerlUnicodeGCString] = Metadata{
|
||||
f: Toolchain.newPerlUnicodeGCString,
|
||||
artifactsM[PerlUnicodeLineBreak] = Metadata{
|
||||
f: Toolchain.newPerlUnicodeLineBreak,
|
||||
|
||||
Name: "perl-Unicode::GCString",
|
||||
Name: "perl-Unicode::LineBreak",
|
||||
Description: "String as Sequence of UAX #29 Grapheme Clusters",
|
||||
Website: "https://metacpan.org/release/Unicode-LineBreak",
|
||||
|
||||
Dependencies: P{
|
||||
PerlMIMECharset,
|
||||
},
|
||||
|
||||
ID: 6033,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,11 +364,11 @@ func (t Toolchain) newPerlYAMLTiny() (pkg.Artifact, string) {
|
||||
version = "1.76"
|
||||
checksum = "V1MV4KPym1LxSw8CRXqPR3K-l1hGHbT5Ob4t-9xju6R9X_CWyw6hI8wsMaNdHdBY"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("YAML::Tiny", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://cpan.metacpan.org/authors/id/E/ET/ETHER/"+
|
||||
"YAML-Tiny-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
return t.newViaPerlMakeMaker("YAML::Tiny", version, newFromCPAN(
|
||||
"ETHER",
|
||||
"YAML-Tiny",
|
||||
version,
|
||||
checksum,
|
||||
), nil), version
|
||||
}
|
||||
func init() {
|
||||
@@ -347,5 +378,7 @@ func init() {
|
||||
Name: "perl-YAML::Tiny",
|
||||
Description: "read/write YAML files with as little code as possible",
|
||||
Website: "https://metacpan.org/release/YAML-Tiny",
|
||||
|
||||
ID: 3549,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ func (t Toolchain) newPkgConfig() (pkg.Artifact, string) {
|
||||
version = "0.29.2"
|
||||
checksum = "6UsGqEMA8EER_5b9N0b32UCqiRy39B6_RnPfvuslWhtFV1qYD4DfS10crGZN_TP2"
|
||||
)
|
||||
return t.NewPackage("pkg-config", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://gitlab.freedesktop.org/pkg-config/pkg-config/-/archive"+
|
||||
"/pkg-config-"+version+"/pkg-config-pkg-config-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
pkg.TarBzip2,
|
||||
return t.NewPackage("pkg-config", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"pkg-config/pkg-config",
|
||||
"pkg-config-"+version,
|
||||
checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "./autogen.sh --no-configure",
|
||||
Configure: []KV{
|
||||
|
||||
@@ -7,11 +7,11 @@ func (t Toolchain) newProcps() (pkg.Artifact, string) {
|
||||
version = "4.0.6"
|
||||
checksum = "pl_fZLvDlv6iZTkm8l_tHFpzTDVFGCiSJEs3eu0zAX6u36AV36P_En8K7JPScRWM"
|
||||
)
|
||||
return t.NewPackage("procps", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://gitlab.com/procps-ng/procps/-/archive/"+
|
||||
"v"+version+"/procps-v"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
pkg.TarBzip2,
|
||||
return t.NewPackage("procps", version, newFromGitLab(
|
||||
"gitlab.com",
|
||||
"procps-ng/procps",
|
||||
"v"+version,
|
||||
checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "./autogen.sh",
|
||||
Configure: []KV{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package rosa
|
||||
|
||||
import (
|
||||
"path"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
@@ -9,13 +10,13 @@ import (
|
||||
|
||||
func (t Toolchain) newPython() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "3.14.3"
|
||||
checksum = "ajEC32WPmn9Jvll0n4gGvlTvhMPUHb2H_j5_h9jf_esHmkZBRfAumDcKY7nTTsCH"
|
||||
version = "3.14.4"
|
||||
checksum = "X0VRAAGOlCVldh4J9tRAE-YrJtDvqfQTJaqxKPXNX6YTPlwpR9GwA5WRIZDO-63s"
|
||||
)
|
||||
return t.NewPackage("python", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://www.python.org/ftp/python/"+version+
|
||||
return t.NewPackage("python", version, newTar(
|
||||
"https://www.python.org/ftp/python/"+version+
|
||||
"/Python-"+version+".tgz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
// test_synopsis_sourceless assumes this is writable and checks __pycache__
|
||||
@@ -80,26 +81,42 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// newViaPip is a helper for installing python dependencies via pip.
|
||||
func newViaPip(
|
||||
name, description, version, interpreter, abi, platform, checksum, prefix string,
|
||||
// newViaPip installs a pip wheel from a url.
|
||||
func (t Toolchain) newViaPip(
|
||||
name, version, url, checksum string,
|
||||
extra ...PArtifact,
|
||||
) Metadata {
|
||||
wname := name + "-" + version + "-" + interpreter + "-" + abi + "-" + platform + ".whl"
|
||||
return Metadata{
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
return t.New(name+"-"+version, 0, t.AppendPresets(nil,
|
||||
slices.Concat(P{Python}, extra)...,
|
||||
), nil, nil, `
|
||||
) pkg.Artifact {
|
||||
return t.New(name+"-"+version, 0, t.AppendPresets(nil,
|
||||
slices.Concat(P{Python}, extra)...,
|
||||
), nil, nil, `
|
||||
pip3 install \
|
||||
--no-index \
|
||||
--prefix=/system \
|
||||
--root=/work \
|
||||
/usr/src/`+wname+`
|
||||
`, pkg.Path(AbsUsrSrc.Append(wname), false, pkg.NewHTTPGet(
|
||||
nil, prefix+wname,
|
||||
mustDecode(checksum),
|
||||
))), version
|
||||
'/usr/src/`+path.Base(url)+`'
|
||||
`, pkg.Path(AbsUsrSrc.Append(path.Base(url)), false, pkg.NewHTTPGet(
|
||||
nil, url,
|
||||
mustDecode(checksum),
|
||||
)))
|
||||
}
|
||||
|
||||
// newPypi creates [Metadata] for a [pypi] package.
|
||||
//
|
||||
// [pypi]: https://pypi.org/
|
||||
func newPypi(
|
||||
name string, id int,
|
||||
description, version, interpreter, abi, platform, checksum string,
|
||||
extra ...PArtifact,
|
||||
) Metadata {
|
||||
return Metadata{
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
return t.newViaPip(name, version, "https://files.pythonhosted.org/"+path.Join(
|
||||
"packages",
|
||||
interpreter,
|
||||
string(name[0]),
|
||||
name,
|
||||
name+"-"+version+"-"+interpreter+"-"+abi+"-"+platform+".whl",
|
||||
), checksum, extra...), version
|
||||
},
|
||||
|
||||
Name: "python-" + name,
|
||||
@@ -107,6 +124,8 @@ pip3 install \
|
||||
Website: "https://pypi.org/project/" + name + "/",
|
||||
|
||||
Dependencies: slices.Concat(P{Python}, extra),
|
||||
|
||||
ID: id,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,11 +142,9 @@ pip3 install \
|
||||
--prefix=/system \
|
||||
--root=/work \
|
||||
/usr/src/setuptools
|
||||
`, pkg.Path(AbsUsrSrc.Append("setuptools"), true, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/pypa/setuptools/archive/refs/tags/"+
|
||||
"v"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
`, pkg.Path(AbsUsrSrc.Append("setuptools"), true, newFromGitHub(
|
||||
"pypa/setuptools",
|
||||
"v"+version, checksum,
|
||||
))), version
|
||||
}
|
||||
func init() {
|
||||
@@ -147,52 +164,71 @@ func init() {
|
||||
}
|
||||
|
||||
func init() {
|
||||
artifactsM[PythonPygments] = newViaPip(
|
||||
"pygments",
|
||||
artifactsM[PythonPygments] = newPypi(
|
||||
"pygments", 3986,
|
||||
" a syntax highlighting package written in Python",
|
||||
"2.19.2", "py3", "none", "any",
|
||||
"ak_lwTalmSr7W4Mjy2XBZPG9I6a0gwSy2pS87N8x4QEuZYif0ie9z0OcfRfi9msd",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/",
|
||||
"2.20.0", "py3", "none", "any",
|
||||
"qlyqX2YSXcV0Z8XgGaPttc_gkq-xsu_nYs6NFOcYnk-CX7qmcj45gG-h6DpwPIcO",
|
||||
)
|
||||
|
||||
artifactsM[PythonPluggy] = newViaPip(
|
||||
"pluggy",
|
||||
artifactsM[PythonPluggy] = newPypi(
|
||||
"pluggy", 7500,
|
||||
"the core framework used by the pytest, tox, and devpi projects",
|
||||
"1.6.0", "py3", "none", "any",
|
||||
"2HWYBaEwM66-y1hSUcWI1MyE7dVVuNNRW24XD6iJBey4YaUdAK8WeXdtFMQGC-4J",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/",
|
||||
)
|
||||
|
||||
artifactsM[PythonPackaging] = newViaPip(
|
||||
"packaging",
|
||||
artifactsM[PythonPackaging] = newPypi(
|
||||
"packaging", 60461,
|
||||
"reusable core utilities for various Python Packaging interoperability specifications",
|
||||
"26.0", "py3", "none", "any",
|
||||
"iVVXcqdwHDskPKoCFUlh2x8J0Gyq-bhO4ns9DvUJ7oJjeOegRYtSIvLV33Bki-pP",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/",
|
||||
"26.1", "py3", "none", "any",
|
||||
"6WZjBJeRb0eZZavxM8cLPcgD-ch-1FblsHoCFKC_9VUC5XAmd397LwliVhsnQcSN",
|
||||
)
|
||||
|
||||
artifactsM[PythonIniConfig] = newViaPip(
|
||||
"iniconfig",
|
||||
artifactsM[PythonIniConfig] = newPypi(
|
||||
"iniconfig", 114778,
|
||||
"a small and simple INI-file parser module",
|
||||
"2.3.0", "py3", "none", "any",
|
||||
"SDgs4S5bXi77aVOeKTPv2TUrS3M9rduiK4DpU0hCmDsSBWqnZcWInq9lsx6INxut",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/",
|
||||
)
|
||||
|
||||
artifactsM[PythonPyTest] = newViaPip(
|
||||
"pytest",
|
||||
artifactsM[PythonPyTest] = newPypi(
|
||||
"pytest", 3765,
|
||||
"the pytest framework",
|
||||
"9.0.2", "py3", "none", "any",
|
||||
"IM2wDbLke1EtZhF92zvAjUl_Hms1uKDtM7U8Dt4acOaChMnDg1pW7ib8U0wYGDLH",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/",
|
||||
"9.0.3", "py3", "none", "any",
|
||||
"57WLrIVOfyoRDjt5qD6LGOaDcDCtzQnKDSTUb7GzHyJDtry_nGHHs4-0tW0tiIJr",
|
||||
PythonIniConfig,
|
||||
PythonPackaging,
|
||||
PythonPluggy,
|
||||
PythonPygments,
|
||||
)
|
||||
|
||||
artifactsM[PythonMarkupSafe] = newPypi(
|
||||
"markupsafe", 3918,
|
||||
"implements a text object that escapes characters so it is safe to use in HTML and XML",
|
||||
"3.0.3", "cp314", "cp314", "musllinux_1_2_"+linuxArch(),
|
||||
perArch[string]{
|
||||
"amd64": "E2mo9ig_FKgTpGon_8qqviSEULwhnmxTIqd9vfyNxNpK4yofVYM7eLW_VE-LKbtO",
|
||||
"arm64": "iG_hqsncOs8fA7bCaAg0x9XenXWlo9sqblyPcSG7yA9sfGLvM9KZznCpwWfOCwFC",
|
||||
"riscv64": "7DI7U0M3jvr7U4uZml25GLw3m3EvMubCtNukZmss1gkVJ_DVkhV5DgX3Wt_sztbv",
|
||||
}.unwrap(),
|
||||
)
|
||||
|
||||
artifactsM[PythonMako] = newPypi(
|
||||
"mako", 3915,
|
||||
"a template library written in Python",
|
||||
"1.3.11", "py3", "none", "any",
|
||||
"WJ_hxYI-nNiuDiM6QhfAG84uO5U-M2aneB0JS9AQ2J2Oi6YXAbBxIdOeOEng6CoS",
|
||||
PythonMarkupSafe,
|
||||
)
|
||||
|
||||
artifactsM[PythonPyYAML] = newPypi(
|
||||
"pyyaml", 4123,
|
||||
"a YAML parser and emitter for Python",
|
||||
"6.0.3", "cp314", "cp314", "musllinux_1_2_"+linuxArch(),
|
||||
perArch[string]{
|
||||
"amd64": "4_jhCFpUNtyrFp2HOMqUisR005u90MHId53eS7rkUbcGXkoaJ7JRsY21dREHEfGN",
|
||||
"arm64": "sQ818ZYSmC7Vj9prIPx3sEYqSDhZlWvLbgHV9w4GjxsfQ63ZSzappctKM7Lb0Whw",
|
||||
}.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ func (t Toolchain) newQEMU() (pkg.Artifact, string) {
|
||||
version = "10.2.2"
|
||||
checksum = "uNzRxlrVoLWe-EmZmBp75SezymgE512iE5XN90Bl7wi6CjE_oQGQB-9ocs7E16QG"
|
||||
)
|
||||
return t.NewPackage("qemu", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://download.qemu.org/qemu-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("qemu", version, newTar(
|
||||
"https://download.qemu.org/qemu-"+version+".tar.bz2",
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
), &PackageAttr{
|
||||
Patches: []KV{
|
||||
|
||||
@@ -7,9 +7,9 @@ func (t Toolchain) newRdfind() (pkg.Artifact, string) {
|
||||
version = "1.8.0"
|
||||
checksum = "PoaeJ2WIG6yyfe5VAYZlOdAQiR3mb3WhAUMj2ziTCx_IIEal4640HMJUb4SzU9U3"
|
||||
)
|
||||
return t.NewPackage("rdfind", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://rdfind.pauldreik.se/rdfind-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("rdfind", version, newTar(
|
||||
"https://rdfind.pauldreik.se/rdfind-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, &MakeHelper{
|
||||
// test suite hard codes /bin/echo
|
||||
|
||||
@@ -4,6 +4,7 @@ package rosa
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"path"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
@@ -69,6 +70,18 @@ func triplet() string {
|
||||
return linuxArch() + "-rosa-linux-musl"
|
||||
}
|
||||
|
||||
// perArch is a value that differs per architecture.
|
||||
type perArch[T any] map[string]T
|
||||
|
||||
// unwrap returns the value for the current architecture.
|
||||
func (p perArch[T]) unwrap() T {
|
||||
v, ok := p[runtime.GOARCH]
|
||||
if !ok {
|
||||
panic("unsupported target " + runtime.GOARCH)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
const (
|
||||
// EnvTriplet holds the return value of triplet.
|
||||
EnvTriplet = "ROSA_TRIPLE"
|
||||
@@ -315,24 +328,23 @@ mkdir -vp /work/system/bin
|
||||
name += "-std"
|
||||
}
|
||||
|
||||
boot := t - 1
|
||||
musl, compilerRT, runtimes, clang := boot.NewLLVM()
|
||||
toybox := Toybox
|
||||
if flag&TEarly != 0 {
|
||||
toybox = toyboxEarly
|
||||
}
|
||||
std := []pkg.Artifact{cureEtc{newIANAEtc()}, musl}
|
||||
toolchain := []pkg.Artifact{compilerRT, runtimes, clang}
|
||||
utils := []pkg.Artifact{
|
||||
boot.Load(Mksh),
|
||||
boot.Load(toybox),
|
||||
}
|
||||
|
||||
base := Clang
|
||||
if flag&TNoToolchain != 0 {
|
||||
toolchain = nil
|
||||
base = Musl
|
||||
}
|
||||
|
||||
support = slices.Concat(extra, std, toolchain, utils)
|
||||
support = slices.Concat(extra, (t-1).AppendPresets([]pkg.Artifact{
|
||||
cureEtc{newIANAEtc()},
|
||||
},
|
||||
base,
|
||||
Mksh,
|
||||
toybox,
|
||||
))
|
||||
env = fixupEnviron(env, []string{
|
||||
EnvTriplet + "=" + triplet(),
|
||||
lcMessages,
|
||||
@@ -408,8 +420,6 @@ const helperInPlace = "\x00"
|
||||
|
||||
// Helper is a build system helper for [Toolchain.NewPackage].
|
||||
type Helper interface {
|
||||
// name returns the value passed to the name argument of [Toolchain.New].
|
||||
name(name, version string) string
|
||||
// extra returns helper-specific dependencies.
|
||||
extra(flag int) P
|
||||
|
||||
@@ -431,11 +441,6 @@ type Helper interface {
|
||||
script(name string) string
|
||||
}
|
||||
|
||||
const (
|
||||
// SourceKindTarXZ denotes a source tarball to be decompressed using [XZ].
|
||||
SourceKindTarXZ = 1 + iota
|
||||
)
|
||||
|
||||
// PackageAttr holds build-system-agnostic attributes.
|
||||
type PackageAttr struct {
|
||||
// Mount the source tree writable.
|
||||
@@ -452,8 +457,6 @@ type PackageAttr struct {
|
||||
|
||||
// Passed to [Toolchain.NewPatchedSource].
|
||||
Patches []KV
|
||||
// Kind of source artifact.
|
||||
SourceKind int
|
||||
|
||||
// Dependencies not provided by stage0.
|
||||
NonStage0 []pkg.Artifact
|
||||
@@ -525,11 +528,6 @@ func (t Toolchain) NewPackage(
|
||||
panic("source must be non-nil")
|
||||
}
|
||||
wantsChmod, wantsWrite := helper.wantsChmod(), helper.wantsWrite()
|
||||
if attr.SourceKind > 0 &&
|
||||
(attr.Writable || attr.Chmod || wantsChmod || wantsWrite || len(attr.Patches) > 0) {
|
||||
panic("source processing requested on a non-unpacked kind")
|
||||
}
|
||||
|
||||
dc := len(attr.NonStage0)
|
||||
if !t.isStage0() {
|
||||
dc += 1<<3 + len(extra)
|
||||
@@ -548,17 +546,23 @@ func (t Toolchain) NewPackage(
|
||||
paPut(pv)
|
||||
}
|
||||
|
||||
var scriptEarly string
|
||||
var (
|
||||
scriptEarly string
|
||||
sourceSuffix string
|
||||
)
|
||||
|
||||
if _, ok := source.(pkg.FileArtifact); ok {
|
||||
if attr.Writable || attr.Chmod ||
|
||||
wantsChmod || wantsWrite ||
|
||||
len(attr.Patches) > 0 {
|
||||
panic("source processing requested on a xz-compressed tarball")
|
||||
}
|
||||
|
||||
var sourceSuffix string
|
||||
switch attr.SourceKind {
|
||||
case SourceKindTarXZ:
|
||||
sourceSuffix = ".tar.xz"
|
||||
scriptEarly += `
|
||||
tar -C /usr/src/ -xf '/usr/src/` + name + `.tar.xz'
|
||||
mv '/usr/src/` + name + `-` + version + `' '/usr/src/` + name + `'
|
||||
`
|
||||
break
|
||||
}
|
||||
|
||||
dir := helper.wantsDir()
|
||||
@@ -582,7 +586,7 @@ cd '/usr/src/` + name + `/'
|
||||
}
|
||||
|
||||
return t.New(
|
||||
helper.name(name, version),
|
||||
name+"-"+version,
|
||||
attr.Flag,
|
||||
extraRes,
|
||||
nil,
|
||||
@@ -597,3 +601,65 @@ cd '/usr/src/` + name + `/'
|
||||
})...,
|
||||
)
|
||||
}
|
||||
|
||||
const (
|
||||
// jobsE is expression for preferred job count set by [pkg].
|
||||
jobsE = `"$` + pkg.EnvJobs + `"`
|
||||
// jobsE is expression for flag with preferred job count.
|
||||
jobsFlagE = `"-j$` + pkg.EnvJobs + `"`
|
||||
// jobsLE is expression for twice of preferred job count set by [pkg].
|
||||
jobsLE = `"$(expr ` + jobsE + ` '*' 2)"`
|
||||
// jobsE is expression for flag with double of preferred job count.
|
||||
jobsLFlagE = `"-j$(expr ` + jobsE + ` '*' 2)"`
|
||||
)
|
||||
|
||||
// newTar wraps [pkg.NewHTTPGetTar] with a simpler function signature.
|
||||
func newTar(url, checksum string, compression uint32) pkg.Artifact {
|
||||
return pkg.NewHTTPGetTar(nil, url, mustDecode(checksum), compression)
|
||||
}
|
||||
|
||||
// newFromCPAN is a helper for downloading release from CPAN.
|
||||
func newFromCPAN(author, name, version, checksum string) pkg.Artifact {
|
||||
return newTar(
|
||||
"https://cpan.metacpan.org/authors/id/"+
|
||||
author[:1]+"/"+author[:2]+"/"+author+"/"+
|
||||
name+"-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
)
|
||||
}
|
||||
|
||||
// newFromGitLab is a helper for downloading source from GitLab.
|
||||
func newFromGitLab(domain, suffix, ref, checksum string) pkg.Artifact {
|
||||
return newTar(
|
||||
"https://"+domain+"/"+suffix+"/-/archive/"+
|
||||
ref+"/"+path.Base(suffix)+"-"+
|
||||
strings.ReplaceAll(ref, "/", "-")+".tar.bz2",
|
||||
checksum,
|
||||
pkg.TarBzip2,
|
||||
)
|
||||
}
|
||||
|
||||
// newFromGitHub is a helper for downloading source from Microsoft Github.
|
||||
func newFromGitHub(suffix, tag, checksum string) pkg.Artifact {
|
||||
return newTar(
|
||||
"https://github.com/"+suffix+
|
||||
"/archive/refs/tags/"+tag+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
)
|
||||
}
|
||||
|
||||
// newFromGitHubRelease is a helper for downloading release tarball from
|
||||
// Microsoft Github.
|
||||
func newFromGitHubRelease(
|
||||
suffix, tag, name, checksum string,
|
||||
compression uint32,
|
||||
) pkg.Artifact {
|
||||
return newTar(
|
||||
"https://github.com/"+suffix+
|
||||
"/releases/download/"+tag+"/"+name,
|
||||
checksum,
|
||||
compression,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ func getCache(t *testing.T) *pkg.Cache {
|
||||
msg := message.New(log.New(os.Stderr, "rosa: ", 0))
|
||||
msg.SwapVerbose(true)
|
||||
|
||||
if buildTestCache, err = pkg.Open(ctx, msg, 0, 0, a); err != nil {
|
||||
if buildTestCache, err = pkg.Open(ctx, msg, 0, 0, 0, a); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ func TestCureAll(t *testing.T) {
|
||||
|
||||
func BenchmarkStage3(b *testing.B) {
|
||||
for b.Loop() {
|
||||
rosa.Std.Load(rosa.LLVMClang)
|
||||
rosa.Std.Load(rosa.Clang)
|
||||
|
||||
b.StopTimer()
|
||||
rosa.DropCaches()
|
||||
|
||||
@@ -7,10 +7,10 @@ func (t Toolchain) newRsync() (pkg.Artifact, string) {
|
||||
version = "3.4.1"
|
||||
checksum = "VBlTsBWd9z3r2-ex7GkWeWxkUc5OrlgDzikAC0pK7ufTjAJ0MbmC_N04oSVTGPiv"
|
||||
)
|
||||
return t.NewPackage("rsync", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://download.samba.org/pub/rsync/src/"+
|
||||
return t.NewPackage("rsync", version, newTar(
|
||||
"https://download.samba.org/pub/rsync/src/"+
|
||||
"rsync-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Flag: TEarly,
|
||||
|
||||
@@ -7,10 +7,11 @@ func (t Toolchain) newSquashfsTools() (pkg.Artifact, string) {
|
||||
version = "4.7.5"
|
||||
checksum = "rF52wLQP-jeAmcD-48wqJcck8ZWRFwkax3T-7snaRf5EBnCQQh0YypMY9lwcivLz"
|
||||
)
|
||||
return t.NewPackage("squashfs-tools", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://github.com/plougher/squashfs-tools/releases/"+
|
||||
"download/"+version+"/squashfs-tools-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
return t.NewPackage("squashfs-tools", version, newFromGitHubRelease(
|
||||
"plougher/squashfs-tools",
|
||||
version,
|
||||
"squashfs-tools-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
// uses source tree as scratch space
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user