forked from rosa/hakurei
Compare commits
31 Commits
staging
...
wip-azalea
| Author | SHA1 | Date | |
|---|---|---|---|
|
c2d44d5937
|
|||
|
c32c06b2e8
|
|||
|
61199f734c
|
|||
|
87cf0d4e6b
|
|||
|
cf0dffa0f5
|
|||
|
686d7ec63a
|
|||
|
4c653b1151
|
|||
|
0b0a63d151
|
|||
|
6231cfe2aa
|
|||
|
712e80890b
|
|||
|
3fe7d48014
|
|||
|
16f9d39427
|
|||
|
c1cd5ba07b
|
|||
|
7b0cd2e472
|
|||
|
e580307528
|
|||
|
ee1dffb676
|
|||
|
f095fcf181
|
|||
|
ca8a130130
|
|||
|
0ad6b00e41
|
|||
|
ad0f1cf36b
|
|||
|
b12d924fa2
|
|||
|
c31d8ae41a
|
|||
|
6dbbf15c0e
|
|||
|
be7de68a42
|
|||
|
a759cf3666
|
|||
|
8c2dd3e984
|
|||
|
67038d5af4
|
|||
|
53d8d12e7f
|
|||
|
7997d79e56
|
|||
|
f2f1726190
|
|||
|
f63203cb0a
|
@@ -506,6 +506,8 @@ func main() {
|
||||
flagExport string
|
||||
flagRemote bool
|
||||
flagNoReply bool
|
||||
flagFaults bool
|
||||
flagPop bool
|
||||
|
||||
flagBoot bool
|
||||
flagStd bool
|
||||
@@ -614,6 +616,49 @@ func main() {
|
||||
}
|
||||
|
||||
return err
|
||||
|
||||
case flagFaults:
|
||||
var faults []pkg.Fault
|
||||
if err := cm.Do(func(cache *pkg.Cache) (err error) {
|
||||
faults, err = cache.ReadFaults(t.Load(p))
|
||||
return
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, fault := range faults {
|
||||
log.Printf("%s: %s ago", fault.String(), time.Since(fault.Time()))
|
||||
}
|
||||
return nil
|
||||
|
||||
case flagPop:
|
||||
var faults []pkg.Fault
|
||||
if err := cm.Do(func(cache *pkg.Cache) (err error) {
|
||||
faults, err = cache.ReadFaults(t.Load(p))
|
||||
return
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(faults) == 0 {
|
||||
return errors.New("no fault entries found")
|
||||
}
|
||||
fault := faults[len(faults)-1]
|
||||
r, err := fault.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = io.Copy(os.Stdout, r); err != nil {
|
||||
_ = r.Close()
|
||||
return err
|
||||
}
|
||||
fmt.Println()
|
||||
if err = r.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("faulting cure terminated %s ago", time.Since(fault.Time()))
|
||||
return fault.Destroy()
|
||||
}
|
||||
},
|
||||
).Flag(
|
||||
@@ -644,9 +689,40 @@ func main() {
|
||||
&flagStd,
|
||||
"std", command.BoolFlag(false),
|
||||
"Build on the intermediate toolchain",
|
||||
).Flag(
|
||||
&flagFaults,
|
||||
"faults", command.BoolFlag(false),
|
||||
"Display fault entries of the specified artifact",
|
||||
).Flag(
|
||||
&flagPop,
|
||||
"pop", command.BoolFlag(false),
|
||||
"Display and destroy the most recent fault entry",
|
||||
)
|
||||
}
|
||||
|
||||
c.NewCommand(
|
||||
"clear",
|
||||
"Remove all fault entries from the cache",
|
||||
func([]string) error {
|
||||
return cm.Do(func(*pkg.Cache) error {
|
||||
pathname := filepath.Join(cm.base, "fault")
|
||||
dents, err := os.ReadDir(pathname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, dent := range dents {
|
||||
msg.Verbosef("destroying entry %s", dent.Name())
|
||||
if err = os.Remove(filepath.Join(pathname, dent.Name())); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
log.Printf("destroyed %d fault entries", len(dents))
|
||||
return nil
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
c.NewCommand(
|
||||
"abort",
|
||||
"Abort all pending cures on the daemon",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package pkg_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
@@ -85,6 +86,30 @@ func TestExec(t *testing.T) {
|
||||
pkg.MustPath("/opt", false, testtool),
|
||||
), ignorePathname, wantOffline, nil},
|
||||
|
||||
{"substitution", pkg.NewExec(
|
||||
"exec-offline", "", new(wantOffline.hash()), 0, false, false,
|
||||
pkg.AbsWork,
|
||||
[]string{"HAKUREI_TEST=1"},
|
||||
check.MustAbs("/opt/bin/testtool"),
|
||||
[]string{"testtool"},
|
||||
|
||||
pkg.MustPath("/file", false, newStubFile(
|
||||
pkg.KindHTTPGet,
|
||||
pkg.ID{0xfe, 0},
|
||||
nil,
|
||||
nil, nil,
|
||||
)),
|
||||
// substitution miss fails in testtool due to differing idents
|
||||
pkg.MustPath("/.hakurei", false, &stubArtifact{
|
||||
kind: pkg.KindTar,
|
||||
params: []byte("empty directory (substituted)"),
|
||||
cure: func(t *pkg.TContext) error {
|
||||
return os.MkdirAll(t.GetWorkDir().String(), 0700)
|
||||
},
|
||||
}),
|
||||
pkg.MustPath("/opt", false, testtool),
|
||||
), ignorePathname, wantOffline, nil},
|
||||
|
||||
{"error passthrough", pkg.NewExec(
|
||||
"", "", nil, 0, false, true,
|
||||
pkg.AbsWork,
|
||||
@@ -112,18 +137,41 @@ func TestExec(t *testing.T) {
|
||||
})
|
||||
|
||||
// check init failure passthrough
|
||||
var exitError *exec.ExitError
|
||||
if _, _, err := c.Cure(pkg.NewExec(
|
||||
initFailureArtifact := pkg.NewExec(
|
||||
"", "", nil, 0, false, false,
|
||||
pkg.AbsWork,
|
||||
nil,
|
||||
check.MustAbs("/opt/bin/testtool"),
|
||||
[]string{"testtool"},
|
||||
)); !errors.As(err, &exitError) ||
|
||||
)
|
||||
var exitError *exec.ExitError
|
||||
if _, _, err := c.Cure(initFailureArtifact); !errors.As(err, &exitError) ||
|
||||
exitError.ExitCode() != hst.ExitFailure {
|
||||
t.Fatalf("Cure: error = %v, want init exit status 1", err)
|
||||
}
|
||||
|
||||
var faultStatus []byte
|
||||
if faults, err := c.ReadFaults(initFailureArtifact); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(faults) != 1 {
|
||||
t.Fatalf("ReadFaults: %v", faults)
|
||||
} else if faultStatus, err = os.ReadFile(faults[0].String()); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if err = faults[0].Destroy(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
t.Logf("destroyed expected fault at %s", faults[0].Time().UTC())
|
||||
}
|
||||
|
||||
if !bytes.HasPrefix(faultStatus, []byte(
|
||||
"internal/pkg ",
|
||||
)) || !bytes.Contains(faultStatus, []byte(
|
||||
"\ninit: fork/exec /opt/bin/testtool: no such file or directory\n",
|
||||
)) {
|
||||
t.Errorf("unexpected status:\n%s", string(faultStatus))
|
||||
}
|
||||
|
||||
destroyStatus(t, base, 2, 1)
|
||||
testtoolDestroy(t, base, c)
|
||||
}, expectsFS{
|
||||
".": {Mode: fs.ModeDir | 0700},
|
||||
@@ -135,6 +183,8 @@ func TestExec(t *testing.T) {
|
||||
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400, Data: []byte{}},
|
||||
|
||||
"identifier": {Mode: fs.ModeDir | 0700},
|
||||
"identifier/IY91PCtOpCYy21AaIK0c9f8-Z6fb2_2ewoHWkt4dxoLf0GOrWqS8yAGFLV84b1Dw": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
||||
"identifier/QwS7SmiatdqryQYgESdGw7Yw2PcpNf0vNfpvUA0t92BTlKiUjfCrXyMW17G2X77X": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||
"identifier/" + expected.Offline: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||
@@ -178,6 +228,7 @@ func TestExec(t *testing.T) {
|
||||
), ignorePathname, wantNet, nil},
|
||||
})
|
||||
|
||||
destroyStatus(t, base, 2, 0)
|
||||
testtoolDestroy(t, base, c)
|
||||
}, expectsFS{
|
||||
".": {Mode: fs.ModeDir | 0700},
|
||||
@@ -221,6 +272,7 @@ func TestExec(t *testing.T) {
|
||||
), ignorePathname, wantOffline, nil},
|
||||
})
|
||||
|
||||
destroyStatus(t, base, 2, 0)
|
||||
testtoolDestroy(t, base, c)
|
||||
}, expectsFS{
|
||||
".": {Mode: fs.ModeDir | 0700},
|
||||
@@ -267,6 +319,7 @@ func TestExec(t *testing.T) {
|
||||
), ignorePathname, wantOffline, nil},
|
||||
})
|
||||
|
||||
destroyStatus(t, base, 2, 0)
|
||||
testtoolDestroy(t, base, c)
|
||||
}, expectsFS{
|
||||
".": {Mode: fs.ModeDir | 0700},
|
||||
@@ -335,6 +388,7 @@ func TestExec(t *testing.T) {
|
||||
), ignorePathname, wantOffline, nil},
|
||||
})
|
||||
|
||||
destroyStatus(t, base, 2, 0)
|
||||
testtoolDestroy(t, base, c)
|
||||
}, expectsFS{
|
||||
".": {Mode: fs.ModeDir | 0700},
|
||||
@@ -387,6 +441,7 @@ func TestExec(t *testing.T) {
|
||||
), ignorePathname, wantOffline, nil},
|
||||
})
|
||||
|
||||
destroyStatus(t, base, 2, 0)
|
||||
testtoolDestroy(t, base, c)
|
||||
}, expectsFS{
|
||||
".": {Mode: fs.ModeDir | 0700},
|
||||
@@ -450,6 +505,8 @@ func TestExec(t *testing.T) {
|
||||
"check": {Mode: 0400, Data: []byte("binfmt")},
|
||||
}, nil},
|
||||
})
|
||||
|
||||
destroyStatus(t, base, 2, 0)
|
||||
}, expectsFS{
|
||||
".": {Mode: fs.ModeDir | 0700},
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ package pkg
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"cmp"
|
||||
"context"
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
@@ -25,6 +26,7 @@ import (
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
"unique"
|
||||
"unsafe"
|
||||
|
||||
@@ -248,7 +250,14 @@ func (t *TContext) destroy(errP *error) {
|
||||
*errP = errors.Join(*errP, err)
|
||||
}
|
||||
if *errP != nil {
|
||||
*errP = errors.Join(*errP, os.Remove(t.statusPath.String()))
|
||||
*errP = errors.Join(*errP, os.Rename(
|
||||
t.statusPath.String(), t.cache.base.Append(
|
||||
dirFault,
|
||||
t.ids+"."+strconv.FormatUint(uint64(
|
||||
time.Now().UnixNano(),
|
||||
), 10),
|
||||
).String(),
|
||||
))
|
||||
}
|
||||
t.status = nil
|
||||
}
|
||||
@@ -509,36 +518,34 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
// fileLock is the file name appended to Cache.base for guaranteeing
|
||||
// exclusive access to the cache directory.
|
||||
// fileLock is the lock file for exclusive access to the cache directory.
|
||||
fileLock = "lock"
|
||||
// fileVariant is the file name appended to Cache.base holding the variant
|
||||
// identification string set by a prior call to [SetExtension].
|
||||
// fileVariant is a file holding the variant identification string set by a
|
||||
// prior call to [SetExtension].
|
||||
fileVariant = "variant"
|
||||
|
||||
// dirSubstitute is the directory name appended to Cache.base for linking
|
||||
// artifacts named after their substitute identifier.
|
||||
// dirSubstitute holds symlinks to artifacts by checksum, named after their
|
||||
// substitute identifier.
|
||||
dirSubstitute = "substitute"
|
||||
// dirIdentifier is the directory name appended to Cache.base for storing
|
||||
// artifacts named after their [ID].
|
||||
// dirIdentifier holds symlinks to artifacts by checksum, named after their
|
||||
// IR-based identifier.
|
||||
dirIdentifier = "identifier"
|
||||
// dirChecksum is the directory name appended to Cache.base for storing
|
||||
// artifacts named after their [Checksum].
|
||||
// dirChecksum holds artifacts named after their [Checksum].
|
||||
dirChecksum = "checksum"
|
||||
// dirStatus is the directory name appended to Cache.base for storing
|
||||
// artifact metadata and logs named after their [ID].
|
||||
// dirStatus holds artifact metadata and logs named after their IR-based
|
||||
// identifier. For [FloodArtifact], the same file is also available under
|
||||
// its substitute identifier.
|
||||
dirStatus = "status"
|
||||
// dirFault holds status files of faulted cures.
|
||||
dirFault = "fault"
|
||||
|
||||
// dirWork is the directory name appended to Cache.base for working
|
||||
// pathnames set up during [Cache.Cure].
|
||||
// dirWork holds working pathnames set up during [Cache.Cure].
|
||||
dirWork = "work"
|
||||
// dirTemp is the directory name appended to Cache.base for scratch space
|
||||
// pathnames allocated during [Cache.Cure].
|
||||
// dirTemp holds scratch space allocated during [Cache.Cure].
|
||||
dirTemp = "temp"
|
||||
|
||||
// dirExecScratch is the directory name appended to Cache.base for scratch
|
||||
// space setting up the container started by [Cache.EnterExec]. Exclusivity
|
||||
// via Cache.inExec.
|
||||
// dirExecScratch is scratch space set up for the container started by
|
||||
// [Cache.EnterExec]. Exclusivity via Cache.inExec.
|
||||
dirExecScratch = "scratch"
|
||||
|
||||
// checksumLinknamePrefix is prepended to the encoded [Checksum] value
|
||||
@@ -1995,10 +2002,11 @@ func (c *Cache) cure(a Artifact, curesExempt bool) (
|
||||
buf := c.getIdentBuf()
|
||||
sh.Sum(buf[wordSize:wordSize])
|
||||
substitute = unique.Make(ID(buf[wordSize:]))
|
||||
substitutes := Encode(substitute.Value())
|
||||
c.putIdentBuf(buf)
|
||||
alternative = c.base.Append(
|
||||
dirSubstitute,
|
||||
Encode(substitute.Value()),
|
||||
substitutes,
|
||||
)
|
||||
|
||||
if c.flags&CIgnoreSubstitutes == 0 {
|
||||
@@ -2014,6 +2022,17 @@ func (c *Cache) cure(a Artifact, curesExempt bool) (
|
||||
dirChecksum,
|
||||
checksums,
|
||||
)
|
||||
if _, err = os.Lstat(c.base.Append(
|
||||
dirStatus,
|
||||
substitutes,
|
||||
).String()); err == nil {
|
||||
err = os.Symlink(substitutes, c.base.Append(
|
||||
dirStatus,
|
||||
ids,
|
||||
).String())
|
||||
} else if errors.Is(err, os.ErrNotExist) {
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -2023,6 +2042,15 @@ func (c *Cache) cure(a Artifact, curesExempt bool) (
|
||||
return
|
||||
}
|
||||
err = ca.Cure(&f)
|
||||
if err == nil && f.status != nil {
|
||||
err = os.Link(c.base.Append(
|
||||
dirStatus,
|
||||
ids,
|
||||
).String(), c.base.Append(
|
||||
dirStatus,
|
||||
substitutes,
|
||||
).String())
|
||||
}
|
||||
c.exitCure(a, curesExempt)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -2131,6 +2159,52 @@ func (c *Cache) OpenStatus(a Artifact) (r io.ReadSeekCloser, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Fault holds the pathname and termination time of an [Artifact] fault entry.
|
||||
type Fault struct {
|
||||
*check.Absolute
|
||||
t uint64
|
||||
}
|
||||
|
||||
// Time returns the instant in time where the fault occurred.
|
||||
func (f Fault) Time() time.Time { return time.Unix(0, int64(f.t)) }
|
||||
|
||||
// Open opens the underlying entry for reading.
|
||||
func (f Fault) Open() (io.ReadCloser, error) { return os.Open(f.Absolute.String()) }
|
||||
|
||||
// Destroy removes the underlying fault entry.
|
||||
func (f Fault) Destroy() error { return os.Remove(f.Absolute.String()) }
|
||||
|
||||
// ReadFaults returns fault entries for an [Artifact].
|
||||
func (c *Cache) ReadFaults(a Artifact) (faults []Fault, err error) {
|
||||
prefix := Encode(c.Ident(a).Value()) + "."
|
||||
var dents []os.DirEntry
|
||||
if dents, err = os.ReadDir(c.base.Append(dirFault).String()); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, dent := range dents {
|
||||
name := dent.Name()
|
||||
if !strings.HasPrefix(name, prefix) {
|
||||
continue
|
||||
}
|
||||
var t uint64
|
||||
t, err = strconv.ParseUint(name[len(prefix):], 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
faults = append(faults, Fault{c.base.Append(
|
||||
dirFault,
|
||||
name,
|
||||
), t})
|
||||
}
|
||||
|
||||
slices.SortFunc(faults, func(a, b Fault) int {
|
||||
return cmp.Compare(a.t, b.t)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Abort cancels all pending cures and waits for them to clean up, but does not
|
||||
// close the cache.
|
||||
func (c *Cache) Abort() {
|
||||
@@ -2234,6 +2308,7 @@ func open(
|
||||
dirIdentifier,
|
||||
dirChecksum,
|
||||
dirStatus,
|
||||
dirFault,
|
||||
dirWork,
|
||||
} {
|
||||
if err := os.MkdirAll(
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
"time"
|
||||
"unique"
|
||||
"unsafe"
|
||||
|
||||
@@ -244,6 +245,41 @@ func newDestroyArtifactFunc(a pkg.Artifact) func(
|
||||
}
|
||||
}
|
||||
|
||||
// destroyStatus counts non-substitution status entries and destroys them.
|
||||
func destroyStatus(t *testing.T, base *check.Absolute, c, s int) {
|
||||
dents, err := os.ReadDir(base.Append("status").String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var gotC, gotS int
|
||||
for _, dent := range dents {
|
||||
if err = os.Remove(base.Append(
|
||||
"status",
|
||||
dent.Name(),
|
||||
).String()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if dent.Type().IsRegular() {
|
||||
gotC++
|
||||
continue
|
||||
}
|
||||
if dent.Type()&fs.ModeSymlink == fs.ModeSymlink {
|
||||
gotS++
|
||||
continue
|
||||
}
|
||||
t.Errorf("%s: %s", dent.Name(), dent.Type())
|
||||
}
|
||||
|
||||
if gotC != c {
|
||||
t.Errorf("status: c = %d, want %d", gotC, c)
|
||||
}
|
||||
if gotS != s {
|
||||
t.Errorf("status: s = %d, want %d", gotS, s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIdent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -488,10 +524,17 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
|
||||
}
|
||||
}
|
||||
|
||||
// destroy non-deterministic status files
|
||||
if err := os.RemoveAll(base.Append("status").String()); err != nil {
|
||||
// destroy empty status directory
|
||||
if err := syscall.Rmdir(base.Append("status").String()); err != nil {
|
||||
t.Error(expectsFrom(base.Append("status").String()))
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// destroy empty fault directory
|
||||
if err := os.Remove(base.Append("fault").String()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
want := tc.want.hash()
|
||||
|
||||
var checksum pkg.Checksum
|
||||
@@ -555,6 +598,21 @@ func cureMany(t *testing.T, c *pkg.Cache, steps []cureStep) {
|
||||
for _, step := range steps {
|
||||
t.Log("cure step:", step.name)
|
||||
if pathname, checksum, err := c.Cure(step.a); !reflect.DeepEqual(err, step.err) {
|
||||
faults, _err := c.ReadFaults(step.a)
|
||||
if _err != nil {
|
||||
t.Errorf("ReadFaults: error = %v", _err)
|
||||
}
|
||||
|
||||
var p []byte
|
||||
for _, fault := range faults {
|
||||
p, _err = os.ReadFile(fault.String())
|
||||
if _err != nil {
|
||||
t.Error(_err)
|
||||
continue
|
||||
}
|
||||
t.Log(string(p))
|
||||
t.Logf("faulting cure terminated %s ago", time.Since(faults[0].Time()))
|
||||
}
|
||||
t.Fatalf("Cure: error = %v, want %v", err, step.err)
|
||||
} else if step.pathname != ignorePathname && !pathname.Is(step.pathname) {
|
||||
t.Fatalf("Cure: pathname = %q, want %q", pathname, step.pathname)
|
||||
@@ -1059,8 +1117,14 @@ func TestCache(t *testing.T) {
|
||||
"_EmV5nsYZ2UWHgRmLDMU8i-rJWDx-kv5_1pFrzQI7vMMCM5mAXivO8UZtVfOqMR_",
|
||||
), want, nil},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if dents, err := os.ReadDir(base.Append("status").String()); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(dents) > 0 {
|
||||
t.Errorf("ReadDir: %v", dents)
|
||||
}
|
||||
|
||||
}, expectsFS{
|
||||
".": {Mode: fs.ModeDir | 0700},
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ const (
|
||||
Fakeroot
|
||||
Findutils
|
||||
Flex
|
||||
FontUtil
|
||||
Freetype
|
||||
Fuse
|
||||
GMP
|
||||
GLib
|
||||
@@ -77,7 +79,10 @@ const (
|
||||
LIT
|
||||
LibX11
|
||||
LibXau
|
||||
LibXdmcp
|
||||
LibXext
|
||||
LibXfixes
|
||||
LibXfont2
|
||||
LibXrandr
|
||||
LibXrender
|
||||
LibXxf86vm
|
||||
@@ -87,9 +92,11 @@ const (
|
||||
Libconfig
|
||||
LibdisplayInfo
|
||||
Libdrm
|
||||
Libepoxy
|
||||
Libev
|
||||
Libexpat
|
||||
Libffi
|
||||
Libfontenc
|
||||
Libgd
|
||||
Libglvnd
|
||||
Libiconv
|
||||
@@ -101,17 +108,28 @@ const (
|
||||
Libpsl
|
||||
Libseccomp
|
||||
Libtasn1
|
||||
Libtirpc
|
||||
Libtool
|
||||
Libucontext
|
||||
Libunistring
|
||||
Libxshmfence
|
||||
Libva
|
||||
LibxcbRenderUtil
|
||||
LibxcbUtil
|
||||
LibxcbUtilImage
|
||||
LibxcbUtilKeysyms
|
||||
LibxcbUtilWM
|
||||
Libxcvt
|
||||
Libxkbfile
|
||||
Libxml2
|
||||
Libxshmfence
|
||||
Libxslt
|
||||
Libxtrans
|
||||
LMSensors
|
||||
M4
|
||||
MPC
|
||||
MPFR
|
||||
Make
|
||||
Mesa
|
||||
Meson
|
||||
Mksh
|
||||
MuslFts
|
||||
@@ -133,10 +151,12 @@ const (
|
||||
PerlPodParser
|
||||
PerlSGMLS
|
||||
PerlTermReadKey
|
||||
PerlTestCmd
|
||||
PerlTextCharWidth
|
||||
PerlTextWrapI18N
|
||||
PerlUnicodeLineBreak
|
||||
PerlYAMLTiny
|
||||
Pixman
|
||||
PkgConfig
|
||||
Procps
|
||||
Python
|
||||
@@ -179,10 +199,12 @@ const (
|
||||
WaylandProtocols
|
||||
XCB
|
||||
XCBProto
|
||||
XCBUtilKeysyms
|
||||
XDGDBusProxy
|
||||
XZ
|
||||
Xkbcomp
|
||||
XkeyboardConfig
|
||||
XorgProto
|
||||
Xserver
|
||||
Zlib
|
||||
Zstd
|
||||
|
||||
|
||||
386
internal/rosa/azalea/azalea.go
Normal file
386
internal/rosa/azalea/azalea.go
Normal file
@@ -0,0 +1,386 @@
|
||||
// Package azalea implements a proof-of-concept, domain-specific language for
|
||||
// Rosa OS software packaging.
|
||||
package azalea
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"strconv"
|
||||
"text/scanner"
|
||||
)
|
||||
|
||||
// idents are runes accepted in an identifier.
|
||||
var idents = [...]bool{
|
||||
'0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true,
|
||||
'7': true, '8': true, '9': true,
|
||||
|
||||
'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true,
|
||||
'H': true, 'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true,
|
||||
'O': true, 'P': true, 'Q': true, 'R': true, 'S': true, 'T': true, 'U': true,
|
||||
'V': true, 'W': true, 'X': true, 'Y': true, 'Z': true,
|
||||
|
||||
'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true,
|
||||
'h': true, 'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true,
|
||||
'o': true, 'p': true, 'q': true, 'r': true, 's': true, 't': true, 'u': true,
|
||||
'v': true, 'w': true, 'x': true, 'y': true, 'z': true,
|
||||
|
||||
'-': true, '_': true,
|
||||
}
|
||||
|
||||
// TokenError describes an unexpected token.
|
||||
type TokenError [2]rune
|
||||
|
||||
func (e TokenError) Error() string {
|
||||
return "expected " + scanner.TokenString(e[0]) +
|
||||
", found " + scanner.TokenString(e[1])
|
||||
}
|
||||
|
||||
// ExprError is an unexpected token encountered while parsing an expression.
|
||||
type ExprError rune
|
||||
|
||||
func (e ExprError) Error() string {
|
||||
return "unexpected token " + scanner.TokenString(rune(e))
|
||||
}
|
||||
|
||||
// must1 returns v, or panics if err is not nil.
|
||||
func must1[T any](v T, err error) T {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// parser retains the current token.
|
||||
type parser struct {
|
||||
s scanner.Scanner
|
||||
tok rune
|
||||
}
|
||||
|
||||
// scan advances the underlying scanner to the next token, storing its result.
|
||||
func (p *parser) scan() rune { p.tok = p.s.Scan(); return p.tok }
|
||||
|
||||
// scanAs advances the scanner for an expected token.
|
||||
func (p *parser) scanAs(expects rune) {
|
||||
e := TokenError{expects, p.scan()}
|
||||
if e[0] != e[1] {
|
||||
panic(e)
|
||||
}
|
||||
}
|
||||
|
||||
// parseInt parses the current token as a base 10 representation of a 64-bit
|
||||
// signed integer.
|
||||
func (p *parser) parseInt() int64 {
|
||||
return must1(strconv.ParseInt(p.s.TokenText(), 10, 64))
|
||||
}
|
||||
|
||||
// A String represents an identifier or string literal.
|
||||
type String struct {
|
||||
Value string
|
||||
Ident bool
|
||||
}
|
||||
|
||||
// A StringSpec describes a statement evaluating down to a string value.
|
||||
type StringSpec []String
|
||||
|
||||
// parseString parses the current token as a string.
|
||||
func (p *parser) parseString() string {
|
||||
return must1(strconv.Unquote(p.s.TokenText()))
|
||||
}
|
||||
|
||||
// appendStringSpec parses from the next token until the end of the StringSpec.
|
||||
// It always advances past the final token.
|
||||
func (p *parser) appendStringSpec(
|
||||
op bool,
|
||||
data StringSpec,
|
||||
) (v StringSpec, ok bool) {
|
||||
ok = true
|
||||
v = data
|
||||
for {
|
||||
if op {
|
||||
switch tok := p.scan(); tok {
|
||||
case '+':
|
||||
break
|
||||
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
switch tok := p.scan(); tok {
|
||||
case scanner.String, scanner.RawString:
|
||||
v = append(v, String{p.parseString(), false})
|
||||
|
||||
case scanner.Ident:
|
||||
v = append(v, String{p.s.TokenText(), true})
|
||||
|
||||
default:
|
||||
ok = op
|
||||
return
|
||||
}
|
||||
op = true
|
||||
}
|
||||
}
|
||||
|
||||
// A KV holds a key/value pair.
|
||||
type KV struct {
|
||||
K string
|
||||
V any
|
||||
}
|
||||
|
||||
// An Arg represents an argument of [Func].
|
||||
type Arg struct {
|
||||
K []string
|
||||
V any
|
||||
R bool
|
||||
}
|
||||
|
||||
// Func is a function call or package declaration.
|
||||
type Func struct {
|
||||
// Function or package identifier.
|
||||
Ident string
|
||||
// Whether this is a package declaration.
|
||||
Package bool
|
||||
// Key-value arguments.
|
||||
Args []Arg
|
||||
}
|
||||
|
||||
// parseExpr scans and parses the current expression. A nil return indicates
|
||||
// [scanner.EOF].
|
||||
func (p *parser) parseExpr() (any, bool) {
|
||||
switch p.tok {
|
||||
case scanner.EOF:
|
||||
return nil, false
|
||||
|
||||
case scanner.Int:
|
||||
return p.parseInt(), false
|
||||
|
||||
case scanner.String, scanner.RawString:
|
||||
v, ok := p.appendStringSpec(true, StringSpec{
|
||||
{p.parseString(), false},
|
||||
})
|
||||
if !ok {
|
||||
panic(TokenError{scanner.String, p.tok})
|
||||
}
|
||||
return v, true
|
||||
|
||||
case scanner.Ident:
|
||||
var v Func
|
||||
v.Ident = p.s.TokenText()
|
||||
if v.Package = v.Ident == "package"; v.Package {
|
||||
p.scanAs(scanner.Ident)
|
||||
v.Ident = p.s.TokenText()
|
||||
}
|
||||
|
||||
p.scan()
|
||||
switch p.tok {
|
||||
case '{':
|
||||
for {
|
||||
p.scan()
|
||||
switch p.tok {
|
||||
case '}':
|
||||
return v, false
|
||||
|
||||
case scanner.Ident:
|
||||
break
|
||||
|
||||
default:
|
||||
panic(TokenError{scanner.Ident, p.tok})
|
||||
}
|
||||
|
||||
var next bool
|
||||
arg := Arg{K: []string{p.s.TokenText()}}
|
||||
delim := true
|
||||
arg:
|
||||
for {
|
||||
p.scan()
|
||||
switch p.tok {
|
||||
case ',':
|
||||
if delim {
|
||||
delim = false
|
||||
continue
|
||||
}
|
||||
panic(ExprError(p.tok))
|
||||
|
||||
case scanner.Ident:
|
||||
if delim {
|
||||
panic(TokenError{',', p.tok})
|
||||
}
|
||||
delim = true
|
||||
arg.K = append(arg.K, p.s.TokenText())
|
||||
|
||||
default:
|
||||
break arg
|
||||
}
|
||||
}
|
||||
switch p.tok {
|
||||
case '=':
|
||||
break
|
||||
|
||||
case '*':
|
||||
arg.R = true
|
||||
p.scanAs('=')
|
||||
|
||||
default:
|
||||
panic(TokenError{'=', p.tok})
|
||||
}
|
||||
p.scan()
|
||||
arg.V, next = p.parseExpr()
|
||||
v.Args = append(v.Args, arg)
|
||||
if !next {
|
||||
p.scanAs(';')
|
||||
}
|
||||
}
|
||||
|
||||
case ';':
|
||||
return StringSpec{{v.Ident, true}}, true
|
||||
|
||||
case '+':
|
||||
s, ok := p.appendStringSpec(false, StringSpec{
|
||||
{v.Ident, true},
|
||||
})
|
||||
if !ok {
|
||||
panic(TokenError{scanner.String, p.tok})
|
||||
}
|
||||
return s, p.tok != scanner.EOF
|
||||
|
||||
case scanner.EOF:
|
||||
return StringSpec{{v.Ident, true}}, false
|
||||
|
||||
default:
|
||||
return StringSpec{{v.Ident, true}}, true
|
||||
}
|
||||
|
||||
case '{':
|
||||
var v []KV
|
||||
for {
|
||||
p.scan()
|
||||
switch p.tok {
|
||||
case '}':
|
||||
return v, false
|
||||
|
||||
case scanner.String:
|
||||
pair := KV{K: p.parseString()}
|
||||
p.scan()
|
||||
switch p.tok {
|
||||
case ';':
|
||||
break
|
||||
|
||||
case ':':
|
||||
var next bool
|
||||
p.scan()
|
||||
pair.V, next = p.parseExpr()
|
||||
if !next {
|
||||
p.scanAs(';')
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
panic(ExprError(p.tok))
|
||||
}
|
||||
v = append(v, pair)
|
||||
|
||||
default:
|
||||
panic(ExprError(p.tok))
|
||||
}
|
||||
}
|
||||
|
||||
case '[':
|
||||
var (
|
||||
v []any
|
||||
e any
|
||||
delim bool
|
||||
next bool
|
||||
)
|
||||
for {
|
||||
if !next {
|
||||
p.scan()
|
||||
}
|
||||
switch p.tok {
|
||||
case ',':
|
||||
if delim {
|
||||
delim = false
|
||||
next = false
|
||||
continue
|
||||
}
|
||||
panic(ExprError(','))
|
||||
case ']':
|
||||
return v, false
|
||||
case scanner.EOF:
|
||||
panic(ExprError(scanner.EOF))
|
||||
default:
|
||||
if delim {
|
||||
panic(TokenError{',', p.tok})
|
||||
}
|
||||
delim = true
|
||||
break
|
||||
}
|
||||
|
||||
e, next = p.parseExpr()
|
||||
v = append(v, e)
|
||||
}
|
||||
|
||||
default:
|
||||
panic(ExprError(p.tok))
|
||||
}
|
||||
}
|
||||
|
||||
// ScanError is the error count parsing all expressions.
|
||||
type ScanError int
|
||||
|
||||
func (ScanError) Error() string {
|
||||
return "aborting due to scanning errors"
|
||||
}
|
||||
|
||||
// Parse parses expressions from r.
|
||||
func Parse(r io.Reader) (e []any, err error) {
|
||||
var p parser
|
||||
p.s.Init(r)
|
||||
|
||||
p.s.Mode = scanner.ScanIdents |
|
||||
scanner.ScanInts |
|
||||
scanner.ScanStrings |
|
||||
scanner.ScanRawStrings |
|
||||
scanner.ScanComments |
|
||||
scanner.SkipComments
|
||||
p.s.IsIdentRune = func(ch rune, i int) bool {
|
||||
if i == 0 && ch >= '0' && ch <= '9' {
|
||||
return false
|
||||
}
|
||||
return ch > 0 && ch < rune(len(idents)) && idents[ch]
|
||||
}
|
||||
|
||||
defer func() {
|
||||
v := recover()
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
|
||||
_err, ok := v.(error)
|
||||
if !ok {
|
||||
panic(v)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
err = _err
|
||||
return
|
||||
}
|
||||
err = errors.Join(err, _err)
|
||||
}()
|
||||
|
||||
p.scan()
|
||||
for {
|
||||
expr, next := p.parseExpr()
|
||||
if expr == nil {
|
||||
break
|
||||
}
|
||||
e = append(e, expr)
|
||||
if !next {
|
||||
p.scan()
|
||||
}
|
||||
}
|
||||
|
||||
if p.s.ErrorCount != 0 {
|
||||
err = ScanError(p.s.ErrorCount)
|
||||
}
|
||||
return
|
||||
}
|
||||
149
internal/rosa/azalea/azalea_test.go
Normal file
149
internal/rosa/azalea/azalea_test.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package azalea_test
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"text/scanner"
|
||||
|
||||
"hakurei.app/internal/rosa/azalea"
|
||||
)
|
||||
|
||||
//go:embed testdata/gcc.az
|
||||
var sample string
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
data string
|
||||
want []any
|
||||
err error
|
||||
}{
|
||||
{"invalid", "}", nil, azalea.ExprError('}')},
|
||||
{"bad sep", "f{v?}", nil, azalea.TokenError{'=', '?'}},
|
||||
{"bad ident", "f{9}", nil, azalea.TokenError{scanner.Ident, scanner.Int}},
|
||||
{"share bad sep", "f { v,,v = v; }", nil, azalea.ExprError(',')},
|
||||
{"share missing sep", "f { v v }", nil, azalea.TokenError{',', scanner.Ident}},
|
||||
|
||||
{"ident string", `v`, []any{azalea.StringSpec{
|
||||
{Value: "v", Ident: true},
|
||||
}}, nil},
|
||||
{"ident string concat", `v+"\xfd"`, []any{azalea.StringSpec{
|
||||
{Value: "v", Ident: true},
|
||||
{Value: "\xfd"},
|
||||
}}, nil},
|
||||
{"truncated string concat", `v+`, nil,
|
||||
azalea.TokenError{scanner.String, scanner.EOF}},
|
||||
{"unexpected string concat", `v+9`, nil,
|
||||
azalea.TokenError{scanner.String, scanner.Int}},
|
||||
|
||||
{"empty pairs", `{}`, []any{[]azalea.KV(nil)}, nil},
|
||||
{"short kv", `{"\x00":v;}`, []any{[]azalea.KV{
|
||||
{K: "\x00", V: azalea.StringSpec{azalea.String{Value: "v", Ident: true}}},
|
||||
}}, nil},
|
||||
{"truncated kv", `{"\x00"`, nil, azalea.ExprError(scanner.EOF)},
|
||||
{"ident kv", `{v="";}`, nil, azalea.ExprError(scanner.Ident)},
|
||||
|
||||
{"empty array", `[]`, []any{[]any(nil)}, nil},
|
||||
{"integer array", `[9]`, []any{[]any{int64(9)}}, nil},
|
||||
{"short array", `[ "\x00" ]`, []any{
|
||||
[]any{azalea.StringSpec{{Value: "\x00"}}},
|
||||
}, nil},
|
||||
{"short array delim", `[ "\x00", ]`, []any{
|
||||
[]any{azalea.StringSpec{{Value: "\x00"}}},
|
||||
}, nil},
|
||||
{"missing array value", `[ "\x00", , v ]`, nil, azalea.ExprError(',')},
|
||||
{"missing array delimiter", `[ v0 v1 ]`, nil, azalea.TokenError{',', scanner.Ident}},
|
||||
{"truncated array", `[ "\x00"`, nil,
|
||||
azalea.ExprError(scanner.EOF)},
|
||||
|
||||
{"gcc", sample, []any{azalea.Func{
|
||||
Ident: "gcc",
|
||||
Package: true,
|
||||
|
||||
Args: []azalea.Arg{
|
||||
{K: []string{"description"}, V: azalea.StringSpec{{Value: "The GNU Compiler Collection"}}},
|
||||
{K: []string{"website"}, V: azalea.StringSpec{{Value: "https://www.gnu.org/software/gcc"}}},
|
||||
{K: []string{"anitya"}, V: int64(6502)},
|
||||
{K: []string{"version"}, V: azalea.StringSpec{{Value: "16.1.0"}}, R: true},
|
||||
{K: []string{"source"}, V: azalea.Func{Ident: "remoteTar", Package: false, Args: []azalea.Arg{
|
||||
{K: []string{"url"}, V: azalea.StringSpec{
|
||||
{Value: "https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"},
|
||||
{Value: "gcc-"}, {Value: "version", Ident: true},
|
||||
{Value: "/gcc-"}, {Value: "version", Ident: true},
|
||||
{Value: ".tar.gz"},
|
||||
}},
|
||||
{K: []string{"checksum"}, V: azalea.StringSpec{
|
||||
{Value: "4ASoWbxaA2FW7PAB0zzHDPC5XnNhyaAyjtDPpGzceSLeYnEIXsNYZR3PA_Zu5P0K"},
|
||||
}},
|
||||
{K: []string{"compress"}, V: azalea.StringSpec{{Value: "gzip", Ident: true}}},
|
||||
}}},
|
||||
{K: []string{"patches"}, V: []any{
|
||||
azalea.StringSpec{{Value: "musl-off64_t-loff_t.patch"}},
|
||||
azalea.StringSpec{{Value: "musl-legacy-lfs.patch"}},
|
||||
}},
|
||||
{K: []string{"exclusive"}, V: azalea.StringSpec{{Value: "true", Ident: true}}},
|
||||
{K: []string{"exec"}, V: azalea.Func{
|
||||
Ident: "make",
|
||||
|
||||
Args: []azalea.Arg{
|
||||
{K: []string{"configure"}, V: []azalea.KV{
|
||||
{K: "disable-multilib"},
|
||||
{K: "enable-default-pie"},
|
||||
{K: "disable-nls"},
|
||||
{K: "with-gnu-as"},
|
||||
{K: "with-gnu-ld"},
|
||||
{K: "with-system-zlib"},
|
||||
{K: "enable-languages", V: azalea.StringSpec{{Value: "c,c++,go"}}},
|
||||
{K: "with-native-system-header-dir", V: azalea.StringSpec{{Value: "/system/include"}}},
|
||||
{K: "with-multilib-list", V: azalea.Func{
|
||||
Ident: "arch",
|
||||
|
||||
Args: []azalea.Arg{
|
||||
{K: []string{"amd64", "arm64"}, V: azalea.StringSpec{{Value: "''"}}},
|
||||
{K: []string{"default"}, V: azalea.StringSpec{{Value: "unset", Ident: true}}},
|
||||
},
|
||||
}},
|
||||
}},
|
||||
{K: []string{"make"}, V: []any{
|
||||
azalea.StringSpec{{Value: "BOOT_CFLAGS='-O2 -g'"}},
|
||||
azalea.Func{
|
||||
Ident: "noop",
|
||||
Args: []azalea.Arg{
|
||||
{K: []string{"key"}, V: azalea.StringSpec{
|
||||
{Value: "value", Ident: true},
|
||||
}},
|
||||
},
|
||||
},
|
||||
azalea.StringSpec{{Value: "bootstrap"}},
|
||||
}},
|
||||
{K: []string{"skip-check"}, V: azalea.StringSpec{{Value: "true", Ident: true}}},
|
||||
},
|
||||
}},
|
||||
{K: []string{"inputs"}, V: []any{
|
||||
azalea.StringSpec{{Value: "binutils", Ident: true}},
|
||||
azalea.StringSpec{{Value: "mpc", Ident: true}},
|
||||
azalea.StringSpec{{Value: "zlib", Ident: true}},
|
||||
azalea.StringSpec{{Value: "libucontext", Ident: true}},
|
||||
azalea.StringSpec{{Value: "kernel-headers", Ident: true}},
|
||||
}},
|
||||
},
|
||||
}}, nil},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p, err := azalea.Parse(strings.NewReader(tc.data))
|
||||
if !reflect.DeepEqual(p, tc.want) {
|
||||
t.Errorf("Parse: %#v, want %#v", p, tc.want)
|
||||
}
|
||||
if !reflect.DeepEqual(err, tc.err) {
|
||||
t.Errorf("Parse: error = %v, want %v", err, tc.err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
57
internal/rosa/azalea/testdata/gcc.az
vendored
Normal file
57
internal/rosa/azalea/testdata/gcc.az
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package gcc {
|
||||
description = "The GNU Compiler Collection";
|
||||
website = "https://www.gnu.org/software/gcc";
|
||||
anitya = 6502;
|
||||
|
||||
version* = "16.1.0";
|
||||
source = remoteTar {
|
||||
url = "https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"+
|
||||
"gcc-"+version+"/gcc-"+version+".tar.gz";
|
||||
checksum = "4ASoWbxaA2FW7PAB0zzHDPC5XnNhyaAyjtDPpGzceSLeYnEIXsNYZR3PA_Zu5P0K";
|
||||
compress = gzip;
|
||||
};
|
||||
patches = [
|
||||
"musl-off64_t-loff_t.patch",
|
||||
"musl-legacy-lfs.patch",
|
||||
];
|
||||
|
||||
// GCC spends most of its time in its many configure scripts, however
|
||||
// it also saturates the CPU for a consequential amount of time.
|
||||
exclusive = true;
|
||||
|
||||
exec = make {
|
||||
configure = {
|
||||
"disable-multilib";
|
||||
"enable-default-pie";
|
||||
"disable-nls";
|
||||
"with-gnu-as";
|
||||
"with-gnu-ld";
|
||||
"with-system-zlib";
|
||||
"enable-languages": "c,c++,go";
|
||||
"with-native-system-header-dir": "/system/include";
|
||||
"with-multilib-list": arch {
|
||||
amd64, arm64 = "''";
|
||||
default = unset;
|
||||
};
|
||||
};
|
||||
make = [
|
||||
"BOOT_CFLAGS='-O2 -g'",
|
||||
noop { key = value; },
|
||||
"bootstrap",
|
||||
];
|
||||
|
||||
// This toolchain is hacked to pieces, it is not expected to ever work
|
||||
// well in its current state. That does not matter as long as the
|
||||
// toolchain it produces passes its own test suite.
|
||||
skip-check = true;
|
||||
};
|
||||
|
||||
inputs = [
|
||||
binutils,
|
||||
|
||||
mpc,
|
||||
zlib,
|
||||
libucontext,
|
||||
kernel-headers,
|
||||
];
|
||||
}
|
||||
27
internal/rosa/freetype.go
Normal file
27
internal/rosa/freetype.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newFreetype() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "2.14.3"
|
||||
checksum = "-WfLv8fVJNyCHpP_lriiDzOcVbBL9ajdQ3tl8AzIIUa9-8sVpU9irxOmSMgRHWYz"
|
||||
)
|
||||
return t.NewPackage("freetype", version, newTar(
|
||||
"https://download.savannah.gnu.org/releases/freetype/"+
|
||||
"freetype-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil)), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Freetype] = Metadata{
|
||||
f: Toolchain.newFreetype,
|
||||
|
||||
Name: "freetype",
|
||||
Description: "a freely available software library to render fonts",
|
||||
Website: "http://www.freetype.org/",
|
||||
|
||||
ID: 854,
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ disable_test t7002-mv-sparse-checkout
|
||||
disable_test t1451-fsck-buffer
|
||||
disable_test t4104-apply-boundary
|
||||
disable_test t4200-rerere
|
||||
disable_test t5515-fetch-merge-logic
|
||||
`,
|
||||
Check: []string{
|
||||
"-C t",
|
||||
|
||||
@@ -189,9 +189,18 @@ func (t Toolchain) newSPIRVLLVMTranslator() (pkg.Artifact, string) {
|
||||
), &PackageAttr{
|
||||
Patches: []KV{
|
||||
{"remove-early-prefix", `diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index c000a77e..86f79b03 100644
|
||||
index c000a77e..f18f3fde 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -164,7 +164,7 @@ install(
|
||||
${LLVM_SPIRV_INCLUDE_DIRS}/LLVMSPIRVOpts.h
|
||||
${LLVM_SPIRV_INCLUDE_DIRS}/LLVMSPIRVExtensions.inc
|
||||
DESTINATION
|
||||
- ${CMAKE_INSTALL_PREFIX}/include/LLVMSPIRVLib
|
||||
+ include/LLVMSPIRVLib
|
||||
)
|
||||
|
||||
configure_file(LLVMSPIRVLib.pc.in ${CMAKE_BINARY_DIR}/LLVMSPIRVLib.pc @ONLY)
|
||||
@@ -172,5 +172,5 @@ install(
|
||||
FILES
|
||||
${CMAKE_BINARY_DIR}/LLVMSPIRVLib.pc
|
||||
@@ -199,7 +208,7 @@ index c000a77e..86f79b03 100644
|
||||
- ${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}/pkgconfig
|
||||
+ lib${LLVM_LIBDIR_SUFFIX}/pkgconfig
|
||||
)
|
||||
`},
|
||||
;`},
|
||||
},
|
||||
|
||||
// litArgs emits shell syntax
|
||||
|
||||
33
internal/rosa/libepoxy.go
Normal file
33
internal/rosa/libepoxy.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newLibepoxy() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.5.10"
|
||||
checksum = "OHI8wshrlGw6BMGrmSyejJtwzM2gPhyFJrTsKxULyKMmYrfgcOe7Iw2ibVoUND_Q"
|
||||
)
|
||||
return t.NewPackage("libepoxy", version, newFromGitHub(
|
||||
"anholt/libepoxy",
|
||||
version,
|
||||
checksum,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
{"Dglx", "no"},
|
||||
{"Degl", "no"},
|
||||
},
|
||||
},
|
||||
LibX11,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Libepoxy] = Metadata{
|
||||
f: Toolchain.newLibepoxy,
|
||||
|
||||
Name: "libepoxy",
|
||||
Description: "a library for handling OpenGL function pointer management",
|
||||
Website: "https://github.com/anholt/libepoxy",
|
||||
|
||||
ID: 6090,
|
||||
}
|
||||
}
|
||||
44
internal/rosa/libtirpc.go
Normal file
44
internal/rosa/libtirpc.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package rosa
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"hakurei.app/internal/pkg"
|
||||
)
|
||||
|
||||
func (t Toolchain) newLibtirpc() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.3.7"
|
||||
checksum = "nzFfu7LNvnSNiNAryD1vtnNWnU-Xqee8KqfXUKoBf5yjb5-dkeRkYuRijdCoYLof"
|
||||
)
|
||||
return t.NewPackage("libtirpc", version, t.newTagRemote(
|
||||
"git://linux-nfs.org/~steved/libtirpc",
|
||||
"libtirpc-"+
|
||||
strings.Join(strings.SplitN(version, ".", 3), "-"),
|
||||
checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "sh -e ./bootstrap",
|
||||
Configure: []KV{
|
||||
{"CFLAGS", `"$(pkg-config --cflags libbsd-overlay) ${CFLAGS:-}"`},
|
||||
{"disable-gssapi"},
|
||||
},
|
||||
},
|
||||
Automake,
|
||||
Libtool,
|
||||
PkgConfig,
|
||||
|
||||
Libbsd,
|
||||
KernelHeaders,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Libtirpc] = Metadata{
|
||||
f: Toolchain.newLibtirpc,
|
||||
|
||||
Name: "libtirpc",
|
||||
Description: "a port of Suns Transport-Independent RPC library to Linux",
|
||||
Website: "https://sourceforge.net/projects/libtirpc/",
|
||||
|
||||
ID: 1740,
|
||||
}
|
||||
}
|
||||
59
internal/rosa/lm-sensors.go
Normal file
59
internal/rosa/lm-sensors.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newLMSensors() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "3-6-2"
|
||||
checksum = "7JYNutrihe-FP6r3ftf96uFZJJWPfxnBHL0ALSMA-vovaXVRr-sAjlLitw7WWpCI"
|
||||
)
|
||||
return t.NewPackage("lm_sensors", version, newFromGitHub(
|
||||
"lm-sensors/lm-sensors",
|
||||
"V"+version,
|
||||
checksum,
|
||||
), &PackageAttr{
|
||||
Writable: true,
|
||||
Chmod: true,
|
||||
EnterSource: true,
|
||||
|
||||
ScriptEarly: `
|
||||
ln -s \
|
||||
../../system/bin/perl \
|
||||
/usr/bin/
|
||||
`,
|
||||
}, &MakeHelper{
|
||||
InPlace: true,
|
||||
SkipConfigure: true,
|
||||
|
||||
Make: []string{
|
||||
"CC=cc",
|
||||
"ETCDIR=/system/etc",
|
||||
"PREFIX=/system",
|
||||
},
|
||||
|
||||
Check: []string{
|
||||
"CC=cc",
|
||||
"check",
|
||||
},
|
||||
|
||||
Install: "make DESTDIR=/work PREFIX=/system install",
|
||||
},
|
||||
Perl,
|
||||
PerlTestCmd,
|
||||
|
||||
M4,
|
||||
Bison,
|
||||
Flex,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[LMSensors] = Metadata{
|
||||
f: Toolchain.newLMSensors,
|
||||
|
||||
Name: "lm_sensors",
|
||||
Description: "user-space support for hardware monitoring drivers",
|
||||
Website: "https://hwmon.wiki.kernel.org/lm_sensors",
|
||||
|
||||
ID: 1831,
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"hakurei.app/internal/pkg"
|
||||
)
|
||||
|
||||
func (t Toolchain) newLibglvnd() (pkg.Artifact, string) {
|
||||
const (
|
||||
@@ -12,8 +16,22 @@ func (t Toolchain) newLibglvnd() (pkg.Artifact, string) {
|
||||
"glvnd/libglvnd",
|
||||
"v"+version,
|
||||
checksum,
|
||||
), nil, (*MesonHelper)(nil),
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
{"Dx11", "enabled"},
|
||||
{"Dglx", "enabled"},
|
||||
},
|
||||
ScriptCompiled: `
|
||||
export DISPLAY=':0'
|
||||
Xvfb &
|
||||
XVFB_PID="$!"
|
||||
trap 'kill $XVFB_PID && wait $XVFB_PID' EXIT
|
||||
`,
|
||||
},
|
||||
Binutils, // symbols check fail with llvm nm
|
||||
Xserver, // test suite wants X server
|
||||
|
||||
LibXext,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
@@ -24,6 +42,10 @@ func init() {
|
||||
Description: "The GL Vendor-Neutral Dispatch library",
|
||||
Website: "https://gitlab.freedesktop.org/glvnd/libglvnd",
|
||||
|
||||
Dependencies: P{
|
||||
LibXext,
|
||||
},
|
||||
|
||||
ID: 12098,
|
||||
}
|
||||
}
|
||||
@@ -64,3 +86,180 @@ func init() {
|
||||
ID: 1596,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibva() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "2.23.0"
|
||||
checksum = "UmF5tPyWIG_w5kiR3KFpoYbF7UUcaak5tyc-RhOheNTwQlLkPlifreFYCM9FQxbq"
|
||||
)
|
||||
return t.NewPackage("libva", version, newFromGitHub(
|
||||
"intel/libva",
|
||||
version,
|
||||
checksum,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
{"Dwith_x11", "yes"},
|
||||
{"Dwith_glx", "yes"},
|
||||
{"Dwith_wayland", "yes"},
|
||||
},
|
||||
},
|
||||
Libdrm,
|
||||
LibXfixes,
|
||||
Libglvnd,
|
||||
Wayland,
|
||||
KernelHeaders,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Libva] = Metadata{
|
||||
f: Toolchain.newLibva,
|
||||
|
||||
Name: "libva",
|
||||
Description: "an implementation for VA-API (Video Acceleration API)",
|
||||
Website: "https://01.org/vaapi",
|
||||
|
||||
Dependencies: P{
|
||||
Libdrm,
|
||||
LibXfixes,
|
||||
Libglvnd,
|
||||
Wayland,
|
||||
},
|
||||
|
||||
ID: 1752,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newMesa() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "26.1.0"
|
||||
checksum = "zU0fjqevySBaoi_5SLW3e2UffmGeBdxOuHmAHTH68n2hV-sjYoqg30koLqFXuk5y"
|
||||
)
|
||||
return t.NewPackage("mesa", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"mesa/mesa",
|
||||
"mesa-"+version,
|
||||
checksum,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
{"Dplatforms", "x11,wayland"},
|
||||
{"Dvideo-codecs", "all"},
|
||||
|
||||
{"Dglvnd", "enabled"},
|
||||
{"Dgbm", "enabled"},
|
||||
|
||||
{"Dgallium-drivers", strings.Join([]string{
|
||||
"asahi", // Apple AGX
|
||||
"crocus", // Intel legacy
|
||||
"etnaviv", // Vivante GPU designs (mostly NXP/Marvell SoCs)
|
||||
"freedreno", // Qualcomm Adreno (all Qualcomm SoCs)
|
||||
"i915", // Intel extra legacy
|
||||
"iris", // new Intel (Broadwell+)
|
||||
"lima", // ARM Mali 4xx
|
||||
"llvmpipe", // software renderer
|
||||
"nouveau", // Nvidia
|
||||
"panfrost", // ARM Mali Midgard and up (T/G series)
|
||||
"r300", // very old AMD
|
||||
"r600", // less old AMD
|
||||
"radeonsi", // new AMD (GCN+)
|
||||
"softpipe", // older software renderer
|
||||
"svga", // VMWare virtualized GPU
|
||||
"tegra", // Nvidia Tegra SoCs
|
||||
"v3d", // Broadcom VC5 (Raspberry Pi 4)
|
||||
"vc4", // Broadcom VC4 (Raspberry Pi 0-3)
|
||||
"virgl", // QEMU virtualized GPU (aka VirGL)
|
||||
"zink", // generic OpenGL over Vulkan, experimental
|
||||
|
||||
// d3d12: WSL emulated GPU (aka Dozen)
|
||||
// ethosu: accelerator
|
||||
// rocket: accelerator
|
||||
}, ",")},
|
||||
|
||||
{"Dvulkan-drivers", strings.Join([]string{
|
||||
"amd", // AMD (aka RADV)
|
||||
"broadcom", // Broadcom VC5 (Raspberry Pi 4, aka V3D)
|
||||
"freedreno", // Qualcomm Adreno (all Qualcomm SoCs)
|
||||
"intel", // new Intel (aka ANV)
|
||||
"intel_hasvk", // Intel Haswell/Broadwell, "legacy" Vulkan driver (https://www.phoronix.com/news/Intel-HasVK-Drop-Dead-Code)
|
||||
"panfrost", // ARM Mali Midgard and up (T/G series)
|
||||
"swrast", // software renderer (aka Lavapipe)
|
||||
"virtio", // QEMU virtualized GPU (aka VirGL)
|
||||
"imagination", // PowerVR Rogue
|
||||
"asahi", // Apple AGX
|
||||
"gfxstream", // Android virtualized GPU
|
||||
|
||||
// nouveau: Nouveau (aka NVK), requires rust
|
||||
// microsoft-experimental: WSL virtualized GPU (aka DZN/Dozen)
|
||||
// kosmickrisp: macOS-specific
|
||||
}, ",")},
|
||||
{"Dvulkan-layers", strings.Join([]string{
|
||||
"device-select",
|
||||
"intel-nullhw",
|
||||
"overlay",
|
||||
"screenshot",
|
||||
"anti-lag",
|
||||
"vram-report-limit",
|
||||
}, ",")},
|
||||
|
||||
{"Dfreedreno-kmds", "msm,virtio"},
|
||||
{"Damdgpu-virtio", "true"},
|
||||
},
|
||||
},
|
||||
M4,
|
||||
PythonPackaging,
|
||||
PythonMako,
|
||||
PythonPyYAML,
|
||||
PythonPycparser,
|
||||
Glslang,
|
||||
SPIRVLLVMTranslator,
|
||||
|
||||
Zlib,
|
||||
Zstd,
|
||||
Gzip,
|
||||
Ncurses,
|
||||
Libglvnd,
|
||||
Libexpat,
|
||||
Libva,
|
||||
Libdrm,
|
||||
Elfutils,
|
||||
Bison,
|
||||
Flex,
|
||||
LMSensors,
|
||||
Libconfig,
|
||||
LibdisplayInfo,
|
||||
Wayland,
|
||||
WaylandProtocols,
|
||||
Libxshmfence,
|
||||
LibXxf86vm,
|
||||
LibXrandr,
|
||||
LibxcbUtilKeysyms,
|
||||
Libpng,
|
||||
Libarchive,
|
||||
KernelHeaders,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Mesa] = Metadata{
|
||||
f: Toolchain.newMesa,
|
||||
|
||||
Name: "mesa",
|
||||
Description: "open source implementations of OpenGL, OpenGL ES, Vulkan, OpenCL, and more",
|
||||
Website: "https://mesa3d.org",
|
||||
|
||||
Dependencies: P{
|
||||
Libdrm,
|
||||
Elfutils,
|
||||
LMSensors,
|
||||
LibdisplayInfo,
|
||||
Wayland,
|
||||
Libxshmfence,
|
||||
LibXxf86vm,
|
||||
LibXrandr,
|
||||
LibxcbUtilKeysyms,
|
||||
Libpng,
|
||||
},
|
||||
|
||||
ID: 1970,
|
||||
|
||||
latest: (*Versions).getStable,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,3 +382,27 @@ func init() {
|
||||
ID: 3549,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newPerlTestCmd() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.09"
|
||||
checksum = "gpGUwyC9IozDiYSgW_kXARNfXsTPFa6cTowJmmCBbPqcs2-pONZca_SB06FGy-7H"
|
||||
)
|
||||
return t.newViaPerlMakeMaker("Test::Cmd", version, newFromCPAN(
|
||||
"NEILB",
|
||||
"Test-Cmd",
|
||||
version,
|
||||
checksum,
|
||||
), nil), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[PerlTestCmd] = Metadata{
|
||||
f: Toolchain.newPerlTestCmd,
|
||||
|
||||
Name: "perl-Test::Cmd",
|
||||
Description: "portable testing of commands and scripts",
|
||||
Website: "https://metacpan.org/release/Test-Cmd",
|
||||
|
||||
ID: 6014,
|
||||
}
|
||||
}
|
||||
|
||||
31
internal/rosa/pixman.go
Normal file
31
internal/rosa/pixman.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newPixman() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.46.4"
|
||||
checksum = "iECDxLG9SxUrvGHqeDoaBa-b3uqdT5DC4zudjtrwb8Wodq82pyacmFNEAo4SDsiE"
|
||||
)
|
||||
return t.NewPackage("pixman", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"pixman/pixman",
|
||||
"pixman-"+version,
|
||||
checksum,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
{"Dtests", "enabled"},
|
||||
},
|
||||
}), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Pixman] = Metadata{
|
||||
f: Toolchain.newPixman,
|
||||
|
||||
Name: "pixman",
|
||||
Description: "a low-level software library for pixel manipulation",
|
||||
Website: "https://pixman.org/",
|
||||
|
||||
ID: 3648,
|
||||
}
|
||||
}
|
||||
@@ -186,12 +186,12 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newXCBUtilKeysyms() (pkg.Artifact, string) {
|
||||
func (t Toolchain) newLibxcbUtilKeysyms() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.4.1"
|
||||
checksum = "-EEje12UEjtFBuIjb6Fy4cxEghV20BXwQ1BLvhtvSuVcrFkp_X-ZHRM48wAspXZ4"
|
||||
)
|
||||
return t.NewPackage("xcb-util-keysyms", version, newTar(
|
||||
return t.NewPackage("libxcb-util-keysyms", version, newTar(
|
||||
"https://xcb.freedesktop.org/dist/xcb-util-keysyms-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
@@ -202,10 +202,10 @@ func (t Toolchain) newXCBUtilKeysyms() (pkg.Artifact, string) {
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[XCBUtilKeysyms] = Metadata{
|
||||
f: Toolchain.newXCBUtilKeysyms,
|
||||
artifactsM[LibxcbUtilKeysyms] = Metadata{
|
||||
f: Toolchain.newLibxcbUtilKeysyms,
|
||||
|
||||
Name: "xcb-util-keysyms",
|
||||
Name: "libxcb-util-keysyms",
|
||||
Description: "standard X key constants and conversion to/from keycodes",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/lib/libxcb-keysyms",
|
||||
|
||||
@@ -217,6 +217,135 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibxcbUtilImage() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.4.1"
|
||||
checksum = "47pvXmFwaUBZIrJ4CE9xjTQIFyxeqoNAL-DshlB11GZ_jjI3G1a6KF0K7mtBQ1E7"
|
||||
)
|
||||
return t.NewPackage("libxcb-util-image", version, newTar(
|
||||
"https://xcb.freedesktop.org/dist/xcb-util-image-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
PkgConfig,
|
||||
|
||||
LibxcbUtil,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[LibxcbUtilImage] = Metadata{
|
||||
f: Toolchain.newLibxcbUtilImage,
|
||||
|
||||
Name: "libxcb-util-image",
|
||||
Description: "XCB port of Xlib's XImage and XShmImage functions",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/lib/libxcb-image",
|
||||
|
||||
Dependencies: P{
|
||||
LibxcbUtil,
|
||||
},
|
||||
|
||||
ID: 5168,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibxcbUtilWM() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.4.2"
|
||||
checksum = "g0VZgMU9hcIgyXb3XxBR9xqsvUMBd9qt_Dbmwoj2h5y24pODr_S_D0DhRsuXUNjF"
|
||||
)
|
||||
return t.NewPackage("libxcb-util-wm", version, newTar(
|
||||
"https://xcb.freedesktop.org/dist/xcb-util-wm-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
M4,
|
||||
PkgConfig,
|
||||
|
||||
XCB,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[LibxcbUtilWM] = Metadata{
|
||||
f: Toolchain.newLibxcbUtilWM,
|
||||
|
||||
Name: "libxcb-util-wm",
|
||||
Description: "XCB client and window-manager helpers for ICCCM & EWMH",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/lib/libxcb-wm",
|
||||
|
||||
Dependencies: P{
|
||||
XCB,
|
||||
},
|
||||
|
||||
ID: 5170,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibxcbUtil() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.4.1"
|
||||
checksum = "YMXGQUQbF6PoEAGflvYnJYsLWjti6sL_ifY47wIXTNGVM3tQ8u41nkBYN4K1D5CD"
|
||||
)
|
||||
return t.NewPackage("libxcb-util", version, newTar(
|
||||
"https://www.x.org/releases/individual/xcb/"+
|
||||
"xcb-util-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
PkgConfig,
|
||||
|
||||
utilMacros,
|
||||
XCB,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[LibxcbUtil] = Metadata{
|
||||
f: Toolchain.newLibxcbUtil,
|
||||
|
||||
Name: "libxcb-util",
|
||||
Description: "XCB utility libraries",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/lib/libxcb-util",
|
||||
|
||||
Dependencies: P{
|
||||
XCB,
|
||||
},
|
||||
|
||||
ID: 5165,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibxcbRenderUtil() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.3.10"
|
||||
checksum = "n08L8PyCoOd7v2vb6fSVq5Pq6JtteXVh9K2wrQMTNwGMf_Fjpi6i3HWF-TMFSVTI"
|
||||
)
|
||||
return t.NewPackage("libxcb-render-util", version, newTar(
|
||||
"https://www.x.org/releases/individual/xcb/"+
|
||||
"xcb-util-renderutil-"+version+".tar.gz",
|
||||
checksum,
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
PkgConfig,
|
||||
|
||||
utilMacros,
|
||||
XCB,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[LibxcbRenderUtil] = Metadata{
|
||||
f: Toolchain.newLibxcbRenderUtil,
|
||||
|
||||
Name: "libxcb-render-util",
|
||||
Description: "XCB convenience functions for the Render extension",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/lib/libxcb-render-util",
|
||||
|
||||
Dependencies: P{
|
||||
XCB,
|
||||
},
|
||||
|
||||
ID: 5169,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibX11() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.8.13"
|
||||
@@ -298,6 +427,44 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibXfixes() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "6.0.2"
|
||||
checksum = "_-kJfKZ7cE3NNeMr6NLSXCmsyP7MVEHVPLNfxatz2qBy3_fZJvPMQwZNOC9y6V5L"
|
||||
)
|
||||
return t.NewPackage("libXfixes", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xorg/lib/libxfixes",
|
||||
"libXfixes-"+version,
|
||||
checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "NOCONFIGURE=1 ./autogen.sh",
|
||||
},
|
||||
Automake,
|
||||
Libtool,
|
||||
PkgConfig,
|
||||
|
||||
utilMacros,
|
||||
XorgProto,
|
||||
LibX11,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[LibXfixes] = Metadata{
|
||||
f: Toolchain.newLibXfixes,
|
||||
|
||||
Name: "libXfixes",
|
||||
Description: "Xlib-based library for the XFIXES Extension",
|
||||
Website: "https://www.freedesktop.org/wiki/Software/FixesExt/",
|
||||
|
||||
Dependencies: P{
|
||||
LibX11,
|
||||
},
|
||||
|
||||
ID: 1775,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibXrender() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.9.12"
|
||||
@@ -446,6 +613,264 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newFontUtil() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.4.2"
|
||||
checksum = "YWiaIxkq-N2yNdbGa_RF1S0UkQq6xsgoRT73WZP2DOmyH_CJ0TAkpQjId657MQmh"
|
||||
)
|
||||
return t.NewPackage("font-util", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xorg/font/util",
|
||||
"font-util-"+version,
|
||||
checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "NOCONFIGURE=1 ./autogen.sh",
|
||||
},
|
||||
Automake,
|
||||
Libtool,
|
||||
PkgConfig,
|
||||
|
||||
utilMacros,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[FontUtil] = Metadata{
|
||||
f: Toolchain.newFontUtil,
|
||||
|
||||
Name: "font-util",
|
||||
Description: "X.Org font package creation/installation utilities",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/font/util",
|
||||
|
||||
ID: 15055,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibfontenc() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.1.9"
|
||||
checksum = "XqosXfbVwaoYzG9vVyRCl3eatwjASoJdLZsxQ37NN8S_jTyqNmbxpRSJGImJj7RS"
|
||||
)
|
||||
return t.NewPackage("libfontenc", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xorg/lib/libfontenc",
|
||||
"libfontenc-"+version,
|
||||
checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "NOCONFIGURE=1 ./autogen.sh",
|
||||
},
|
||||
Automake,
|
||||
Libtool,
|
||||
PkgConfig,
|
||||
|
||||
utilMacros,
|
||||
FontUtil,
|
||||
XorgProto,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Libfontenc] = Metadata{
|
||||
f: Toolchain.newLibfontenc,
|
||||
|
||||
Name: "libfontenc",
|
||||
Description: "X font encoding library",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/lib/libfontenc",
|
||||
|
||||
ID: 1613,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibxkbfile() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.2.0"
|
||||
checksum = "WUtph1ab0AyATahlwljchBxZJcpjYrjyhCK9DW2VO0uXEXaN22GWmUaibcA83i_B"
|
||||
)
|
||||
return t.NewPackage("libxkbfile", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xorg/lib/libxkbfile",
|
||||
"libxkbfile-"+version,
|
||||
checksum,
|
||||
), nil, (*MesonHelper)(nil),
|
||||
LibX11,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Libxkbfile] = Metadata{
|
||||
f: Toolchain.newLibxkbfile,
|
||||
|
||||
Name: "libxkbfile",
|
||||
Description: "XKB file handling routines",
|
||||
Website: "http://www.x.org/wiki/XKB",
|
||||
|
||||
Dependencies: P{
|
||||
LibX11,
|
||||
},
|
||||
|
||||
ID: 1781,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newXkbcomp() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.5.0"
|
||||
checksum = "ttICW8ZPbljI-nw2kknvxFhwFoDK40iAMBeZDLAHYsHf3B6UPO_zc9TpzZYRRyZH"
|
||||
)
|
||||
return t.NewPackage("xkbcomp", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xorg/app/xkbcomp",
|
||||
"xkbcomp-"+version,
|
||||
checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "NOCONFIGURE=1 ./autogen.sh",
|
||||
},
|
||||
Automake,
|
||||
Libtool,
|
||||
PkgConfig,
|
||||
Bison,
|
||||
|
||||
utilMacros,
|
||||
Libxkbfile,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Xkbcomp] = Metadata{
|
||||
f: Toolchain.newXkbcomp,
|
||||
|
||||
Name: "xkbcomp",
|
||||
Description: "XKB keyboard description compiler",
|
||||
Website: "http://www.x.org/wiki/XKB",
|
||||
|
||||
Dependencies: P{
|
||||
Libxkbfile,
|
||||
},
|
||||
|
||||
ID: 15018,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibXfont2() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "2.0.7"
|
||||
checksum = "jv9BZNA02493KB8j1lfAErF5SA3ZFcAhm3_UVJ--Bp1maz-vNprl_wXpkHApBi9M"
|
||||
)
|
||||
return t.NewPackage("libXfont2", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xorg/lib/libxfont",
|
||||
"libXfont2-"+version,
|
||||
checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "NOCONFIGURE=1 ./autogen.sh",
|
||||
},
|
||||
Automake,
|
||||
Libtool,
|
||||
PkgConfig,
|
||||
|
||||
utilMacros,
|
||||
Freetype,
|
||||
XorgProto,
|
||||
Libxtrans,
|
||||
Libfontenc,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[LibXfont2] = Metadata{
|
||||
f: Toolchain.newLibXfont2,
|
||||
|
||||
Name: "libXfont2",
|
||||
Description: "X font handling library for server & utilities",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/lib/libxfont",
|
||||
|
||||
Dependencies: P{
|
||||
Freetype,
|
||||
Libfontenc,
|
||||
},
|
||||
|
||||
ID: 17165,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibxcvt() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.1.3"
|
||||
checksum = "IfIA7SxlHMWh681e1AgYmZcRAfkZd5LlzmqcMRifNY5nNVRrUx_wnoaidAv0Yu03"
|
||||
)
|
||||
return t.NewPackage("libxcvt", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xorg/lib/libxcvt",
|
||||
"libxcvt-"+version,
|
||||
checksum,
|
||||
), nil, (*MesonHelper)(nil)), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Libxcvt] = Metadata{
|
||||
f: Toolchain.newLibxcvt,
|
||||
|
||||
Name: "libxcvt",
|
||||
Description: "VESA CVT standard timing modeline generation library & utility",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/lib/libxcvt",
|
||||
|
||||
ID: 235147,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibXdmcp() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.1.5"
|
||||
checksum = "N6AJSv9pmeBedFn8KuSIOUGvTken4rkypNWVE2KfPlliwkfIbhfXrt5YHZkBMUHp"
|
||||
)
|
||||
return t.NewPackage("libXdmcp", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xorg/lib/libxdmcp",
|
||||
"libXdmcp-"+version,
|
||||
checksum,
|
||||
), nil, &MakeHelper{
|
||||
Generate: "NOCONFIGURE=1 ./autogen.sh",
|
||||
},
|
||||
Automake,
|
||||
Libtool,
|
||||
PkgConfig,
|
||||
|
||||
utilMacros,
|
||||
XorgProto,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[LibXdmcp] = Metadata{
|
||||
f: Toolchain.newLibXdmcp,
|
||||
|
||||
Name: "libXdmcp",
|
||||
Description: "X Display Manager Control Protocol library",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/lib/libxdmcp",
|
||||
|
||||
ID: 1772,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newXkeyboardConfig() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "2.47"
|
||||
checksum = "E03PsPIaRrxPAuKgDGSQyPiJB49wXtyyvdV0lVx3_G-pelMMlaFLkoTDHTHG_qgA"
|
||||
)
|
||||
return t.NewPackage("xkeyboard-config", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xkeyboard-config/xkeyboard-config",
|
||||
"xkeyboard-config-"+version,
|
||||
checksum,
|
||||
), nil, (*MesonHelper)(nil),
|
||||
Perl,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[XkeyboardConfig] = Metadata{
|
||||
f: Toolchain.newXkeyboardConfig,
|
||||
|
||||
Name: "xkeyboard-config",
|
||||
Description: "the non-arch keyboard configuration database for X Window",
|
||||
Website: "https://www.freedesktop.org/wiki/Software/XKeyboardConfig/",
|
||||
|
||||
ID: 5191,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newLibpciaccess() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "0.19"
|
||||
@@ -477,3 +902,87 @@ func init() {
|
||||
ID: 1703,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newXserver() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "21.1.22"
|
||||
checksum = "prLT2wKecBu5m9w1ThgIt0GvenNpjKXoOyvTiMA1oQTlP0QHh6QiWsdvH3OmUwNo"
|
||||
)
|
||||
return t.NewPackage("xserver", version, newFromGitLab(
|
||||
"gitlab.freedesktop.org",
|
||||
"xorg/xserver",
|
||||
"xorg-server-"+version,
|
||||
checksum,
|
||||
), nil, &MesonHelper{
|
||||
Setup: []KV{
|
||||
{"Dxorg", "true"},
|
||||
{"Dxephyr", "true"},
|
||||
{"Dxnest", "true"},
|
||||
{"Dipv6", "false"},
|
||||
|
||||
{"Dudev", "false"},
|
||||
{"Dudev_kms", "false"},
|
||||
{"Dglx", "false"},
|
||||
// ../../usr/src/xserver/glamor/glamor_glx.c:24:10: fatal error: 'epoxy/glx.h' file not found
|
||||
{"Dglamor", "false"},
|
||||
},
|
||||
},
|
||||
Gawk,
|
||||
|
||||
XorgProto,
|
||||
Libxtrans,
|
||||
Libxshmfence,
|
||||
Pixman,
|
||||
Libbsd,
|
||||
Xkbcomp,
|
||||
XkeyboardConfig,
|
||||
LibXfont2,
|
||||
DBus,
|
||||
FontUtil,
|
||||
Libxcvt,
|
||||
LibXext,
|
||||
Libmd,
|
||||
LibXdmcp,
|
||||
Libtirpc,
|
||||
Libepoxy,
|
||||
LibxcbUtil,
|
||||
LibxcbUtilImage,
|
||||
LibxcbUtilWM,
|
||||
LibxcbUtilKeysyms,
|
||||
LibxcbRenderUtil,
|
||||
Libpciaccess,
|
||||
KernelHeaders,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Xserver] = Metadata{
|
||||
f: Toolchain.newXserver,
|
||||
|
||||
Name: "xserver",
|
||||
Description: "X server",
|
||||
Website: "https://gitlab.freedesktop.org/xorg/xserver",
|
||||
|
||||
Dependencies: P{
|
||||
Xkbcomp,
|
||||
XkeyboardConfig,
|
||||
|
||||
XCB,
|
||||
Pixman,
|
||||
Libmd,
|
||||
Libbsd,
|
||||
Libtirpc,
|
||||
Libxcvt,
|
||||
LibXdmcp,
|
||||
LibXfont2,
|
||||
Libpciaccess,
|
||||
|
||||
// Xephyr
|
||||
LibxcbUtilImage,
|
||||
LibxcbUtilWM,
|
||||
LibxcbUtilKeysyms,
|
||||
LibxcbRenderUtil,
|
||||
},
|
||||
|
||||
ID: 5250,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user