96 Commits

Author SHA1 Message Date
mae
33e11856c6 cmd/pkgserver: add status endpoint 2026-03-09 04:09:18 -05:00
mae
0f944f7a0e cmd/pkgserver: add createPackageIndex 2026-03-09 01:27:46 -05:00
mae
223037e7c2 cmd/pkgserver: add command handler 2026-03-08 22:28:08 -05:00
mae
acecad7f75 Merge remote-tracking branch 'origin/pkgserver' into pkgserver 2026-03-08 13:29:49 -05:00
mae
4f82f28c73 cmd/pkgserver: replace favicon 2026-03-08 13:29:15 -05:00
mae
ae07e0127b cmd/pkgserver: pagination 2026-03-08 13:29:15 -05:00
mae
d2696a6f30 cmd/pkgserver: basic web ui 2026-03-08 13:29:10 -05:00
mae
17ba70771c cmd/pkgserver: replace favicon 2026-03-08 13:29:01 -05:00
mae
93984f29da cmd/pkgserver: pagination 2026-03-08 13:29:01 -05:00
mae
d7cd746b43 cmd/pkgserver: basic web ui 2026-03-08 13:29:01 -05:00
6988c9c4db internal/rosa: firmware artifact
Required for generic hardware.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 22:50:36 +09:00
d6e0ed8c76 internal/rosa/python: various pypi artifacts
These are dependencies of pre-commit.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 22:25:16 +09:00
53be3309c5 internal/rosa: rdfind artifact
Required by linux firmware.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 20:26:15 +09:00
644dd18a52 internal/rosa: nettle artifact
Required by rdfind, which is required by linux firmware.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 20:22:09 +09:00
27c6f976df internal/rosa/gnu: parallel artifact
Used by linux firmware.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 19:56:40 +09:00
279a973633 internal/rosa: build independent earlyinit
This avoids unnecessarily rebuilding hakurei during development.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 18:29:04 +09:00
9c1b522689 internal/rosa/hakurei: optional hostname tool
This makes it more efficient to reuse the helper for partial builds.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 18:26:03 +09:00
5c8cd46c02 internal/rosa: update arm64 kernel config
This was not feasible during the bump, now there is a viable toolchain.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 03:17:53 +09:00
2dba550a2b internal/rosa/zlib: 1.3.1 to 1.3.2
This also switches to the CMake build system because upstream broke their old build system.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 02:36:59 +09:00
8c64812b34 internal/rosa: add zlib runtime dependency
For transitioning to dynamically linking zlib.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 02:36:09 +09:00
d1423d980d internal/rosa/cmake: bake in CMAKE_INSTALL_LIBDIR
There is never a good reason to set this to anything else, and the default value of lib64 breaks everything. This did not manifest on LLVM (which the CMake helper was initially written for) because it did not use this value.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 01:20:41 +09:00
104da0f66a internal/rosa/cmake: pass correct prefix
This can change build output similar to autotools --prefix and DESTDIR, but was not clearly indicated to do so.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 01:04:02 +09:00
d996d9fbb7 internal/rosa/cmake: pass parallel argument for make
This uses the default value for each build system, which is parallel for ninja but not for make.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 00:55:58 +09:00
469f97ccc1 internal/rosa/gnu: libiconv 1.18 to 1.19
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-08 00:36:38 +09:00
af7a6180a1 internal/rosa/cmake: optionally use makefile
This breaks the dependency loop in zlib.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 22:47:30 +09:00
03b5c0e20a internal/rosa/tamago: populate Anitya project id
This had to wait quite a while due to Microsoft Github rate-limiting.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 19:37:03 +09:00
6a31fb4fa3 internal/rosa: hakurei 0.3.5 to 0.3.6
This also removes the backport patch.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 18:53:48 +09:00
bae45363bc release: 0.3.6
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 16:32:04 +09:00
2c17d1abe0 cmd/mbf: create report with reasonable perm
Making it inaccessible certainly is not reasonable.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 16:16:47 +09:00
0aa459d1a9 cmd/mbf: check for updates concurrently
Runs much faster this way.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 16:05:16 +09:00
00053e6287 internal/rosa: set User-Agent for Anitya requests
This is cleaner than using the default string.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 16:03:06 +09:00
3a0c020150 internal/rosa/gnu: coreutils 9.9 to 9.10
This breaks two tests, one of them is fixed and the other disabled. Additionally, two fixed tests are re-enabled.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 14:31:03 +09:00
78655f159e internal/rosa/ncurses: use stable Anitya project
The alpine mapping points to ncurses~devel for some reason.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 13:43:38 +09:00
30bb52e380 internal/rosa/x: libXau 1.0.7 to 1.0.12
This also switches to individual releases.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 13:39:48 +09:00
66197ebdb2 internal/rosa/x: xproto 7.0.23 to 7.0.31
This also switches to individual releases.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 13:39:23 +09:00
f7a2744025 internal/rosa/x: util-macros 1.17 to 1.20.2
This also switches to individual releases.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 13:38:54 +09:00
f16b7bfaf0 internal/rosa: do not keep underlying file
No operation require further filesystem interaction for now.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 13:04:06 +09:00
6228cda7ad cmd/mbf: optionally read report in info
This is a useful frontend for the report files before web server is ready.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 02:26:35 +09:00
86c336de88 cmd/mbf: cure status report command
This emits a report stream for the opened cache into the specified file.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 02:20:40 +09:00
ba5d882ef2 internal/rosa: stream format for cure report
This is for efficient cure status retrieval by the package website server.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-07 02:18:00 +09:00
1e0d68a29e internal/pkg: move output buffer to reader
This side is the read end of a pipe and buffering reads from it ended up performing better than buffering one half of the TeeReader (which already goes through the kernel page cache anyway).

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 23:39:12 +09:00
80f2367c16 cmd/mbf: merge status and info commands
This is cleaner, and offers better integration with the work-in-progress report file.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 23:20:00 +09:00
5ea4dae4b8 cmd/mbf: info accept multiple names
This also improves formatting for use with multiple info blocks.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 23:10:43 +09:00
eb1a3918a8 internal/rosa/gnu: texinfo 7.2 to 7.3
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 22:09:00 +09:00
349011a5e6 internal/rosa/perl: compile dynamic libperl
Required by texinfo 7.3.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 22:08:38 +09:00
861249751a internal/rosa/openssl: 3.5.5 to 3.6.1
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 21:39:52 +09:00
e3445c2a7e internal/rosa/libffi: 3.4.5 to 3.5.2
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 21:39:25 +09:00
7315e64a8a internal/rosa/ssl: nss 3.120 to 3.121
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 21:38:41 +09:00
7d74454f6d internal/rosa/python: 3.14.2 to 3.14.3
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 21:38:17 +09:00
96956c849a internal/rosa/gnu: gawk 5.3.2 to 5.4.0
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 21:30:37 +09:00
aabdcbba1c internal/rosa/gnu: m4 1.4.20 to 1.4.21
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 21:22:33 +09:00
38cc4a6429 internal/rosa/openssl: check stable versions
This has a bunch of strange malformed tags.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 19:22:41 +09:00
27ef7f81fa internal/rosa/perl: check stable versions
This uses odd-even versioning.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 19:16:07 +09:00
f7888074b9 internal/rosa/util-linux: check stable versions
Anitya appears to get confused when seeing release candidates.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 19:15:16 +09:00
95ffe0429c internal/rosa: overridable version check
For projects with strange versioning practices.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 19:13:55 +09:00
16d0cf04c1 internal/rosa/python: setuptools 80.10.1 to 82.0.0
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 18:40:55 +09:00
6a2b32b48c internal/rosa/libxml2: 2.15.1 to 2.15.2
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 18:36:06 +09:00
c1472fc54d internal/rosa/wayland: 1.24.0 to 1.24.91
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 18:33:26 +09:00
179cf07e48 internal/rosa/git: 2.52.0 to 2.53.0
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 18:32:41 +09:00
c2d2795e2b internal/rosa/libexpat: 2.7.3 to 2.7.4
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 18:22:39 +09:00
2c1d7edd7a internal/rosa/squashfs: 4.7.4 to 4.7.5
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 17:47:23 +09:00
1ee8d09223 internal/rosa/pcre2: 10.43 to 10.47
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 17:46:59 +09:00
7f01cb3d59 internal/rosa/gtk: glib 2.86.4 to 2.87.3
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 17:46:32 +09:00
65ae4f57c2 internal/rosa/go: 1.26.0 to 1.26.1
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 17:46:05 +09:00
77110601cc internal/rosa/gnu: binutils 2.45 to 2.46.0
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 17:45:10 +09:00
c5b1949430 internal/rosa/kernel: backport AMD display patches
These reduce stack usage in dml30_ModeSupportAndSystemConfigurationFull enough to fix compile on clang 22.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 16:22:20 +09:00
17805cdfa8 internal/rosa/kernel: 6.12.73 to 6.12.76
Toolchain is broken on arm64 at the moment so the configuration is not updated.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-06 15:01:01 +09:00
9c9befb4c9 internal/rosa/llvm: separate major version
For pathname formatting at compile time.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 22:59:51 +09:00
fcdf9ecee4 internal/rosa/llvm: 21.1.8 to 22.1.0
New patch should not be affected next time.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 22:42:27 +09:00
fbd97b658f cmd/mbf: display metadata
For viewing package metadata before the website is ready.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 22:11:26 +09:00
c93725ac58 internal/rosa: prefix python constants
These have confusing names.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 21:37:06 +09:00
f14ab80253 internal/rosa: populate Anitya project ids
This enables release monitoring for all applicable projects.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 21:32:15 +09:00
9989881dd9 internal/rosa/llvm: populate metadata
This enables use of release monitoring for LLVM.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 21:27:33 +09:00
a36b3ece16 internal/rosa: release monitoring via Anitya
This is much more sustainable than manual package flagging.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 20:57:05 +09:00
75970a5650 internal/rosa: check name uniqueness
This should prevent adding packages with nonunique names.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 18:37:55 +09:00
mae
b255f07b0f Merge remote-tracking branch 'origin/pkgserver' into pkgserver 2026-03-05 02:06:27 -06:00
572c99825d Revert "internal/rosa/zlib: 1.3.1 to 1.3.2"
The bump broke elfutils build.

This reverts commit 0eb2bfa12e.
2026-03-05 17:06:15 +09:00
mae
dec4cdd068 cmd/pkgserver: replace favicon 2026-03-05 02:06:07 -06:00
mae
73c620ecd5 cmd/pkgserver: pagination 2026-03-05 02:06:07 -06:00
mae
69467a1542 cmd/pkgserver: basic web ui 2026-03-05 02:06:07 -06:00
ebdf9dcecc cmd/mbf: preset status command
This exposes the new OpenStatus cache method.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 16:59:47 +09:00
8ea2a56d5b internal/pkg: expose status file
This is useful for external tooling.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 16:58:52 +09:00
159a45c027 internal/rosa: export preset bounds
These are useful for external tooling.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 16:34:25 +09:00
mae
1ae6a35bc8 cmd/pkgserver: replace favicon 2026-03-05 01:12:17 -06:00
0eb2bfa12e internal/rosa/zlib: 1.3.1 to 1.3.2
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 15:49:18 +09:00
e19a98244a internal/rosa: zlib use stable archive url
These do not get removed on new release.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 15:46:10 +09:00
mae
9ef5b52b85 cmd/pkgserver: pagination 2026-03-05 00:32:25 -06:00
mae
f93158cb3c cmd/pkgserver: basic web ui 2026-03-04 22:50:58 -06:00
7e2f13fa1b internal/rosa: cure checks
This cures all presets if a cache directory is supplied and verbose is set.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 00:47:39 +09:00
97448e2104 internal/rosa/squashfs: enter correct directory
This was missed during the make helper migration.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 00:43:50 +09:00
a87ad28b8b internal/pkg: scrub for dangling status
These cause build to fail to start.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 00:39:15 +09:00
883d4ee4af internal/pkg: return writer after sync
This fixes a use-after-free.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 00:23:24 +09:00
d2c6d486b0 internal/rosa: provide package metadata
This had to be done out-of-band because there was no way to efficiently represent these within Artifact.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-05 00:20:27 +09:00
6fdd800b2b internal/pkg: check filtered error
This avoids filtering some unrelated os.ErrExist.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-04 17:43:17 +09:00
94e3debc63 internal/pkg: write per-artifact logs
This is currently only used by execArtifact. A later patch will add additional logging facilities.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-04 17:27:54 +09:00
ea87664a75 internal/pkg: cancel on scanner error
This avoids discarding output thus appearing unresponsive.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-03-03 22:20:43 +09:00
89 changed files with 4573 additions and 665 deletions

View File

@@ -4,11 +4,16 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"io"
"log" "log"
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv"
"strings"
"sync"
"sync/atomic"
"syscall" "syscall"
"time" "time"
"unique" "unique"
@@ -128,6 +133,207 @@ func main() {
) )
} }
{
var (
flagStatus bool
flagReport string
)
c.NewCommand(
"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, "/"))
}
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
},
).
Flag(
&flagStatus,
"status", command.BoolFlag(false),
"Display cure status if available",
).
Flag(
&flagReport,
"report", command.StringFlag(""),
"Load cure status from this report file instead of cache",
)
}
c.NewCommand(
"report",
"Generate an artifact cure report for the current cache",
func(args []string) (err error) {
var w *os.File
switch len(args) {
case 0:
w = os.Stdout
case 1:
if w, err = os.OpenFile(
args[0],
os.O_CREATE|os.O_EXCL|syscall.O_WRONLY,
0400,
); err != nil {
return
}
defer func() {
closeErr := w.Close()
if err == nil {
err = closeErr
}
}()
default:
return errors.New("report requires 1 argument")
}
if container.Isatty(int(w.Fd())) {
return errors.New("output appears to be a terminal")
}
return rosa.WriteReport(msg, w, cache)
},
)
{
var flagJobs int
c.NewCommand("updates", command.UsageInternal, func([]string) error {
var (
errsMu sync.Mutex
errs []error
n atomic.Uint64
)
w := make(chan rosa.PArtifact)
var wg sync.WaitGroup
for range max(flagJobs, 1) {
wg.Go(func() {
for p := range w {
meta := rosa.GetMetadata(p)
if meta.ID == 0 {
continue
}
v, err := meta.GetVersions(ctx)
if err != nil {
errsMu.Lock()
errs = append(errs, err)
errsMu.Unlock()
continue
}
if current, latest :=
rosa.Std.Version(p),
meta.GetLatest(v); current != latest {
n.Add(1)
log.Printf("%s %s < %s", meta.Name, current, latest)
continue
}
msg.Verbosef("%s is up to date", meta.Name)
}
})
}
done:
for i := range rosa.PresetEnd {
select {
case w <- rosa.PArtifact(i):
break
case <-ctx.Done():
break done
}
}
close(w)
wg.Wait()
if v := n.Load(); v > 0 {
errs = append(errs, errors.New(strconv.Itoa(int(v))+
" package(s) are out of date"))
}
return errors.Join(errs...)
}).
Flag(
&flagJobs,
"j", command.IntFlag(32),
"Maximum number of simultaneous connections",
)
}
{ {
var ( var (
flagGentoo string flagGentoo string
@@ -401,6 +607,16 @@ func main() {
if cache != nil { if cache != nil {
cache.Close() cache.Close()
} }
log.Fatal(err) if w, ok := err.(interface{ Unwrap() []error }); !ok {
log.Fatal(err)
} else {
errs := w.Unwrap()
for i, e := range errs {
if i == len(errs)-1 {
log.Fatal(e)
}
log.Println(e)
}
}
}) })
} }

229
cmd/pkgserver/main.go Normal file
View File

@@ -0,0 +1,229 @@
package main
import (
"bytes"
"cmp"
"context"
"embed"
"fmt"
"io"
"log"
"net/http"
"os"
"os/signal"
"path"
"slices"
"strings"
"syscall"
"hakurei.app/command"
"hakurei.app/container/check"
"hakurei.app/internal/pkg"
"hakurei.app/internal/rosa"
"hakurei.app/message"
)
//go:generate sh -c "sass ui/static/dark.scss ui/static/dark.css && sass ui/static/light.scss ui/static/light.css && tsc ui/static/index.ts"
//go:embed ui/*
var content embed.FS
func serveWebUI(w http.ResponseWriter, r *http.Request) {
fmt.Printf("serveWebUI: %s\n", r.URL.Path)
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Set("Pragma", "no-cache")
w.Header().Set("Expires", "0")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("X-XSS-Protection", "1")
w.Header().Set("X-Frame-Options", "DENY")
http.ServeFileFS(w, r, content, "ui/index.html")
}
func serveStaticContent(w http.ResponseWriter, r *http.Request) {
fmt.Printf("serveStaticContent: %s\n", r.URL.Path)
switch r.URL.Path {
case "/static/style.css":
darkTheme := r.CookiesNamed("dark_theme")
if len(darkTheme) > 0 && darkTheme[0].Value == "true" {
http.ServeFileFS(w, r, content, "ui/static/dark.css")
} else {
http.ServeFileFS(w, r, content, "ui/static/light.css")
}
break
case "/favicon.ico":
http.ServeFileFS(w, r, content, "ui/static/favicon.ico")
break
case "/static/index.js":
http.ServeFileFS(w, r, content, "ui/static/index.js")
break
default:
http.NotFound(w, r)
}
}
func serveAPI(index *PackageIndex) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {}
}
func serveStatus(index *PackageIndex) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if index == nil {
http.Error(w, "index is nil", http.StatusInternalServerError)
return
}
base := path.Base(r.URL.Path)
name := strings.TrimSuffix(base, ".log")
p, ok := rosa.ResolveName(name)
if !ok {
http.NotFound(w, r)
return
}
m := rosa.GetMetadata(p)
pk, ok := index.names[m.Name]
if !ok {
http.NotFound(w, r)
return
}
if len(pk.status) > 0 {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.WriteHeader(http.StatusOK)
_, err := io.Copy(w, bytes.NewReader(pk.status))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
} else {
http.NotFound(w, r)
}
}
}
type SortOrders int
const (
DeclarationAscending SortOrders = iota
DeclarationDescending
NameAscending
NameDescending
limitSortOrders
)
type PackageIndex struct {
sorts [limitSortOrders][rosa.PresetUnexportedStart]*PackageIndexEntry
names map[string]*PackageIndexEntry
}
type PackageIndexEntry struct {
Name string `json:"name"`
Description string `json:"description"`
Website string `json:"website"`
Version string `json:"version"`
status []byte
}
func createPackageIndex(cache *pkg.Cache, report *rosa.Report) (_ *PackageIndex, err error) {
index := new(PackageIndex)
index.names = make(map[string]*PackageIndexEntry, rosa.PresetUnexportedStart)
work := make([]PackageIndexEntry, rosa.PresetUnexportedStart)
defer report.HandleAccess(&err)()
for p := range rosa.PresetUnexportedStart {
m := rosa.GetMetadata(p)
v := rosa.Std.Version(p)
a := rosa.Std.Load(p)
id := cache.Ident(a)
st, n := report.ArtifactOf(id)
var status []byte
if n < 1 {
status = nil
} else {
status = st
}
log.Printf("Processing package %s...\n", m.Name)
entry := PackageIndexEntry{
Name: m.Name,
Description: m.Description,
Website: m.Website,
Version: v,
status: status,
}
work[p] = entry
index.names[m.Name] = &entry
}
for i, p := range work {
index.sorts[DeclarationAscending][i] = &p
}
slices.Reverse(work)
for i, p := range work {
index.sorts[DeclarationDescending][i] = &p
}
slices.SortFunc(work, func(a PackageIndexEntry, b PackageIndexEntry) int {
return cmp.Compare(a.Name, b.Name)
})
for i, p := range work {
index.sorts[NameAscending][i] = &p
}
slices.Reverse(work)
for i, p := range work {
index.sorts[NameDescending][i] = &p
}
return index, err
}
func main() {
log.SetFlags(0)
log.SetPrefix("pkgserver: ")
var (
flagBaseDir string
flagPort int
)
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
defer stop()
msg := message.New(log.Default())
c := command.New(os.Stderr, log.Printf, "pkgserver", func(args []string) error {
reportPath := args[0]
baseDir, err := check.NewAbs(flagBaseDir)
if err != nil {
return err
}
log.Println("baseDir:", baseDir)
cache, err := pkg.Open(ctx, msg, 0, baseDir)
if err != nil {
return err
}
report, err := rosa.OpenReport(reportPath)
if err != nil {
return err
}
log.Println("reportPath:", reportPath)
log.Println("indexing packages...")
index, err := createPackageIndex(cache, report)
if err != nil {
return err
}
log.Println("created package index")
http.HandleFunc("GET /{$}", serveWebUI)
http.HandleFunc("GET /favicon.ico", serveStaticContent)
http.HandleFunc("GET /static/", serveStaticContent)
http.HandleFunc("GET /api/", serveAPI(index))
http.HandleFunc("GET /api/status/", serveStatus(index))
log.Println("listening on", flagPort)
err = http.ListenAndServe(fmt.Sprintf(":%d", flagPort), nil)
if err != nil {
return err
}
return nil
}).Flag(
&flagBaseDir,
"b", command.StringFlag(""),
"base directory for cache",
).Flag(
&flagPort,
"p", command.IntFlag(8067),
"http listen port",
)
c.MustParse(os.Args[1:], func(e error) {
log.Fatal(e)
})
}

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="static/style.css">
<title>Hakurei PkgServer</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="static/index.js"></script>
</head>
<body>
<h1>Hakurei PkgServer</h1>
<table id="pkg-list">
<tr><th>Status</th><th>Name</th><th>Version</th></tr>
</table>
<p>Showing entries <span id="entry-counter"></span>.</p>
<span class="bottom-nav"><a href="javascript:prevPage()">&laquo; Previous</a> <span id="page-number">1</span> <a href="javascript:nextPage()">Next &raquo;</a></span>
<span><label for="count">Entries per page:</label><select name="count" id="count">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select></span>
</body>
<footer>&copy; <a href="https://hakurei.app/">Hakurei</a>. Licensed under the MIT license.</footer>
</html>

View File

View File

@@ -0,0 +1,6 @@
@use 'common';
html {
background-color: #2c2c2c;
color: ghostwhite; }
/*# sourceMappingURL=dark.css.map */

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "AAAA,aAAa;AAEb,IAAK;EACH,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,UAAU",
"sources": ["dark.scss"],
"names": [],
"file": "dark.css"
}

View File

@@ -0,0 +1,6 @@
@use 'common';
html {
background-color: #2c2c2c;
color: ghostwhite;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,67 @@
"use strict";
var PackageEntry = /** @class */ (function () {
function PackageEntry() {
}
return PackageEntry;
}());
var State = /** @class */ (function () {
function State() {
this.entriesPerPage = 10;
this.currentPage = 1;
this.entryIndex = 0;
this.loadedEntries = [];
}
State.prototype.getEntriesPerPage = function () {
return this.entriesPerPage;
};
State.prototype.setEntriesPerPage = function (entriesPerPage) {
this.entriesPerPage = entriesPerPage;
this.updateRange();
};
State.prototype.getCurrentPage = function () {
return this.currentPage;
};
State.prototype.setCurrentPage = function (page) {
this.currentPage = page;
document.getElementById("page-number").innerText = String(this.currentPage);
this.updateRange();
};
State.prototype.getEntryIndex = function () {
return this.entryIndex;
};
State.prototype.setEntryIndex = function (entryIndex) {
this.entryIndex = entryIndex;
this.updateRange();
};
State.prototype.getLoadedEntries = function () {
return this.loadedEntries;
};
State.prototype.getMaxPage = function () {
return this.loadedEntries.length / this.entriesPerPage;
};
State.prototype.updateRange = function () {
var max = Math.min(this.entryIndex + this.entriesPerPage, this.loadedEntries.length);
document.getElementById("entry-counter").innerText = "".concat(this.entryIndex, "-").concat(max, " of ").concat(this.loadedEntries.length);
};
return State;
}());
var STATE;
function prevPage() {
var current = STATE.getCurrentPage();
if (current > 1) {
STATE.setCurrentPage(STATE.getCurrentPage() - 1);
}
}
function nextPage() {
var current = STATE.getCurrentPage();
if (current < STATE.getMaxPage()) {
STATE.setCurrentPage(STATE.getCurrentPage() + 1);
}
}
document.addEventListener("DOMContentLoaded", function () {
STATE = new State();
STATE.updateRange();
document.getElementById("count").addEventListener("change", function (event) {
STATE.setEntriesPerPage(parseInt(event.target.value));
});
});

View File

@@ -0,0 +1,66 @@
"use strict"
class PackageEntry {
}
class State {
entriesPerPage: number = 10
currentPage: number = 1
entryIndex: number = 0
loadedEntries: PackageEntry[] = []
getEntriesPerPage(): number {
return this.entriesPerPage
}
setEntriesPerPage(entriesPerPage: number) {
this.entriesPerPage = entriesPerPage
this.updateRange()
}
getCurrentPage(): number {
return this.currentPage
}
setCurrentPage(page: number) {
this.currentPage = page
document.getElementById("page-number").innerText = String(this.currentPage)
this.updateRange()
}
getEntryIndex(): number {
return this.entryIndex
}
setEntryIndex(entryIndex: number) {
this.entryIndex = entryIndex
this.updateRange()
}
getLoadedEntries(): PackageEntry[] {
return this.loadedEntries
}
getMaxPage(): number {
return this.loadedEntries.length / this.entriesPerPage
}
updateRange() {
let max = Math.min(this.entryIndex + this.entriesPerPage, this.loadedEntries.length)
document.getElementById("entry-counter").innerText = `${this.entryIndex}-${max} of ${this.loadedEntries.length}`
}
}
let STATE: State
function prevPage() {
let current = STATE.getCurrentPage()
if (current > 1) {
STATE.setCurrentPage(STATE.getCurrentPage() - 1)
}
}
function nextPage() {
let current = STATE.getCurrentPage()
if (current < STATE.getMaxPage()) {
STATE.setCurrentPage(STATE.getCurrentPage() + 1)
}
}
document.addEventListener("DOMContentLoaded", () => {
STATE = new State()
STATE.updateRange()
document.getElementById("count").addEventListener("change", (event) => {
STATE.setEntriesPerPage(parseInt((event.target as HTMLSelectElement).value))
})
})

View File

@@ -0,0 +1,6 @@
@use 'common';
html {
background-color: #d3d3d3;
color: black; }
/*# sourceMappingURL=light.css.map */

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "AAAA,aAAa;AAEb,IAAK;EACH,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,KAAK",
"sources": ["light.scss"],
"names": [],
"file": "light.css"
}

View File

@@ -0,0 +1,6 @@
@use 'common';
html {
background-color: #d3d3d3;
color: black;
}

View File

69
internal/azalea/azalea.go Normal file
View File

@@ -0,0 +1,69 @@
//go:generate gocc -a azalea.bnf
package azalea
import (
"io"
"io/fs"
"os"
"path/filepath"
"strconv"
"strings"
"hakurei.app/container/check"
)
type Parser struct {
Generator
}
func NewParser(gen Generator) *Parser {
return &Parser{
Generator: gen,
}
}
func (p Parser) Initialise() {
}
func (p Parser) Consume(ns string, file io.Reader) error {
return nil
}
// ConsumeDir walks a directory and consumes all Azalea source files within it and all its subdirectories, as long as they end with the .az extension.
func (p Parser) ConsumeDir(dir *check.Absolute) error {
ds := dir.String()
return filepath.WalkDir(ds, func(path string, d fs.DirEntry, err error) (e error) {
if err != nil {
return err
}
if d.IsDir() || !strings.HasSuffix(d.Name(), ".az") {
return
}
rel, e := filepath.Rel(ds, path)
ns := strings.TrimSuffix(rel, ".az")
f, e := os.Open(path)
return p.Consume(ns, f)
})
}
// ConsumeAll consumes all provided readers as Azalea source code, each given the namespace `r%d` where `%d` is the index of the reader in the provided arguments.
func (p Parser) ConsumeAll(in ...io.Reader) error {
for i, r := range in {
err := p.Consume("r"+strconv.FormatInt(int64(i), 10), r)
if err != nil {
return err
}
}
return nil
}
// ConsumeStrings consumes all provided strings as Azalea source code, each given the namespace `s%d` where `%d` is the index of the string in the provided arugments.
func (p Parser) ConsumeStrings(in ...string) error {
for i, s := range in {
err := p.Consume("s"+strconv.FormatInt(int64(i), 10), strings.NewReader(s))
if err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,36 @@
package azalea
import (
"io"
)
type Generator interface {
Finalise() (error, io.Writer)
}
type JsonGenerator struct {
t any
}
func NewJsonGenerator[T any]() JsonGenerator {
t := new(T)
return JsonGenerator{
t,
}
}
func (j *JsonGenerator) Finalise() (error, io.Writer) {
}
type PkgIRGenerator struct {
}
func NewPkgIRGenerator() PkgIRGenerator {
return PkgIRGenerator{}
}
func (p *PkgIRGenerator) Finalise() (error, io.Writer) {
}

View File

@@ -361,6 +361,7 @@ const (
// scanVerbose prefixes program output for a verbose [message.Msg]. // scanVerbose prefixes program output for a verbose [message.Msg].
func scanVerbose( func scanVerbose(
msg message.Msg, msg message.Msg,
cancel context.CancelFunc,
done chan<- struct{}, done chan<- struct{},
prefix string, prefix string,
r io.Reader, r io.Reader,
@@ -375,6 +376,7 @@ func scanVerbose(
msg.Verbose(prefix, s.Text()) msg.Verbose(prefix, s.Text())
} }
if err := s.Err(); err != nil && !errors.Is(err, os.ErrClosed) { if err := s.Err(); err != nil && !errors.Is(err, os.ErrClosed) {
cancel()
msg.Verbose("*"+prefix, err) msg.Verbose("*"+prefix, err)
} }
} }
@@ -416,6 +418,12 @@ func (a *execArtifact) cure(f *FContext, hostNet bool) (err error) {
z.Hostname = "cure-net" z.Hostname = "cure-net"
} }
z.Uid, z.Gid = (1<<10)-1, (1<<10)-1 z.Uid, z.Gid = (1<<10)-1, (1<<10)-1
var status io.Writer
if status, err = f.GetStatusWriter(); err != nil {
return
}
if msg := f.GetMessage(); msg.IsVerbose() { if msg := f.GetMessage(); msg.IsVerbose() {
var stdout, stderr io.ReadCloser var stdout, stderr io.ReadCloser
if stdout, err = z.StdoutPipe(); err != nil { if stdout, err = z.StdoutPipe(); err != nil {
@@ -432,10 +440,26 @@ func (a *execArtifact) cure(f *FContext, hostNet bool) (err error) {
} }
}() }()
brStdout, brStderr := f.cache.getReader(stdout), f.cache.getReader(stderr)
stdoutDone, stderrDone := make(chan struct{}), make(chan struct{}) stdoutDone, stderrDone := make(chan struct{}), make(chan struct{})
go scanVerbose(msg, stdoutDone, "("+a.name+":1)", stdout) go scanVerbose(
go scanVerbose(msg, stderrDone, "("+a.name+":2)", stderr) msg, cancel, stdoutDone,
defer func() { <-stdoutDone; <-stderrDone }() "("+a.name+":1)",
io.TeeReader(brStdout, status),
)
go scanVerbose(
msg, cancel, stderrDone,
"("+a.name+":2)",
io.TeeReader(brStderr, status),
)
defer func() {
<-stdoutDone
<-stderrDone
f.cache.putReader(brStdout)
f.cache.putReader(brStderr)
}()
} else {
z.Stdout, z.Stderr = status, status
} }
z.Dir, z.Env, z.Path, z.Args = a.dir, a.env, a.path, a.args z.Dir, z.Env, z.Path, z.Args = a.dir, a.env, a.path, a.args

View File

@@ -28,15 +28,21 @@ import (
"unsafe" "unsafe"
"hakurei.app/container/check" "hakurei.app/container/check"
"hakurei.app/internal/info"
"hakurei.app/internal/lockedfile" "hakurei.app/internal/lockedfile"
"hakurei.app/message" "hakurei.app/message"
) )
const (
// programName is the string identifying this build system.
programName = "internal/pkg"
)
type ( type (
// A Checksum is a SHA-384 checksum computed for a cured [Artifact]. // A Checksum is a SHA-384 checksum computed for a cured [Artifact].
Checksum = [sha512.Size384]byte Checksum = [sha512.Size384]byte
// An ID is a unique identifier returned by [Artifact.ID]. This value must // An ID is a unique identifier returned by [KnownIdent.ID]. This value must
// be deterministically determined ahead of time. // be deterministically determined ahead of time.
ID Checksum ID Checksum
) )
@@ -81,20 +87,75 @@ type TContext struct {
// Populated during [Cache.Cure]. // Populated during [Cache.Cure].
work, temp *check.Absolute work, temp *check.Absolute
// Target [Artifact] encoded identifier.
ids string
// Pathname status was created at.
statusPath *check.Absolute
// File statusHeader and logs are written to.
status *os.File
// Error value during prepareStatus.
statusErr error
common common
} }
// statusHeader is the header written to all status files in dirStatus.
var statusHeader = func() string {
s := programName
if v := info.Version(); v != info.FallbackVersion {
s += " " + v
}
s += " (" + runtime.GOARCH + ")"
if name, err := os.Hostname(); err == nil {
s += " on " + name
}
s += "\n\n"
return s
}()
// prepareStatus initialises the status file once.
func (t *TContext) prepareStatus() error {
if t.statusPath != nil || t.status != nil {
return t.statusErr
}
t.statusPath = t.cache.base.Append(
dirStatus,
t.ids,
)
if t.status, t.statusErr = os.OpenFile(
t.statusPath.String(),
syscall.O_CREAT|syscall.O_EXCL|syscall.O_WRONLY,
0400,
); t.statusErr != nil {
return t.statusErr
}
_, t.statusErr = t.status.WriteString(statusHeader)
return t.statusErr
}
// GetStatusWriter returns a [io.Writer] for build logs. The caller must not
// seek this writer before the position it was first returned in.
func (t *TContext) GetStatusWriter() (io.Writer, error) {
err := t.prepareStatus()
return t.status, err
}
// destroy destroys the temporary directory and joins its errors with the error // destroy destroys the temporary directory and joins its errors with the error
// referred to by errP. If the error referred to by errP is non-nil, the work // referred to by errP. If the error referred to by errP is non-nil, the work
// directory is removed similarly. [Cache] is responsible for making sure work // directory is removed similarly. [Cache] is responsible for making sure work
// is never left behind for a successful [Cache.Cure]. // is never left behind for a successful [Cache.Cure].
// //
// If implementation had requested status, it is closed with error joined with
// the error referred to by errP. If the error referred to by errP is non-nil,
// the status file is removed from the filesystem.
//
// destroy must be deferred by [Cache.Cure] if [TContext] is passed to any Cure // destroy must be deferred by [Cache.Cure] if [TContext] is passed to any Cure
// implementation. It should not be called prior to that point. // implementation. It should not be called prior to that point.
func (t *TContext) destroy(errP *error) { func (t *TContext) destroy(errP *error) {
if chmodErr, removeErr := removeAll(t.temp); chmodErr != nil || removeErr != nil { if chmodErr, removeErr := removeAll(t.temp); chmodErr != nil || removeErr != nil {
*errP = errors.Join(*errP, chmodErr, removeErr) *errP = errors.Join(*errP, chmodErr, removeErr)
return
} }
if *errP != nil { if *errP != nil {
@@ -102,10 +163,24 @@ func (t *TContext) destroy(errP *error) {
if chmodErr != nil || removeErr != nil { if chmodErr != nil || removeErr != nil {
*errP = errors.Join(*errP, chmodErr, removeErr) *errP = errors.Join(*errP, chmodErr, removeErr)
} else if errors.Is(*errP, os.ErrExist) { } else if errors.Is(*errP, os.ErrExist) {
// two artifacts may be backed by the same file var linkError *os.LinkError
*errP = nil if errors.As(*errP, &linkError) && linkError != nil &&
linkError.Op == "rename" {
// two artifacts may be backed by the same file
*errP = nil
}
} }
} }
if t.status != nil {
if err := t.status.Close(); err != nil {
*errP = errors.Join(*errP, err)
}
if *errP != nil {
*errP = errors.Join(*errP, os.Remove(t.statusPath.String()))
}
t.status = nil
}
} }
// Unwrap returns the underlying [context.Context]. // Unwrap returns the underlying [context.Context].
@@ -169,7 +244,7 @@ type FContext struct {
} }
// InvalidLookupError is the identifier of non-dependency [Artifact] looked up // InvalidLookupError is the identifier of non-dependency [Artifact] looked up
// via [FContext.Pathname] by a misbehaving [Artifact] implementation. // via [FContext.GetArtifact] by a misbehaving [Artifact] implementation.
type InvalidLookupError ID type InvalidLookupError ID
func (e InvalidLookupError) Error() string { func (e InvalidLookupError) Error() string {
@@ -375,6 +450,9 @@ const (
// dirChecksum is the directory name appended to Cache.base for storing // dirChecksum is the directory name appended to Cache.base for storing
// artifacts named after their [Checksum]. // artifacts named after their [Checksum].
dirChecksum = "checksum" dirChecksum = "checksum"
// dirStatus is the directory name appended to Cache.base for storing
// artifact metadata and logs named after their [ID].
dirStatus = "status"
// dirWork is the directory name appended to Cache.base for working // dirWork is the directory name appended to Cache.base for working
// pathnames set up during [Cache.Cure]. // pathnames set up during [Cache.Cure].
@@ -587,6 +665,9 @@ type ScrubError struct {
// Dangling identifier symlinks. This can happen if the content-addressed // Dangling identifier symlinks. This can happen if the content-addressed
// entry was removed while scrubbing due to a checksum mismatch. // entry was removed while scrubbing due to a checksum mismatch.
DanglingIdentifiers []ID DanglingIdentifiers []ID
// Dangling status files. This can happen if a dangling status symlink was
// removed while scrubbing.
DanglingStatus []ID
// Miscellaneous errors, including [os.ReadDir] on checksum and identifier // Miscellaneous errors, including [os.ReadDir] on checksum and identifier
// directories, [Decode] on entry names and [os.RemoveAll] on inconsistent // directories, [Decode] on entry names and [os.RemoveAll] on inconsistent
// entries. // entries.
@@ -638,6 +719,13 @@ func (e *ScrubError) Error() string {
} }
segments = append(segments, s) segments = append(segments, s)
} }
if len(e.DanglingStatus) > 0 {
s := "dangling status:\n"
for _, id := range e.DanglingStatus {
s += Encode(id) + "\n"
}
segments = append(segments, s)
}
if len(e.Errs) > 0 { if len(e.Errs) > 0 {
s := "errors during scrub:\n" s := "errors during scrub:\n"
for pathname, errs := range e.errs { for pathname, errs := range e.errs {
@@ -816,6 +904,36 @@ func (c *Cache) Scrub(checks int) error {
wg.Wait() wg.Wait()
} }
dir = c.base.Append(dirStatus)
if entries, readdirErr := os.ReadDir(dir.String()); readdirErr != nil {
if !errors.Is(readdirErr, os.ErrNotExist) {
addErr(dir, readdirErr)
}
} else {
wg.Add(len(entries))
for _, ent := range entries {
w <- checkEntry{ent, func(ent os.DirEntry, want *Checksum) bool {
got := p.Get().(*Checksum)
defer p.Put(got)
if _, err := os.Stat(c.base.Append(
dirIdentifier,
ent.Name(),
).String()); err != nil {
if !errors.Is(err, os.ErrNotExist) {
addErr(dir.Append(ent.Name()), err)
}
seMu.Lock()
se.DanglingStatus = append(se.DanglingStatus, *want)
seMu.Unlock()
return false
}
return true
}}
}
wg.Wait()
}
if len(c.identPending) > 0 { if len(c.identPending) > 0 {
addErr(c.base, errors.New( addErr(c.base, errors.New(
"scrub began with pending artifacts", "scrub began with pending artifacts",
@@ -846,6 +964,7 @@ func (c *Cache) Scrub(checks int) error {
if len(se.ChecksumMismatches) > 0 || if len(se.ChecksumMismatches) > 0 ||
len(se.DanglingIdentifiers) > 0 || len(se.DanglingIdentifiers) > 0 ||
len(se.DanglingStatus) > 0 ||
len(se.Errs) > 0 { len(se.Errs) > 0 {
slices.SortFunc(se.ChecksumMismatches, func(a, b ChecksumMismatchError) int { slices.SortFunc(se.ChecksumMismatches, func(a, b ChecksumMismatchError) int {
return bytes.Compare(a.Want[:], b.Want[:]) return bytes.Compare(a.Want[:], b.Want[:])
@@ -853,6 +972,9 @@ func (c *Cache) Scrub(checks int) error {
slices.SortFunc(se.DanglingIdentifiers, func(a, b ID) int { slices.SortFunc(se.DanglingIdentifiers, func(a, b ID) int {
return bytes.Compare(a[:], b[:]) return bytes.Compare(a[:], b[:])
}) })
slices.SortFunc(se.DanglingStatus, func(a, b ID) int {
return bytes.Compare(a[:], b[:])
})
return &se return &se
} else { } else {
return nil return nil
@@ -943,8 +1065,9 @@ func (c *Cache) openFile(f FileArtifact) (r io.ReadCloser, err error) {
if !errors.Is(err, os.ErrNotExist) { if !errors.Is(err, os.ErrNotExist) {
return return
} }
id := c.Ident(f)
if c.msg.IsVerbose() { if c.msg.IsVerbose() {
rn := reportName(f, c.Ident(f)) rn := reportName(f, id)
c.msg.Verbosef("curing %s in memory...", rn) c.msg.Verbosef("curing %s in memory...", rn)
defer func() { defer func() {
if err == nil { if err == nil {
@@ -1527,6 +1650,7 @@ func (c *Cache) cure(a Artifact, curesExempt bool) (
t := TContext{ t := TContext{
c.base.Append(dirWork, ids), c.base.Append(dirWork, ids),
c.base.Append(dirTemp, ids), c.base.Append(dirTemp, ids),
ids, nil, nil, nil,
common{c}, common{c},
} }
switch ca := a.(type) { switch ca := a.(type) {
@@ -1666,6 +1790,18 @@ func (pending *pendingArtifactDep) cure(c *Cache) {
pending.errsMu.Unlock() pending.errsMu.Unlock()
} }
// OpenStatus attempts to open the status file associated to an [Artifact]. If
// err is nil, the caller must close the resulting reader.
func (c *Cache) OpenStatus(a Artifact) (r io.ReadSeekCloser, err error) {
c.identMu.RLock()
r, err = os.Open(c.base.Append(
dirStatus,
Encode(c.Ident(a).Value())).String(),
)
c.identMu.RUnlock()
return
}
// Close cancels all pending cures and waits for them to clean up. // Close cancels all pending cures and waits for them to clean up.
func (c *Cache) Close() { func (c *Cache) Close() {
c.closeOnce.Do(func() { c.closeOnce.Do(func() {
@@ -1714,6 +1850,7 @@ func open(
for _, name := range []string{ for _, name := range []string{
dirIdentifier, dirIdentifier,
dirChecksum, dirChecksum,
dirStatus,
dirWork, dirWork,
} { } {
if err := os.MkdirAll(base.Append(name).String(), 0700); err != nil && if err := os.MkdirAll(base.Append(name).String(), 0700); err != nil &&

View File

@@ -314,6 +314,11 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
t.Fatal(err) t.Fatal(err)
} }
// destroy non-deterministic status files
if err := os.RemoveAll(base.Append("status").String()); err != nil {
t.Fatal(err)
}
var checksum pkg.Checksum var checksum pkg.Checksum
if err := pkg.HashDir(&checksum, base); err != nil { if err := pkg.HashDir(&checksum, base); err != nil {
t.Fatalf("HashDir: error = %v", err) t.Fatalf("HashDir: error = %v", err)
@@ -382,6 +387,9 @@ func cureMany(t *testing.T, c *pkg.Cache, steps []cureStep) {
} else if step.pathname != ignorePathname && !pathname.Is(step.pathname) { } else if step.pathname != ignorePathname && !pathname.Is(step.pathname) {
t.Fatalf("Cure: pathname = %q, want %q", pathname, step.pathname) t.Fatalf("Cure: pathname = %q, want %q", pathname, step.pathname)
} else if checksum != makeChecksumH(step.checksum) { } else if checksum != makeChecksumH(step.checksum) {
if checksum == (unique.Handle[pkg.Checksum]{}) {
checksum = unique.Make(pkg.Checksum{})
}
t.Fatalf( t.Fatalf(
"Cure: checksum = %s, want %s", "Cure: checksum = %s, want %s",
pkg.Encode(checksum.Value()), pkg.Encode(step.checksum), pkg.Encode(checksum.Value()), pkg.Encode(step.checksum),

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newAttr() pkg.Artifact { func (t Toolchain) newAttr() (pkg.Artifact, string) {
const ( const (
version = "2.5.2" version = "2.5.2"
checksum = "YWEphrz6vg1sUMmHHVr1CRo53pFXRhq_pjN-AlG8UgwZK1y6m7zuDhxqJhD0SV0l" checksum = "YWEphrz6vg1sUMmHHVr1CRo53pFXRhq_pjN-AlG8UgwZK1y6m7zuDhxqJhD0SV0l"
@@ -62,11 +62,21 @@ ln -s ../../system/bin/perl /usr/bin
`, `,
}, (*MakeHelper)(nil), }, (*MakeHelper)(nil),
Perl, Perl,
) ), version
} }
func init() { artifactsF[Attr] = Toolchain.newAttr } func init() {
artifactsM[Attr] = Metadata{
f: Toolchain.newAttr,
func (t Toolchain) newACL() pkg.Artifact { Name: "attr",
Description: "Commands for Manipulating Filesystem Extended Attributes",
Website: "https://savannah.nongnu.org/projects/attr/",
ID: 137,
}
}
func (t Toolchain) newACL() (pkg.Artifact, string) {
const ( const (
version = "2.3.2" version = "2.3.2"
checksum = "-fY5nwH4K8ZHBCRXrzLdguPkqjKI6WIiGu4dBtrZ1o0t6AIU73w8wwJz_UyjIS0P" checksum = "-fY5nwH4K8ZHBCRXrzLdguPkqjKI6WIiGu4dBtrZ1o0t6AIU73w8wwJz_UyjIS0P"
@@ -81,6 +91,16 @@ func (t Toolchain) newACL() pkg.Artifact {
SkipCheck: true, SkipCheck: true,
}, },
Attr, Attr,
) ), version
}
func init() {
artifactsM[ACL] = Metadata{
f: Toolchain.newACL,
Name: "acl",
Description: "Commands for Manipulating POSIX Access Control Lists",
Website: "https://savannah.nongnu.org/projects/acl/",
ID: 16,
}
} }
func init() { artifactsF[ACL] = Toolchain.newACL }

View File

@@ -1,6 +1,11 @@
package rosa package rosa
import ( import (
"context"
"encoding/json"
"errors"
"net/http"
"strconv"
"sync" "sync"
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
@@ -10,8 +15,14 @@ import (
type PArtifact int type PArtifact int
const ( const (
LLVMCompilerRT PArtifact = iota
LLVMRuntimes
LLVMClang
// EarlyInit is the Rosa OS initramfs init program.
EarlyInit
// ImageInitramfs is the Rosa OS initramfs archive. // ImageInitramfs is the Rosa OS initramfs archive.
ImageInitramfs PArtifact = iota ImageInitramfs
// Kernel is the generic Rosa OS Linux kernel. // Kernel is the generic Rosa OS Linux kernel.
Kernel Kernel
@@ -19,6 +30,8 @@ const (
KernelHeaders KernelHeaders
// KernelSource is a writable kernel source tree installed to [AbsUsrSrc]. // KernelSource is a writable kernel source tree installed to [AbsUsrSrc].
KernelSource KernelSource
// Firmware is firmware blobs for use with the Linux kernel.
Firmware
ACL ACL
ArgpStandalone ArgpStandalone
@@ -52,7 +65,6 @@ const (
Gzip Gzip
Hakurei Hakurei
HakureiDist HakureiDist
IniConfig
Kmod Kmod
LibXau LibXau
Libcap Libcap
@@ -77,10 +89,11 @@ const (
NSS NSS
NSSCACert NSSCACert
Ncurses Ncurses
Nettle
Ninja Ninja
OpenSSL OpenSSL
PCRE2 PCRE2
Packaging Parallel
Patch Patch
Perl Perl
PerlLocaleGettext PerlLocaleGettext
@@ -94,12 +107,25 @@ const (
PerlUnicodeGCString PerlUnicodeGCString
PerlYAMLTiny PerlYAMLTiny
PkgConfig PkgConfig
Pluggy
Procps Procps
PyTest
Pygments
Python Python
PythonCfgv
PythonDiscovery
PythonDistlib
PythonFilelock
PythonIdentify
PythonIniConfig
PythonNodeenv
PythonPackaging
PythonPlatformdirs
PythonPluggy
PythonPreCommit
PythonPyTest
PythonPyYAML
PythonPygments
PythonVirtualenv
QEMU QEMU
Rdfind
Rsync Rsync
Sed Sed
Setuptools Setuptools
@@ -120,7 +146,10 @@ const (
Zlib Zlib
Zstd Zstd
buildcatrust // PresetUnexportedStart is the first unexported preset.
PresetUnexportedStart
buildcatrust = iota - 1
utilMacros utilMacros
// Musl is a standalone libc that does not depend on the toolchain. // Musl is a standalone libc that does not depend on the toolchain.
@@ -134,135 +163,131 @@ const (
// part of the [Std] toolchain. // part of the [Std] toolchain.
Stage0 Stage0
// _presetEnd is the total number of presets and does not denote a preset. // PresetEnd is the total number of presets and does not denote a preset.
_presetEnd PresetEnd
) )
// Metadata is stage-agnostic information of a [PArtifact] not directly
// representable in the resulting [pkg.Artifact].
type Metadata struct {
f func(t Toolchain) (a pkg.Artifact, version string)
// Unique package name.
Name string `json:"name"`
// Short user-facing description.
Description string `json:"description"`
// Project home page.
Website string `json:"website,omitempty"`
// Project identifier on [Anitya].
//
// [Anitya]: https://release-monitoring.org/
ID int `json:"-"`
// Optional custom version checking behaviour.
latest func(v *Versions) string
}
// GetLatest returns the latest version described by v.
func (meta *Metadata) GetLatest(v *Versions) string {
if meta.latest != nil {
return meta.latest(v)
}
return v.Latest
}
// Unversioned denotes an unversioned [PArtifact].
const Unversioned = "\x00"
// UnpopulatedIDError is returned by [Metadata.GetLatest] for an instance of
// [Metadata] where ID is not populated.
type UnpopulatedIDError struct{}
func (UnpopulatedIDError) Unwrap() error { return errors.ErrUnsupported }
func (UnpopulatedIDError) Error() string { return "Anitya ID is not populated" }
// Versions are package versions returned by Anitya.
type Versions struct {
// The latest version for the project, as determined by the version sorting algorithm.
Latest string `json:"latest_version"`
// List of all versions that arent flagged as pre-release.
Stable []string `json:"stable_versions"`
// List of all versions stored, sorted from newest to oldest.
All []string `json:"versions"`
}
// getStable returns the first Stable version, or Latest if that is unavailable.
func (v *Versions) getStable() string {
if len(v.Stable) == 0 {
return v.Latest
}
return v.Stable[0]
}
// GetVersions returns versions fetched from Anitya.
func (meta *Metadata) GetVersions(ctx context.Context) (*Versions, error) {
if meta.ID == 0 {
return nil, UnpopulatedIDError{}
}
var resp *http.Response
if req, err := http.NewRequestWithContext(
ctx,
http.MethodGet,
"https://release-monitoring.org/api/v2/versions/?project_id="+
strconv.Itoa(meta.ID),
nil,
); err != nil {
return nil, err
} else {
req.Header.Set("User-Agent", "Rosa/1.1")
if resp, err = http.DefaultClient.Do(req); err != nil {
return nil, err
}
}
var v Versions
err := json.NewDecoder(resp.Body).Decode(&v)
return &v, errors.Join(err, resp.Body.Close())
}
var ( var (
// artifactsF is an array of functions for the result of [PArtifact]. // artifactsM is an array of [PArtifact] metadata.
artifactsF [_presetEnd]func(t Toolchain) pkg.Artifact artifactsM [PresetEnd]Metadata
// artifacts stores the result of artifactsF. // artifacts stores the result of Metadata.f.
artifacts [_toolchainEnd][len(artifactsF)]pkg.Artifact artifacts [_toolchainEnd][len(artifactsM)]pkg.Artifact
// versions stores the version of [PArtifact].
versions [_toolchainEnd][len(artifactsM)]string
// artifactsOnce is for lazy initialisation of artifacts. // artifactsOnce is for lazy initialisation of artifacts.
artifactsOnce [_toolchainEnd][len(artifactsF)]sync.Once artifactsOnce [_toolchainEnd][len(artifactsM)]sync.Once
) )
// GetMetadata returns [Metadata] of a [PArtifact].
func GetMetadata(p PArtifact) *Metadata { return &artifactsM[p] }
// Load returns the resulting [pkg.Artifact] of [PArtifact]. // Load returns the resulting [pkg.Artifact] of [PArtifact].
func (t Toolchain) Load(p PArtifact) pkg.Artifact { func (t Toolchain) Load(p PArtifact) pkg.Artifact {
artifactsOnce[t][p].Do(func() { artifactsOnce[t][p].Do(func() {
artifacts[t][p] = artifactsF[p](t) artifacts[t][p], versions[t][p] = artifactsM[p].f(t)
}) })
return artifacts[t][p] return artifacts[t][p]
} }
// Version returns the version string of [PArtifact].
func (t Toolchain) Version(p PArtifact) string {
artifactsOnce[t][p].Do(func() {
artifacts[t][p], versions[t][p] = artifactsM[p].f(t)
})
return versions[t][p]
}
// ResolveName returns a [PArtifact] by name. // ResolveName returns a [PArtifact] by name.
func ResolveName(name string) (p PArtifact, ok bool) { func ResolveName(name string) (p PArtifact, ok bool) {
p, ok = map[string]PArtifact{ for i := range PresetUnexportedStart {
"initramfs-image": ImageInitramfs, if name == artifactsM[i].Name {
return i, true
"kernel": Kernel, }
"kernel-headers": KernelHeaders, }
"kernel-source": KernelSource, return 0, false
"acl": ACL,
"argp-standalone": ArgpStandalone,
"attr": Attr,
"autoconf": Autoconf,
"automake": Automake,
"bc": BC,
"bash": Bash,
"binutils": Binutils,
"bison": Bison,
"bzip2": Bzip2,
"cmake": CMake,
"coreutils": Coreutils,
"curl": Curl,
"dtc": DTC,
"diffutils": Diffutils,
"elfutils": Elfutils,
"fakeroot": Fakeroot,
"findutils": Findutils,
"flex": Flex,
"fuse": Fuse,
"gmp": GMP,
"glib": GLib,
"gawk": Gawk,
"gen_init_cpio": GenInitCPIO,
"gettext": Gettext,
"git": Git,
"go": Go,
"gperf": Gperf,
"grep": Grep,
"gzip": Gzip,
"hakurei": Hakurei,
"hakurei-dist": HakureiDist,
"iniconfig": IniConfig,
"kmod": Kmod,
"libXau": LibXau,
"libcap": Libcap,
"libexpat": Libexpat,
"libiconv": Libiconv,
"libpsl": Libpsl,
"libseccomp": Libseccomp,
"libucontext": Libucontext,
"libxml2": Libxml2,
"libxslt": Libxslt,
"libffi": Libffi,
"libgd": Libgd,
"libtool": Libtool,
"m4": M4,
"mpc": MPC,
"mpfr": MPFR,
"make": Make,
"meson": Meson,
"mksh": Mksh,
"musl-fts": MuslFts,
"musl-obstack": MuslObstack,
"nss": NSS,
"nss-cacert": NSSCACert,
"ncurses": Ncurses,
"ninja": Ninja,
"openssl": OpenSSL,
"pcre2": PCRE2,
"packaging": Packaging,
"patch": Patch,
"perl": Perl,
"Locale::gettext": PerlLocaleGettext,
"MIME::Charset": PerlMIMECharset,
"Module::Build": PerlModuleBuild,
"Pod::Parser": PerlPodParser,
"SGMLS": PerlSGMLS,
"Term::ReadKey": PerlTermReadKey,
"Text::CharWidth": PerlTextCharWidth,
"Text::WrapI18N": PerlTextWrapI18N,
"Unicode::GCString": PerlUnicodeGCString,
"YAML::Tiny": PerlYAMLTiny,
"pkg-config": PkgConfig,
"pluggy": Pluggy,
"procps": Procps,
"pytest": PyTest,
"pygments": Pygments,
"python": Python,
"qemu": QEMU,
"rsync": Rsync,
"sed": Sed,
"setuptools": Setuptools,
"squashfs-tools": SquashfsTools,
"tamago": TamaGo,
"tar": Tar,
"texinfo": Texinfo,
"toybox": Toybox,
"unzip": Unzip,
"util-linux": UtilLinux,
"wayland": Wayland,
"wayland-protocols": WaylandProtocols,
"xcb": XCB,
"xcb-proto": XCBProto,
"xproto": Xproto,
"xz": XZ,
"zlib": Zlib,
"zstd": Zstd,
}[name]
return
} }

66
internal/rosa/all_test.go Normal file
View File

@@ -0,0 +1,66 @@
package rosa_test
import (
"testing"
"hakurei.app/internal/rosa"
)
func TestLoad(t *testing.T) {
t.Parallel()
for i := range rosa.PresetEnd {
p := rosa.PArtifact(i)
t.Run(rosa.GetMetadata(p).Name, func(t *testing.T) {
t.Parallel()
rosa.Std.Load(p)
})
}
}
func TestResolveName(t *testing.T) {
t.Parallel()
for i := range rosa.PresetUnexportedStart {
p := i
name := rosa.GetMetadata(p).Name
t.Run(name, func(t *testing.T) {
t.Parallel()
if got, ok := rosa.ResolveName(name); !ok {
t.Fatal("ResolveName: ok = false")
} else if got != p {
t.Fatalf("ResolveName: %d, want %d", got, p)
}
})
}
}
func TestResolveNameUnexported(t *testing.T) {
t.Parallel()
for i := rosa.PresetUnexportedStart; i < rosa.PresetEnd; i++ {
p := i
name := rosa.GetMetadata(p).Name
t.Run(name, func(t *testing.T) {
t.Parallel()
if got, ok := rosa.ResolveName(name); ok {
t.Fatalf("ResolveName: resolved unexported preset %d", got)
}
})
}
}
func TestUnique(t *testing.T) {
t.Parallel()
names := make(map[string]struct{})
for i := range rosa.PresetEnd {
name := rosa.GetMetadata(rosa.PArtifact(i)).Name
if _, ok := names[name]; ok {
t.Fatalf("name %s is not unique", name)
}
names[name] = struct{}{}
}
}

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newArgpStandalone() pkg.Artifact { func (t Toolchain) newArgpStandalone() (pkg.Artifact, string) {
const ( const (
version = "1.3" version = "1.3"
checksum = "vtW0VyO2pJ-hPyYmDI2zwSLS8QL0sPAUKC1t3zNYbwN2TmsaE-fADhaVtNd3eNFl" checksum = "vtW0VyO2pJ-hPyYmDI2zwSLS8QL0sPAUKC1t3zNYbwN2TmsaE-fADhaVtNd3eNFl"
@@ -23,6 +23,14 @@ install -D -m755 libargp.a /work/system/lib/libargp.a
`, `,
}, },
Diffutils, Diffutils,
) ), version
}
func init() {
artifactsM[ArgpStandalone] = Metadata{
f: Toolchain.newArgpStandalone,
Name: "argp-standalone",
Description: "hierarchical argument parsing library broken out from glibc",
Website: "http://www.lysator.liu.se/~nisse/misc/",
}
} }
func init() { artifactsF[ArgpStandalone] = Toolchain.newArgpStandalone }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newBzip2() pkg.Artifact { func (t Toolchain) newBzip2() (pkg.Artifact, string) {
const ( const (
version = "1.0.8" version = "1.0.8"
checksum = "cTLykcco7boom-s05H1JVsQi1AtChYL84nXkg_92Dm1Xt94Ob_qlMg_-NSguIK-c" checksum = "cTLykcco7boom-s05H1JVsQi1AtChYL84nXkg_92Dm1Xt94Ob_qlMg_-NSguIK-c"
@@ -23,6 +23,16 @@ func (t Toolchain) newBzip2() pkg.Artifact {
"CC=cc", "CC=cc",
}, },
Install: "make PREFIX=/work/system install", Install: "make PREFIX=/work/system install",
}) }), version
}
func init() {
artifactsM[Bzip2] = Metadata{
f: Toolchain.newBzip2,
Name: "bzip2",
Description: "a freely available, patent free, high-quality data compressor",
Website: "https://sourceware.org/bzip2/",
ID: 237,
}
} }
func init() { artifactsF[Bzip2] = Toolchain.newBzip2 }

View File

@@ -8,7 +8,7 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newCMake() pkg.Artifact { func (t Toolchain) newCMake() (pkg.Artifact, string) {
const ( const (
version = "4.2.3" version = "4.2.3"
checksum = "Y4uYGnLrDQX78UdzH7fMzfok46Nt_1taDIHSmqgboU1yFi6f0iAXBDegMCu4eS-J" checksum = "Y4uYGnLrDQX78UdzH7fMzfok46Nt_1taDIHSmqgboU1yFi6f0iAXBDegMCu4eS-J"
@@ -102,9 +102,19 @@ index 2ead810437..f85cbb8b1c 100644
}, },
}, },
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[CMake] = Metadata{
f: Toolchain.newCMake,
Name: "cmake",
Description: "cross-platform, open-source build system",
Website: "https://cmake.org/",
ID: 306,
}
} }
func init() { artifactsF[CMake] = Toolchain.newCMake }
// CMakeHelper is the [CMake] build system helper. // CMakeHelper is the [CMake] build system helper.
type CMakeHelper struct { type CMakeHelper struct {
@@ -118,6 +128,9 @@ type CMakeHelper struct {
Cache [][2]string Cache [][2]string
// Runs after install. // Runs after install.
Script string Script string
// Whether to generate Makefile instead.
Make bool
} }
var _ Helper = new(CMakeHelper) var _ Helper = new(CMakeHelper)
@@ -131,7 +144,10 @@ func (attr *CMakeHelper) name(name, version string) string {
} }
// extra returns a hardcoded slice of [CMake] and [Ninja]. // extra returns a hardcoded slice of [CMake] and [Ninja].
func (*CMakeHelper) extra(int) []PArtifact { func (attr *CMakeHelper) extra(int) []PArtifact {
if attr != nil && attr.Make {
return []PArtifact{CMake, Make}
}
return []PArtifact{CMake, Ninja} return []PArtifact{CMake, Ninja}
} }
@@ -163,11 +179,19 @@ func (attr *CMakeHelper) script(name string) string {
panic("CACHE must be non-empty") panic("CACHE must be non-empty")
} }
generate := "Ninja"
jobs := ""
if attr.Make {
generate = "'Unix Makefiles'"
jobs += ` "--parallel=$(nproc)"`
}
return ` return `
cmake -G Ninja \ cmake -G ` + generate + ` \
-DCMAKE_C_COMPILER_TARGET="${ROSA_TRIPLE}" \ -DCMAKE_C_COMPILER_TARGET="${ROSA_TRIPLE}" \
-DCMAKE_CXX_COMPILER_TARGET="${ROSA_TRIPLE}" \ -DCMAKE_CXX_COMPILER_TARGET="${ROSA_TRIPLE}" \
-DCMAKE_ASM_COMPILER_TARGET="${ROSA_TRIPLE}" \ -DCMAKE_ASM_COMPILER_TARGET="${ROSA_TRIPLE}" \
-DCMAKE_INSTALL_LIBDIR=lib \
` + strings.Join(slices.Collect(func(yield func(string) bool) { ` + strings.Join(slices.Collect(func(yield func(string) bool) {
for _, v := range attr.Cache { for _, v := range attr.Cache {
if !yield("-D" + v[0] + "=" + v[1]) { if !yield("-D" + v[0] + "=" + v[1]) {
@@ -175,9 +199,9 @@ cmake -G Ninja \
} }
} }
}), " \\\n\t") + ` \ }), " \\\n\t") + ` \
-DCMAKE_INSTALL_PREFIX=/work/system \ -DCMAKE_INSTALL_PREFIX=/system \
'/usr/src/` + name + `/` + path.Join(attr.Append...) + `' '/usr/src/` + name + `/` + path.Join(attr.Append...) + `'
cmake --build . cmake --build .` + jobs + `
cmake --install . cmake --install . --prefix=/work/system
` + attr.Script ` + attr.Script
} }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newCurl() pkg.Artifact { func (t Toolchain) newCurl() (pkg.Artifact, string) {
const ( const (
version = "8.18.0" version = "8.18.0"
checksum = "YpOolP_sx1DIrCEJ3elgVAu0wTLDS-EZMZFvOP0eha7FaLueZUlEpuMwDzJNyi7i" checksum = "YpOolP_sx1DIrCEJ3elgVAu0wTLDS-EZMZFvOP0eha7FaLueZUlEpuMwDzJNyi7i"
@@ -25,6 +25,16 @@ func (t Toolchain) newCurl() pkg.Artifact {
Libpsl, Libpsl,
OpenSSL, OpenSSL,
) ), version
}
func init() {
artifactsM[Curl] = Metadata{
f: Toolchain.newCurl,
Name: "curl",
Description: "command line tool and library for transferring data with URLs",
Website: "https://curl.se/",
ID: 381,
}
} }
func init() { artifactsF[Curl] = Toolchain.newCurl }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newDTC() pkg.Artifact { func (t Toolchain) newDTC() (pkg.Artifact, string) {
const ( const (
version = "1.7.2" version = "1.7.2"
checksum = "vUoiRynPyYRexTpS6USweT5p4SVHvvVJs8uqFkkVD-YnFjwf6v3elQ0-Etrh00Dt" checksum = "vUoiRynPyYRexTpS6USweT5p4SVHvvVJs8uqFkkVD-YnFjwf6v3elQ0-Etrh00Dt"
@@ -28,6 +28,16 @@ func (t Toolchain) newDTC() pkg.Artifact {
M4, M4,
Coreutils, Coreutils,
Diffutils, Diffutils,
) ), version
}
func init() {
artifactsM[DTC] = Metadata{
f: Toolchain.newDTC,
Name: "dtc",
Description: "The Device Tree Compiler",
Website: "https://git.kernel.org/pub/scm/utils/dtc/dtc.git/",
ID: 16911,
}
} }
func init() { artifactsF[DTC] = Toolchain.newDTC }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newElfutils() pkg.Artifact { func (t Toolchain) newElfutils() (pkg.Artifact, string) {
const ( const (
version = "0.194" version = "0.194"
checksum = "Q3XUygUPv9vR1TkWucwUsQ8Kb1_F6gzk-KMPELr3cC_4AcTrprhVPMvN0CKkiYRa" checksum = "Q3XUygUPv9vR1TkWucwUsQ8Kb1_F6gzk-KMPELr3cC_4AcTrprhVPMvN0CKkiYRa"
@@ -36,6 +36,16 @@ func (t Toolchain) newElfutils() pkg.Artifact {
MuslFts, MuslFts,
MuslObstack, MuslObstack,
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[Elfutils] = Metadata{
f: Toolchain.newElfutils,
Name: "elfutils",
Description: "utilities and libraries to handle ELF files and DWARF data",
Website: "https://sourceware.org/elfutils/",
ID: 5679,
}
} }
func init() { artifactsF[Elfutils] = Toolchain.newElfutils }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newFakeroot() pkg.Artifact { func (t Toolchain) newFakeroot() (pkg.Artifact, string) {
const ( const (
version = "1.37.2" version = "1.37.2"
checksum = "4ve-eDqVspzQ6VWDhPS0NjW3aSenBJcPAJq_BFT7OOFgUdrQzoTBxZWipDAGWxF8" checksum = "4ve-eDqVspzQ6VWDhPS0NjW3aSenBJcPAJq_BFT7OOFgUdrQzoTBxZWipDAGWxF8"
@@ -46,6 +46,16 @@ index f135ad9..85c784c 100644
Attr, Attr,
Libcap, Libcap,
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[Fakeroot] = Metadata{
f: Toolchain.newFakeroot,
Name: "fakeroot",
Description: "tool for simulating superuser privileges",
Website: "https://salsa.debian.org/clint/fakeroot",
ID: 12048,
}
} }
func init() { artifactsF[Fakeroot] = Toolchain.newFakeroot }

View File

@@ -4,7 +4,7 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newFlex() pkg.Artifact { func (t Toolchain) newFlex() (pkg.Artifact, string) {
const ( const (
version = "2.6.4" version = "2.6.4"
checksum = "p9POjQU7VhgOf3x5iFro8fjhy0NOanvA7CTeuWS_veSNgCixIJshTrWVkc5XLZkB" checksum = "p9POjQU7VhgOf3x5iFro8fjhy0NOanvA7CTeuWS_veSNgCixIJshTrWVkc5XLZkB"
@@ -16,6 +16,16 @@ func (t Toolchain) newFlex() pkg.Artifact {
pkg.TarGzip, pkg.TarGzip,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
M4, M4,
) ), version
}
func init() {
artifactsM[Flex] = Metadata{
f: Toolchain.newFlex,
Name: "flex",
Description: "scanner generator for lexing in C and C++",
Website: "https://github.com/westes/flex/",
ID: 819,
}
} }
func init() { artifactsF[Flex] = Toolchain.newFlex }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newFuse() pkg.Artifact { func (t Toolchain) newFuse() (pkg.Artifact, string) {
const ( const (
version = "3.18.1" version = "3.18.1"
checksum = "COb-BgJRWXLbt9XUkNeuiroQizpMifXqxgieE1SlkMXhs_WGSyJStrmyewAw2hd6" checksum = "COb-BgJRWXLbt9XUkNeuiroQizpMifXqxgieE1SlkMXhs_WGSyJStrmyewAw2hd6"
@@ -24,13 +24,23 @@ func (t Toolchain) newFuse() pkg.Artifact {
// this project uses pytest // this project uses pytest
SkipTest: true, SkipTest: true,
}, },
IniConfig, PythonIniConfig,
Packaging, PythonPackaging,
Pluggy, PythonPluggy,
Pygments, PythonPygments,
PyTest, PythonPyTest,
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[Fuse] = Metadata{
f: Toolchain.newFuse,
Name: "fuse",
Description: "the reference implementation of the Linux FUSE interface",
Website: "https://github.com/libfuse/libfuse/",
ID: 861,
}
} }
func init() { artifactsF[Fuse] = Toolchain.newFuse }

View File

@@ -2,10 +2,10 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newGit() pkg.Artifact { func (t Toolchain) newGit() (pkg.Artifact, string) {
const ( const (
version = "2.52.0" version = "2.53.0"
checksum = "uH3J1HAN_c6PfGNJd2OBwW4zo36n71wmkdvityYnrh8Ak0D1IifiAvEWz9Vi9DmS" checksum = "rlqSTeNgSeVKJA7nvzGqddFH8q3eFEPB4qRZft-4zth8wTHnbTbm7J90kp_obHGm"
) )
return t.NewPackage("git", version, pkg.NewHTTPGetTar( return t.NewPackage("git", version, pkg.NewHTTPGetTar(
nil, "https://www.kernel.org/pub/software/scm/git/"+ nil, "https://www.kernel.org/pub/software/scm/git/"+
@@ -63,9 +63,19 @@ disable_test t2200-add-update
Curl, Curl,
OpenSSL, OpenSSL,
Libexpat, Libexpat,
) ), version
}
func init() {
artifactsM[Git] = Metadata{
f: Toolchain.newGit,
Name: "git",
Description: "distributed version control system",
Website: "https://www.git-scm.com/",
ID: 5350,
}
} }
func init() { artifactsF[Git] = Toolchain.newGit }
// NewViaGit returns a [pkg.Artifact] for cloning a git repository. // NewViaGit returns a [pkg.Artifact] for cloning a git repository.
func (t Toolchain) NewViaGit( func (t Toolchain) NewViaGit(

View File

@@ -2,10 +2,10 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newM4() pkg.Artifact { func (t Toolchain) newM4() (pkg.Artifact, string) {
const ( const (
version = "1.4.20" version = "1.4.21"
checksum = "RT0_L3m4Co86bVBY3lCFAEs040yI1WdeNmRylFpah8IZovTm6O4wI7qiHJN3qsW9" checksum = "pPa6YOo722Jw80l1OsH1tnUaklnPFjFT-bxGw5iAVrZTm1P8FQaWao_NXop46-pm"
) )
return t.NewPackage("m4", version, pkg.NewHTTPGetTar( return t.NewPackage("m4", version, pkg.NewHTTPGetTar(
nil, "https://ftpmirror.gnu.org/gnu/m4/m4-"+version+".tar.bz2", nil, "https://ftpmirror.gnu.org/gnu/m4/m4-"+version+".tar.bz2",
@@ -18,11 +18,23 @@ chmod +w tests/test-c32ispunct.sh && echo '#!/bin/sh' > tests/test-c32ispunct.sh
`, `,
}, (*MakeHelper)(nil), }, (*MakeHelper)(nil),
Diffutils, Diffutils,
)
}
func init() { artifactsF[M4] = Toolchain.newM4 }
func (t Toolchain) newBison() pkg.Artifact { KernelHeaders,
), version
}
func init() {
artifactsM[M4] = Metadata{
f: Toolchain.newM4,
Name: "m4",
Description: "a macro processor with GNU extensions",
Website: "https://www.gnu.org/software/m4/",
ID: 1871,
}
}
func (t Toolchain) newBison() (pkg.Artifact, string) {
const ( const (
version = "3.8.2" version = "3.8.2"
checksum = "BhRM6K7URj1LNOkIDCFDctSErLS-Xo5d9ba9seg10o6ACrgC1uNhED7CQPgIY29Y" checksum = "BhRM6K7URj1LNOkIDCFDctSErLS-Xo5d9ba9seg10o6ACrgC1uNhED7CQPgIY29Y"
@@ -35,11 +47,21 @@ func (t Toolchain) newBison() pkg.Artifact {
M4, M4,
Diffutils, Diffutils,
Sed, Sed,
) ), version
} }
func init() { artifactsF[Bison] = Toolchain.newBison } func init() {
artifactsM[Bison] = Metadata{
f: Toolchain.newBison,
func (t Toolchain) newSed() pkg.Artifact { Name: "bison",
Description: "a general-purpose parser generator",
Website: "https://www.gnu.org/software/bison/",
ID: 193,
}
}
func (t Toolchain) newSed() (pkg.Artifact, string) {
const ( const (
version = "4.9" version = "4.9"
checksum = "pe7HWH4PHNYrazOTlUoE1fXmhn2GOPFN_xE62i0llOr3kYGrH1g2_orDz0UtZ9Nt" checksum = "pe7HWH4PHNYrazOTlUoE1fXmhn2GOPFN_xE62i0llOr3kYGrH1g2_orDz0UtZ9Nt"
@@ -50,11 +72,21 @@ func (t Toolchain) newSed() pkg.Artifact {
pkg.TarGzip, pkg.TarGzip,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
Diffutils, Diffutils,
) ), version
} }
func init() { artifactsF[Sed] = Toolchain.newSed } func init() {
artifactsM[Sed] = Metadata{
f: Toolchain.newSed,
func (t Toolchain) newAutoconf() pkg.Artifact { Name: "sed",
Description: "a non-interactive command-line text editor",
Website: "https://www.gnu.org/software/sed/",
ID: 4789,
}
}
func (t Toolchain) newAutoconf() (pkg.Artifact, string) {
const ( const (
version = "2.72" version = "2.72"
checksum = "-c5blYkC-xLDer3TWEqJTyh1RLbOd1c5dnRLKsDnIrg_wWNOLBpaqMY8FvmUFJ33" checksum = "-c5blYkC-xLDer3TWEqJTyh1RLbOd1c5dnRLKsDnIrg_wWNOLBpaqMY8FvmUFJ33"
@@ -75,11 +107,21 @@ func (t Toolchain) newAutoconf() pkg.Artifact {
Perl, Perl,
Bash, Bash,
Diffutils, Diffutils,
) ), version
} }
func init() { artifactsF[Autoconf] = Toolchain.newAutoconf } func init() {
artifactsM[Autoconf] = Metadata{
f: Toolchain.newAutoconf,
func (t Toolchain) newAutomake() pkg.Artifact { Name: "autoconf",
Description: "M4 macros to produce self-contained configure script",
Website: "https://www.gnu.org/software/autoconf/",
ID: 141,
}
}
func (t Toolchain) newAutomake() (pkg.Artifact, string) {
const ( const (
version = "1.18.1" version = "1.18.1"
checksum = "FjvLG_GdQP7cThTZJLDMxYpRcKdpAVG-YDs1Fj1yaHlSdh_Kx6nRGN14E0r_BjcG" checksum = "FjvLG_GdQP7cThTZJLDMxYpRcKdpAVG-YDs1Fj1yaHlSdh_Kx6nRGN14E0r_BjcG"
@@ -107,11 +149,21 @@ test_disable '#!/bin/sh' t/pr9.sh
Gzip, Gzip,
Autoconf, Autoconf,
Diffutils, Diffutils,
) ), version
} }
func init() { artifactsF[Automake] = Toolchain.newAutomake } func init() {
artifactsM[Automake] = Metadata{
f: Toolchain.newAutomake,
func (t Toolchain) newLibtool() pkg.Artifact { Name: "automake",
Description: "a tool for automatically generating Makefile.in files",
Website: "https://www.gnu.org/software/automake/",
ID: 144,
}
}
func (t Toolchain) newLibtool() (pkg.Artifact, string) {
const ( const (
version = "2.5.4" version = "2.5.4"
checksum = "pa6LSrQggh8mSJHQfwGjysAApmZlGJt8wif2cCLzqAAa2jpsTY0jZ-6stS3BWZ2Q" checksum = "pa6LSrQggh8mSJHQfwGjysAApmZlGJt8wif2cCLzqAAa2jpsTY0jZ-6stS3BWZ2Q"
@@ -128,11 +180,21 @@ func (t Toolchain) newLibtool() pkg.Artifact {
}, },
M4, M4,
Diffutils, Diffutils,
) ), version
} }
func init() { artifactsF[Libtool] = Toolchain.newLibtool } func init() {
artifactsM[Libtool] = Metadata{
f: Toolchain.newLibtool,
func (t Toolchain) newGzip() pkg.Artifact { Name: "libtool",
Description: "a generic library support script",
Website: "https://www.gnu.org/software/libtool/",
ID: 1741,
}
}
func (t Toolchain) newGzip() (pkg.Artifact, string) {
const ( const (
version = "1.14" version = "1.14"
checksum = "NWhjUavnNfTDFkZJyAUonL9aCOak8GVajWX2OMlzpFnuI0ErpBFyj88mz2xSjz0q" checksum = "NWhjUavnNfTDFkZJyAUonL9aCOak8GVajWX2OMlzpFnuI0ErpBFyj88mz2xSjz0q"
@@ -144,11 +206,21 @@ func (t Toolchain) newGzip() pkg.Artifact {
), nil, &MakeHelper{ ), nil, &MakeHelper{
// dependency loop // dependency loop
SkipCheck: true, SkipCheck: true,
}) }), version
} }
func init() { artifactsF[Gzip] = Toolchain.newGzip } func init() {
artifactsM[Gzip] = Metadata{
f: Toolchain.newGzip,
func (t Toolchain) newGettext() pkg.Artifact { Name: "gzip",
Description: "a popular data compression program",
Website: "https://www.gnu.org/software/gzip/",
ID: 1290,
}
}
func (t Toolchain) newGettext() (pkg.Artifact, string) {
const ( const (
version = "1.0" version = "1.0"
checksum = "3MasKeEdPeFEgWgzsBKk7JqWqql1wEMbgPmzAfs-mluyokoW0N8oQVxPQoOnSdgC" checksum = "3MasKeEdPeFEgWgzsBKk7JqWqql1wEMbgPmzAfs-mluyokoW0N8oQVxPQoOnSdgC"
@@ -180,11 +252,21 @@ touch gettext-tools/autotools/archive.dir.tar
Sed, Sed,
KernelHeaders, KernelHeaders,
) ), version
} }
func init() { artifactsF[Gettext] = Toolchain.newGettext } func init() {
artifactsM[Gettext] = Metadata{
f: Toolchain.newGettext,
func (t Toolchain) newDiffutils() pkg.Artifact { Name: "gettext",
Description: "tools for producing multi-lingual messages",
Website: "https://www.gnu.org/software/gettext/",
ID: 898,
}
}
func (t Toolchain) newDiffutils() (pkg.Artifact, string) {
const ( const (
version = "3.12" version = "3.12"
checksum = "9J5VAq5oA7eqwzS1Yvw-l3G5o-TccUrNQR3PvyB_lgdryOFAfxtvQfKfhdpquE44" checksum = "9J5VAq5oA7eqwzS1Yvw-l3G5o-TccUrNQR3PvyB_lgdryOFAfxtvQfKfhdpquE44"
@@ -203,11 +285,21 @@ test_disable 'int main(){return 0;}' gnulib-tests/test-c32ispunct.c
test_disable '#!/bin/sh' tests/cmp test_disable '#!/bin/sh' tests/cmp
`, `,
Flag: TEarly, Flag: TEarly,
}, (*MakeHelper)(nil)) }, (*MakeHelper)(nil)), version
} }
func init() { artifactsF[Diffutils] = Toolchain.newDiffutils } func init() {
artifactsM[Diffutils] = Metadata{
f: Toolchain.newDiffutils,
func (t Toolchain) newPatch() pkg.Artifact { Name: "diffutils",
Description: "several programs related to finding differences between files",
Website: "https://www.gnu.org/software/diffutils/",
ID: 436,
}
}
func (t Toolchain) newPatch() (pkg.Artifact, string) {
const ( const (
version = "2.8" version = "2.8"
checksum = "MA0BQc662i8QYBD-DdGgyyfTwaeALZ1K0yusV9rAmNiIsQdX-69YC4t9JEGXZkeR" checksum = "MA0BQc662i8QYBD-DdGgyyfTwaeALZ1K0yusV9rAmNiIsQdX-69YC4t9JEGXZkeR"
@@ -225,11 +317,21 @@ test_disable '#!/bin/sh' tests/ed-style
test_disable '#!/bin/sh' tests/need-filename test_disable '#!/bin/sh' tests/need-filename
`, `,
Flag: TEarly, Flag: TEarly,
}, (*MakeHelper)(nil)) }, (*MakeHelper)(nil)), version
} }
func init() { artifactsF[Patch] = Toolchain.newPatch } func init() {
artifactsM[Patch] = Metadata{
f: Toolchain.newPatch,
func (t Toolchain) newBash() pkg.Artifact { Name: "patch",
Description: "a program to apply diff output to files",
Website: "https://savannah.gnu.org/projects/patch/",
ID: 2597,
}
}
func (t Toolchain) newBash() (pkg.Artifact, string) {
const ( const (
version = "5.3" version = "5.3"
checksum = "4LQ_GRoB_ko-Ih8QPf_xRKA02xAm_TOxQgcJLmFDT6udUPxTAWrsj-ZNeuTusyDq" checksum = "4LQ_GRoB_ko-Ih8QPf_xRKA02xAm_TOxQgcJLmFDT6udUPxTAWrsj-ZNeuTusyDq"
@@ -245,14 +347,24 @@ func (t Toolchain) newBash() pkg.Artifact {
Configure: [][2]string{ Configure: [][2]string{
{"without-bash-malloc"}, {"without-bash-malloc"},
}, },
}) }), version
} }
func init() { artifactsF[Bash] = Toolchain.newBash } func init() {
artifactsM[Bash] = Metadata{
f: Toolchain.newBash,
func (t Toolchain) newCoreutils() pkg.Artifact { Name: "bash",
Description: "the Bourne Again SHell",
Website: "https://www.gnu.org/software/bash/",
ID: 166,
}
}
func (t Toolchain) newCoreutils() (pkg.Artifact, string) {
const ( const (
version = "9.9" version = "9.10"
checksum = "B1_TaXj1j5aiVIcazLWu8Ix03wDV54uo2_iBry4qHG6Y-9bjDpUPlkNLmU_3Nvw6" checksum = "o-B9wssRnZySzJUI1ZJAgw-bZtj1RC67R9po2AcM2OjjS8FQIl16IRHpC6IwO30i"
) )
return t.NewPackage("coreutils", version, pkg.NewHTTPGetTar( return t.NewPackage("coreutils", version, pkg.NewHTTPGetTar(
nil, "https://ftpmirror.gnu.org/gnu/coreutils/coreutils-"+version+".tar.gz", nil, "https://ftpmirror.gnu.org/gnu/coreutils/coreutils-"+version+".tar.gz",
@@ -265,12 +377,105 @@ test_disable() { chmod +w "$2" && echo "$1" > "$2"; }
test_disable '#!/bin/sh' gnulib-tests/test-c32ispunct.sh test_disable '#!/bin/sh' gnulib-tests/test-c32ispunct.sh
test_disable '#!/bin/sh' tests/split/line-bytes.sh test_disable '#!/bin/sh' tests/split/line-bytes.sh
test_disable '#!/bin/sh' tests/dd/no-allocate.sh test_disable '#!/bin/sh' tests/ls/hyperlink.sh
test_disable '#!/bin/sh' tests/env/env.sh
test_disable 'int main(){return 0;}' gnulib-tests/test-chown.c test_disable 'int main(){return 0;}' gnulib-tests/test-chown.c
test_disable 'int main(){return 0;}' gnulib-tests/test-fchownat.c test_disable 'int main(){return 0;}' gnulib-tests/test-fchownat.c
test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c
`, `,
Patches: [][2]string{
{"tests-fix-job-control", `From 21d287324aa43aa3a31f39619ade0deac7fd6013 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
Date: Tue, 24 Feb 2026 15:44:41 +0000
Subject: [PATCH] tests: fix job control triggering test termination
This avoids the test harness being terminated like:
make[1]: *** [Makefile:24419: check-recursive] Hangup
make[3]: *** [Makefile:24668: check-TESTS] Hangup
make: *** [Makefile:24922: check] Hangup
make[2]: *** [Makefile:24920: check-am] Hangup
make[4]: *** [Makefile:24685: tests/misc/usage_vs_refs.log] Error 129
...
This happened sometimes when the tests were being run non interactively.
For example when run like:
setsid make TESTS="tests/timeout/timeout.sh \
tests/tail/overlay-headers.sh" SUBDIRS=. -j2 check
Note the race window can be made bigger by adding a sleep
after tail is stopped in overlay-headers.sh
The race can trigger the kernel to induce its job control
mechanism to prevent stuck processes.
I.e. where it sends SIGHUP + SIGCONT to a process group
when it determines that group may become orphaned,
and there are stopped processes in that group.
* tests/tail/overlay-headers.sh: Use setsid(1) to keep the stopped
tail process in a separate process group, thus avoiding any kernel
job control protection mechanism.
* tests/timeout/timeout.sh: Use setsid(1) to avoid the kernel
checking the main process group when sleep(1) is reparented.
Fixes https://bugs.gnu.org/80477
---
tests/tail/overlay-headers.sh | 8 +++++++-
tests/timeout/timeout.sh | 11 ++++++++---
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/tests/tail/overlay-headers.sh b/tests/tail/overlay-headers.sh
index be9b6a7df..1e6da0a3f 100755
--- a/tests/tail/overlay-headers.sh
+++ b/tests/tail/overlay-headers.sh
@@ -20,6 +20,8 @@
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
print_ver_ tail sleep
+setsid true || skip_ 'setsid required to control groups'
+
# Function to count number of lines from tail
# while ignoring transient errors due to resource limits
countlines_ ()
@@ -54,7 +56,11 @@ echo start > file2 || framework_failure_
env sleep 60 & sleep=$!
# Note don't use timeout(1) here as it currently
-# does not propagate SIGCONT
+# does not propagate SIGCONT.
+# Note use setsid here to ensure we're in a separate process group
+# as we're going to STOP this tail process, and this can trigger
+# the kernel to send SIGHUP to a group if other tests have
+# processes that are reparented. (See tests/timeout/timeout.sh).
tail $fastpoll --pid=$sleep -f file1 file2 > out & pid=$!
# Ensure tail is running
diff --git a/tests/timeout/timeout.sh b/tests/timeout/timeout.sh
index 9a395416b..fbb043312 100755
--- a/tests/timeout/timeout.sh
+++ b/tests/timeout/timeout.sh
@@ -56,9 +56,14 @@ returns_ 124 timeout --foreground -s0 -k1 .1 sleep 10 && fail=1
) || fail=1
# Don't be confused when starting off with a child (Bug#9098).
-out=$(sleep .1 & exec timeout .5 sh -c 'sleep 2; echo foo')
-status=$?
-test "$out" = "" && test $status = 124 || fail=1
+# Use setsid to avoid sleep being in the test's process group, as
+# upon reparenting it can trigger an orphaned process group SIGHUP
+# (if there were stopped processes in other tests).
+if setsid true; then
+ out=$(setsid sleep .1 & exec timeout .5 sh -c 'sleep 2; echo foo')
+ status=$?
+ test "$out" = "" && test $status = 124 || fail=1
+fi
# Verify --verbose output
cat > exp <<\EOF
--
2.53.0
`},
},
Flag: TEarly, Flag: TEarly,
}, &MakeHelper{ }, &MakeHelper{
Configure: [][2]string{ Configure: [][2]string{
@@ -281,14 +486,24 @@ test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c
Bash, Bash,
KernelHeaders, KernelHeaders,
) ), version
} }
func init() { artifactsF[Coreutils] = Toolchain.newCoreutils } func init() {
artifactsM[Coreutils] = Metadata{
f: Toolchain.newCoreutils,
func (t Toolchain) newTexinfo() pkg.Artifact { Name: "coreutils",
Description: "the basic file, shell and text manipulation utilities",
Website: "https://www.gnu.org/software/coreutils/",
ID: 343,
}
}
func (t Toolchain) newTexinfo() (pkg.Artifact, string) {
const ( const (
version = "7.2" version = "7.3"
checksum = "9EelM5b7QGMAY5DKrAm_El8lofBGuFWlaBPSBhh7l_VQE8054MBmC0KBvGrABqjv" checksum = "RRmC8Xwdof7JuZJeWGAQ_GeASIHAuJFQMbNONXBz5InooKIQGmqmWRjGNGEr5n4-"
) )
return t.NewPackage("texinfo", version, pkg.NewHTTPGetTar( return t.NewPackage("texinfo", version, pkg.NewHTTPGetTar(
nil, "https://ftpmirror.gnu.org/gnu/texinfo/texinfo-"+version+".tar.gz", nil, "https://ftpmirror.gnu.org/gnu/texinfo/texinfo-"+version+".tar.gz",
@@ -299,11 +514,21 @@ func (t Toolchain) newTexinfo() pkg.Artifact {
SkipCheck: true, SkipCheck: true,
}, },
Perl, Perl,
) ), version
} }
func init() { artifactsF[Texinfo] = Toolchain.newTexinfo } func init() {
artifactsM[Texinfo] = Metadata{
f: Toolchain.newTexinfo,
func (t Toolchain) newGperf() pkg.Artifact { Name: "texinfo",
Description: "the GNU square-wheel-reinvension of man pages",
Website: "https://www.gnu.org/software/texinfo/",
ID: 4958,
}
}
func (t Toolchain) newGperf() (pkg.Artifact, string) {
const ( const (
version = "3.3" version = "3.3"
checksum = "RtIy9pPb_Bb8-31J2Nw-rRGso2JlS-lDlVhuNYhqR7Nt4xM_nObznxAlBMnarJv7" checksum = "RtIy9pPb_Bb8-31J2Nw-rRGso2JlS-lDlVhuNYhqR7Nt4xM_nObznxAlBMnarJv7"
@@ -314,14 +539,24 @@ func (t Toolchain) newGperf() pkg.Artifact {
pkg.TarGzip, pkg.TarGzip,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
Diffutils, Diffutils,
) ), version
} }
func init() { artifactsF[Gperf] = Toolchain.newGperf } func init() {
artifactsM[Gperf] = Metadata{
f: Toolchain.newGperf,
func (t Toolchain) newGawk() pkg.Artifact { Name: "gperf",
Description: "a perfect hash function generator",
Website: "https://www.gnu.org/software/gperf/",
ID: 1237,
}
}
func (t Toolchain) newGawk() (pkg.Artifact, string) {
const ( const (
version = "5.3.2" version = "5.4.0"
checksum = "uIs0d14h_d2DgMGYwrPtegGNyt_bxzG3D6Fe-MmExx_pVoVkQaHzrtmiXVr6NHKk" checksum = "m0RkIolC-PI7EY5q8pcx5Y-0twlIW0Yp3wXXmV-QaHorSdf8BhZ7kW9F8iWomz0C"
) )
return t.NewPackage("gawk", version, pkg.NewHTTPGetTar( return t.NewPackage("gawk", version, pkg.NewHTTPGetTar(
nil, "https://ftpmirror.gnu.org/gnu/gawk/gawk-"+version+".tar.gz", nil, "https://ftpmirror.gnu.org/gnu/gawk/gawk-"+version+".tar.gz",
@@ -332,11 +567,21 @@ func (t Toolchain) newGawk() pkg.Artifact {
}, &MakeHelper{ }, &MakeHelper{
// dependency loop // dependency loop
SkipCheck: true, SkipCheck: true,
}) }), version
} }
func init() { artifactsF[Gawk] = Toolchain.newGawk } func init() {
artifactsM[Gawk] = Metadata{
f: Toolchain.newGawk,
func (t Toolchain) newGrep() pkg.Artifact { Name: "gawk",
Description: "an implementation of awk with GNU extensions",
Website: "https://www.gnu.org/software/gawk/",
ID: 868,
}
}
func (t Toolchain) newGrep() (pkg.Artifact, string) {
const ( const (
version = "3.12" version = "3.12"
checksum = "qMB4RjaPNRRYsxix6YOrjE8gyAT1zVSTy4nW4wKW9fqa0CHYAuWgPwDTirENzm_1" checksum = "qMB4RjaPNRRYsxix6YOrjE8gyAT1zVSTy4nW4wKW9fqa0CHYAuWgPwDTirENzm_1"
@@ -355,11 +600,21 @@ test_disable 'int main(){return 0;}' gnulib-tests/test-c32ispunct.c
`, `,
}, (*MakeHelper)(nil), }, (*MakeHelper)(nil),
Diffutils, Diffutils,
) ), version
} }
func init() { artifactsF[Grep] = Toolchain.newGrep } func init() {
artifactsM[Grep] = Metadata{
f: Toolchain.newGrep,
func (t Toolchain) newFindutils() pkg.Artifact { Name: "grep",
Description: "searches input for lines containing a match to a pattern",
Website: "https://www.gnu.org/software/grep/",
ID: 1251,
}
}
func (t Toolchain) newFindutils() (pkg.Artifact, string) {
const ( const (
version = "4.10.0" version = "4.10.0"
checksum = "ZXABdNBQXL7QjTygynRRTdXYWxQKZ0Wn5eMd3NUnxR0xaS0u0VfcKoTlbo50zxv6" checksum = "ZXABdNBQXL7QjTygynRRTdXYWxQKZ0Wn5eMd3NUnxR0xaS0u0VfcKoTlbo50zxv6"
@@ -377,11 +632,21 @@ echo 'int main(){return 0;}' > tests/xargs/test-sigusr.c
Diffutils, Diffutils,
XZ, XZ,
Sed, Sed,
) ), version
} }
func init() { artifactsF[Findutils] = Toolchain.newFindutils } func init() {
artifactsM[Findutils] = Metadata{
f: Toolchain.newFindutils,
func (t Toolchain) newBC() pkg.Artifact { Name: "findutils",
Description: "the basic directory searching utilities",
Website: "https://www.gnu.org/software/findutils/",
ID: 812,
}
}
func (t Toolchain) newBC() (pkg.Artifact, string) {
const ( const (
version = "1.08.2" version = "1.08.2"
checksum = "8h6f3hjV80XiFs6v9HOPF2KEyg1kuOgn5eeFdVspV05ODBVQss-ey5glc8AmneLy" checksum = "8h6f3hjV80XiFs6v9HOPF2KEyg1kuOgn5eeFdVspV05ODBVQss-ey5glc8AmneLy"
@@ -397,24 +662,44 @@ func (t Toolchain) newBC() pkg.Artifact {
}, (*MakeHelper)(nil), }, (*MakeHelper)(nil),
Perl, Perl,
Texinfo, Texinfo,
) ), version
} }
func init() { artifactsF[BC] = Toolchain.newBC } func init() {
artifactsM[BC] = Metadata{
f: Toolchain.newBC,
func (t Toolchain) newLibiconv() pkg.Artifact { Name: "bc",
Description: "an arbitrary precision numeric processing language",
Website: "https://www.gnu.org/software/bc/",
ID: 170,
}
}
func (t Toolchain) newLibiconv() (pkg.Artifact, string) {
const ( const (
version = "1.18" version = "1.19"
checksum = "iV5q3VxP5VPdJ-X7O5OQI4fGm8VjeYb5viLd1L3eAHg26bbHb2_Qn63XPF3ucVZr" checksum = "UibB6E23y4MksNqYmCCrA3zTFO6vJugD1DEDqqWYFZNuBsUWMVMcncb_5pPAr88x"
) )
return t.NewPackage("libiconv", version, pkg.NewHTTPGetTar( return t.NewPackage("libiconv", version, pkg.NewHTTPGetTar(
nil, "https://ftpmirror.gnu.org/gnu/libiconv/libiconv-"+version+".tar.gz", nil, "https://ftpmirror.gnu.org/gnu/libiconv/libiconv-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), nil, (*MakeHelper)(nil)) ), nil, (*MakeHelper)(nil)), version
} }
func init() { artifactsF[Libiconv] = Toolchain.newLibiconv } func init() {
artifactsM[Libiconv] = Metadata{
f: Toolchain.newLibiconv,
func (t Toolchain) newTar() pkg.Artifact { Name: "libiconv",
Description: "iconv implementation independent of glibc",
Website: "https://www.gnu.org/software/libiconv/",
ID: 10656,
}
}
func (t Toolchain) newTar() (pkg.Artifact, string) {
const ( const (
version = "1.35" version = "1.35"
checksum = "zSaoSlVUDW0dSfm4sbL4FrXLFR8U40Fh3zY5DWhR5NCIJ6GjU6Kc4VZo2-ZqpBRA" checksum = "zSaoSlVUDW0dSfm4sbL4FrXLFR8U40Fh3zY5DWhR5NCIJ6GjU6Kc4VZo2-ZqpBRA"
@@ -442,14 +727,49 @@ func (t Toolchain) newTar() pkg.Artifact {
Gzip, Gzip,
Bzip2, Bzip2,
Zstd, Zstd,
) ), version
} }
func init() { artifactsF[Tar] = Toolchain.newTar } func init() {
artifactsM[Tar] = Metadata{
f: Toolchain.newTar,
func (t Toolchain) newBinutils() pkg.Artifact { Name: "tar",
Description: "provides the ability to create tar archives",
Website: "https://www.gnu.org/software/tar/",
ID: 4939,
}
}
func (t Toolchain) newParallel() (pkg.Artifact, string) {
const ( const (
version = "2.45" version = "20260222"
checksum = "hlLtqqHDmzAT2OQVHaKEd_io2DGFvJkaeS-igBuK8bRRir7LUKGHgHYNkDVKaHTT" checksum = "4wxjMi3G2zMxr9hvLcIn6D7_12A3e5UNObeTPhzn7mDAYwsZApmmkxfGPyllQQ7E"
)
return t.NewPackage("parallel", version, pkg.NewHTTPGetTar(
nil, "https://ftpmirror.gnu.org/gnu/parallel/parallel-"+version+".tar.bz2",
mustDecode(checksum),
pkg.TarBzip2,
), nil, (*MakeHelper)(nil),
Perl,
), version
}
func init() {
artifactsM[Parallel] = Metadata{
f: Toolchain.newParallel,
Name: "parallel",
Description: "a shell tool for executing jobs in parallel using one or more computers",
Website: "https://www.gnu.org/software/parallel/",
ID: 5448,
}
}
func (t Toolchain) newBinutils() (pkg.Artifact, string) {
const (
version = "2.46.0"
checksum = "4kK1_EXQipxSqqyvwD4LbiMLFKCUApjq6PeG4XJP4dzxYGqDeqXfh8zLuTyOuOVR"
) )
return t.NewPackage("binutils", version, pkg.NewHTTPGetTar( return t.NewPackage("binutils", version, pkg.NewHTTPGetTar(
nil, "https://ftpmirror.gnu.org/gnu/binutils/binutils-"+version+".tar.bz2", nil, "https://ftpmirror.gnu.org/gnu/binutils/binutils-"+version+".tar.bz2",
@@ -457,11 +777,21 @@ func (t Toolchain) newBinutils() pkg.Artifact {
pkg.TarBzip2, pkg.TarBzip2,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
Bash, Bash,
) ), version
} }
func init() { artifactsF[Binutils] = Toolchain.newBinutils } func init() {
artifactsM[Binutils] = Metadata{
f: Toolchain.newBinutils,
func (t Toolchain) newGMP() pkg.Artifact { Name: "binutils",
Description: "a collection of binary tools",
Website: "https://www.gnu.org/software/binutils/",
ID: 7981,
}
}
func (t Toolchain) newGMP() (pkg.Artifact, string) {
const ( const (
version = "6.3.0" version = "6.3.0"
checksum = "yrgbgEDWKDdMWVHh7gPbVl56-sRtVVhfvv0M_LX7xMUUk_mvZ1QOJEAnt7g4i3k5" checksum = "yrgbgEDWKDdMWVHh7gPbVl56-sRtVVhfvv0M_LX7xMUUk_mvZ1QOJEAnt7g4i3k5"
@@ -473,11 +803,21 @@ func (t Toolchain) newGMP() pkg.Artifact {
pkg.TarBzip2, pkg.TarBzip2,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
M4, M4,
) ), version
} }
func init() { artifactsF[GMP] = Toolchain.newGMP } func init() {
artifactsM[GMP] = Metadata{
f: Toolchain.newGMP,
func (t Toolchain) newMPFR() pkg.Artifact { Name: "gmp",
Description: "a free library for arbitrary precision arithmetic",
Website: "https://gmplib.org/",
ID: 1186,
}
}
func (t Toolchain) newMPFR() (pkg.Artifact, string) {
const ( const (
version = "4.2.2" version = "4.2.2"
checksum = "wN3gx0zfIuCn9r3VAn_9bmfvAYILwrRfgBjYSD1IjLqyLrLojNN5vKyQuTE9kA-B" checksum = "wN3gx0zfIuCn9r3VAn_9bmfvAYILwrRfgBjYSD1IjLqyLrLojNN5vKyQuTE9kA-B"
@@ -489,11 +829,21 @@ func (t Toolchain) newMPFR() pkg.Artifact {
pkg.TarBzip2, pkg.TarBzip2,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
GMP, GMP,
) ), version
} }
func init() { artifactsF[MPFR] = Toolchain.newMPFR } func init() {
artifactsM[MPFR] = Metadata{
f: Toolchain.newMPFR,
func (t Toolchain) newMPC() pkg.Artifact { Name: "mpfr",
Description: "a C library for multiple-precision floating-point computations",
Website: "https://www.mpfr.org/",
ID: 2019,
}
}
func (t Toolchain) newMPC() (pkg.Artifact, string) {
const ( const (
version = "1.3.1" version = "1.3.1"
checksum = "o8r8K9R4x7PuRx0-JE3-bC5jZQrtxGV2nkB773aqJ3uaxOiBDCID1gKjPaaDxX4V" checksum = "o8r8K9R4x7PuRx0-JE3-bC5jZQrtxGV2nkB773aqJ3uaxOiBDCID1gKjPaaDxX4V"
@@ -506,11 +856,21 @@ func (t Toolchain) newMPC() pkg.Artifact {
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
GMP, GMP,
MPFR, MPFR,
) ), version
} }
func init() { artifactsF[MPC] = Toolchain.newMPC } func init() {
artifactsM[MPC] = Metadata{
f: Toolchain.newMPC,
func (t Toolchain) newGCC() pkg.Artifact { Name: "mpc",
Description: "a C library for the arithmetic of complex numbers",
Website: "https://www.multiprecision.org/",
ID: 1667,
}
}
func (t Toolchain) newGCC() (pkg.Artifact, string) {
const ( const (
version = "15.2.0" version = "15.2.0"
checksum = "TXJ5WrbXlGLzy1swghQTr4qxgDCyIZFgJry51XEPTBZ8QYbVmFeB4lZbSMtPJ-a1" checksum = "TXJ5WrbXlGLzy1swghQTr4qxgDCyIZFgJry51XEPTBZ8QYbVmFeB4lZbSMtPJ-a1"
@@ -710,6 +1070,16 @@ ln -s system/lib /work/
Zlib, Zlib,
Libucontext, Libucontext,
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[gcc] = Metadata{
f: Toolchain.newGCC,
Name: "gcc",
Description: "The GNU Compiler Collection",
Website: "https://www.gnu.org/software/gcc/",
ID: 6502,
}
} }
func init() { artifactsF[gcc] = Toolchain.newGCC }

View File

@@ -62,7 +62,7 @@ ln -s \
))) )))
} }
func (t Toolchain) newGoLatest() pkg.Artifact { func (t Toolchain) newGoLatest() (pkg.Artifact, string) {
var ( var (
bootstrapEnv []string bootstrapEnv []string
bootstrapExtra []pkg.Artifact bootstrapExtra []pkg.Artifact
@@ -153,9 +153,13 @@ rm \
`, go123, `, go123,
) )
const (
version = "1.26.1"
checksum = "DdC5Ea-aCYPUHNObQh_09uWU0vn4e-8Ben850Vq-5OoamDRrXhuYI4YQ_BOFgaT0"
)
return t.newGo( return t.newGo(
"1.26.0", version,
"uHLcrgBc0NMcyTMDLRNAZIcOx0RyQlyekSl9xbWSwj3esEFWJysYLfLa3S8p39Nh", checksum,
finalEnv, ` finalEnv, `
sed -i \ sed -i \
's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \ 's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \
@@ -164,6 +168,16 @@ sed -i \
rm \ rm \
os/root_unix_test.go os/root_unix_test.go
`, go125, `, go125,
) ), version
}
func init() {
artifactsM[Go] = Metadata{
f: Toolchain.newGoLatest,
Name: "go",
Description: "the Go programming language toolchain",
Website: "https://go.dev/",
ID: 1227,
}
} }
func init() { artifactsF[Go] = Toolchain.newGoLatest }

View File

@@ -7,10 +7,10 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newGLib() pkg.Artifact { func (t Toolchain) newGLib() (pkg.Artifact, string) {
const ( const (
version = "2.86.4" version = "2.87.3"
checksum = "AfTjBrrxtXXPL6dFa1LfTe40PyPSth62CoIkM5m_VJTUngGLOFHw6I4XE7RGQE8G" checksum = "iKSLpzZZVfmAZZmqfO1y6uHdlIks4hzPWrqeUCp4ZeQjrPFA3aAa4OmrBYMNS-Si"
) )
return t.NewPackage("glib", version, pkg.NewHTTPGet( return t.NewPackage("glib", version, pkg.NewHTTPGet(
nil, "https://download.gnome.org/sources/glib/"+ nil, "https://download.gnome.org/sources/glib/"+
@@ -40,12 +40,22 @@ func (t Toolchain) newGLib() pkg.Artifact {
}, },
}, },
XZ, XZ,
Packaging, PythonPackaging,
Bash, Bash,
PCRE2, PCRE2,
Libffi, Libffi,
Zlib, Zlib,
) ), version
}
func init() {
artifactsM[GLib] = Metadata{
f: Toolchain.newGLib,
Name: "glib",
Description: "the GNU library of miscellaneous stuff",
Website: "https://developer.gnome.org/glib/",
ID: 10024,
}
} }
func init() { artifactsF[GLib] = Toolchain.newGLib }

View File

@@ -2,7 +2,19 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newHakurei(suffix, script string) pkg.Artifact { func (t Toolchain) newHakurei(
suffix, script string,
withHostname bool,
) pkg.Artifact {
hostname := `
echo '# Building test helper (hostname).'
go build -v -o /bin/hostname /usr/src/hostname/main.go
echo
`
if !withHostname {
hostname = ""
}
return t.New("hakurei"+suffix+"-"+hakureiVersion, 0, []pkg.Artifact{ return t.New("hakurei"+suffix+"-"+hakureiVersion, 0, []pkg.Artifact{
t.Load(Go), t.Load(Go),
@@ -29,17 +41,12 @@ func (t Toolchain) newHakurei(suffix, script string) pkg.Artifact {
"CGO_ENABLED=1", "CGO_ENABLED=1",
"GOCACHE=/tmp/gocache", "GOCACHE=/tmp/gocache",
"CC=clang -O3 -Werror", "CC=clang -O3 -Werror",
}, ` }, hostname+`
echo '# Building test helper (hostname).'
go build -v -o /bin/hostname /usr/src/hostname/main.go
echo
chmod -R +w /usr/src/hakurei
cd /usr/src/hakurei cd /usr/src/hakurei
HAKUREI_VERSION='v`+hakureiVersion+`' HAKUREI_VERSION='v`+hakureiVersion+`'
`+script, pkg.Path(AbsUsrSrc.Append("hakurei"), true, t.NewPatchedSource( `+script, pkg.Path(AbsUsrSrc.Append("hakurei"), true, t.NewPatchedSource(
"hakurei", hakureiVersion, hakureiSource, true, hakureiPatches..., "hakurei", hakureiVersion, hakureiSource, false, hakureiPatches...,
)), pkg.Path(AbsUsrSrc.Append("hostname", "main.go"), false, pkg.NewFile( )), pkg.Path(AbsUsrSrc.Append("hostname", "main.go"), false, pkg.NewFile(
"hostname.go", "hostname.go",
[]byte(` []byte(`
@@ -58,8 +65,9 @@ func main() {
))) )))
} }
func init() { func init() {
artifactsF[Hakurei] = func(t Toolchain) pkg.Artifact { artifactsM[Hakurei] = Metadata{
return t.newHakurei("", ` f: func(t Toolchain) (pkg.Artifact, string) {
return t.newHakurei("", `
mkdir -p /work/system/libexec/hakurei/ mkdir -p /work/system/libexec/hakurei/
echo '# Building hakurei.' echo '# Building hakurei.'
@@ -68,10 +76,11 @@ go build -trimpath -v -o /work/system/libexec/hakurei -ldflags="-s -w
-buildid= -buildid=
-linkmode external -linkmode external
-extldflags=-static -extldflags=-static
-X hakurei.app/internal/info.buildVersion="$HAKUREI_VERSION" -X hakurei.app/internal/info.buildVersion=${HAKUREI_VERSION}
-X hakurei.app/internal/info.hakureiPath=/system/bin/hakurei -X hakurei.app/internal/info.hakureiPath=/system/bin/hakurei
-X hakurei.app/internal/info.hsuPath=/system/bin/hsu -X hakurei.app/internal/info.hsuPath=/system/bin/hsu
-X main.hakureiPath=/system/bin/hakurei" ./... -X main.hakureiPath=/system/bin/hakurei
" ./...
echo echo
echo '# Testing hakurei.' echo '# Testing hakurei.'
@@ -83,12 +92,25 @@ mkdir -p /work/system/bin/
hakurei \ hakurei \
sharefs \ sharefs \
../../bin/) ../../bin/)
`) `, true), hakureiVersion
},
Name: "hakurei",
Description: "low-level userspace tooling for Rosa OS",
Website: "https://hakurei.app/",
ID: 388834,
} }
artifactsF[HakureiDist] = func(t Toolchain) pkg.Artifact { artifactsM[HakureiDist] = Metadata{
return t.newHakurei("-dist", ` f: func(t Toolchain) (pkg.Artifact, string) {
return t.newHakurei("-dist", `
export HAKUREI_VERSION export HAKUREI_VERSION
DESTDIR=/work /usr/src/hakurei/dist/release.sh DESTDIR=/work /usr/src/hakurei/dist/release.sh
`) `, true), hakureiVersion
},
Name: "hakurei-dist",
Description: "low-level userspace tooling for Rosa OS (distribution tarball)",
Website: "https://hakurei.app/",
} }
} }

View File

@@ -4,48 +4,15 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
const hakureiVersion = "0.3.5" const hakureiVersion = "0.3.6"
// hakureiSource is the source code of a hakurei release. // hakureiSource is the source code of a hakurei release.
var hakureiSource = pkg.NewHTTPGetTar( var hakureiSource = pkg.NewHTTPGetTar(
nil, "https://git.gensokyo.uk/security/hakurei/archive/"+ nil, "https://git.gensokyo.uk/security/hakurei/archive/"+
"v"+hakureiVersion+".tar.gz", "v"+hakureiVersion+".tar.gz",
mustDecode("6Tn38NLezRD2d3aGdFg5qFfqn8_KvC6HwMKwJMPvaHmVw8xRgxn8B0PObswl2mOk"), mustDecode("Yul9J2yV0x453lQP9KUnG_wEJo_DbKMNM7xHJGt4rITCSeX9VRK2J4kzAxcv_0-b"),
pkg.TarGzip, pkg.TarGzip,
) )
// hakureiPatches are patches applied against a hakurei release. // hakureiPatches are patches applied against a hakurei release.
var hakureiPatches = [][2]string{ var hakureiPatches [][2]string
{"createTemp-error-injection", `diff --git a/container/dispatcher_test.go b/container/dispatcher_test.go
index 5de37fc..fe0c4db 100644
--- a/container/dispatcher_test.go
+++ b/container/dispatcher_test.go
@@ -238,8 +238,11 @@ func sliceAddr[S any](s []S) *[]S { return &s }
func newCheckedFile(t *testing.T, name, wantData string, closeErr error) osFile {
f := &checkedOsFile{t: t, name: name, want: wantData, closeErr: closeErr}
- // check happens in Close, and cleanup is not guaranteed to run, so relying on it for sloppy implementations will cause sporadic test results
- f.cleanup = runtime.AddCleanup(f, func(name string) { f.t.Fatalf("checkedOsFile %s became unreachable without a call to Close", name) }, f.name)
+ // check happens in Close, and cleanup is not guaranteed to run, so relying
+ // on it for sloppy implementations will cause sporadic test results
+ f.cleanup = runtime.AddCleanup(f, func(name string) {
+ panic("checkedOsFile " + name + " became unreachable without a call to Close")
+ }, name)
return f
}
diff --git a/container/initplace_test.go b/container/initplace_test.go
index afeddbe..1c2f20b 100644
--- a/container/initplace_test.go
+++ b/container/initplace_test.go
@@ -21,7 +21,7 @@ func TestTmpfileOp(t *testing.T) {
Path: samplePath,
Data: sampleData,
}, nil, nil, []stub.Call{
- call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), stub.UniqueError(5)),
+ call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, (*checkedOsFile)(nil), stub.UniqueError(5)),
}, stub.UniqueError(5)},
{"Write", &Params{ParentPerm: 0700}, &TmpfileOp{
`},
}

View File

@@ -2,10 +2,32 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newImageInitramfs() pkg.Artifact { func init() {
artifactsM[EarlyInit] = Metadata{
Name: "earlyinit",
Description: "Rosa OS initramfs init program",
f: func(t Toolchain) (pkg.Artifact, string) {
return t.newHakurei("-early-init", `
mkdir -p /work/system/libexec/hakurei/
echo '# Building earlyinit.'
go build -trimpath -v -o /work/system/libexec/hakurei -ldflags="-s -w
-buildid=
-linkmode external
-extldflags=-static
-X hakurei.app/internal/info.buildVersion=${HAKUREI_VERSION}
" ./cmd/earlyinit
echo
`, false), Unversioned
},
}
}
func (t Toolchain) newImageInitramfs() (pkg.Artifact, string) {
return t.New("initramfs", TNoToolchain, []pkg.Artifact{ return t.New("initramfs", TNoToolchain, []pkg.Artifact{
t.Load(Zstd), t.Load(Zstd),
t.Load(Hakurei), t.Load(EarlyInit),
t.Load(GenInitCPIO), t.Load(GenInitCPIO),
}, nil, nil, ` }, nil, nil, `
gen_init_cpio -t 4294967295 -c /usr/src/initramfs | zstd > /work/initramfs.zst gen_init_cpio -t 4294967295 -c /usr/src/initramfs | zstd > /work/initramfs.zst
@@ -14,6 +36,13 @@ dir /dev 0755 0 0
nod /dev/null 0666 0 0 c 1 3 nod /dev/null 0666 0 0 c 1 3
nod /dev/console 0600 0 0 c 5 1 nod /dev/console 0600 0 0 c 5 1
file /init /system/libexec/hakurei/earlyinit 0555 0 0 file /init /system/libexec/hakurei/earlyinit 0555 0 0
`)))) `)))), Unversioned
}
func init() {
artifactsM[ImageInitramfs] = Metadata{
Name: "initramfs-image",
Description: "Rosa OS initramfs image",
f: Toolchain.newImageInitramfs,
}
} }
func init() { artifactsF[ImageInitramfs] = Toolchain.newImageInitramfs }

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,16 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/x86 6.12.73 Kernel Configuration # Linux/x86 6.12.76 Kernel Configuration
# #
CONFIG_CC_VERSION_TEXT="clang version 21.1.8" CONFIG_CC_VERSION_TEXT="clang version 22.1.0"
CONFIG_GCC_VERSION=0 CONFIG_GCC_VERSION=0
CONFIG_CC_IS_CLANG=y CONFIG_CC_IS_CLANG=y
CONFIG_CLANG_VERSION=210108 CONFIG_CLANG_VERSION=220100
CONFIG_AS_IS_LLVM=y CONFIG_AS_IS_LLVM=y
CONFIG_AS_VERSION=210108 CONFIG_AS_VERSION=220100
CONFIG_LD_VERSION=0 CONFIG_LD_VERSION=0
CONFIG_LD_IS_LLD=y CONFIG_LD_IS_LLD=y
CONFIG_LLD_VERSION=210108 CONFIG_LLD_VERSION=220100
CONFIG_RUSTC_VERSION=0 CONFIG_RUSTC_VERSION=0
CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_RUSTC_LLVM_VERSION=0
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
@@ -12308,7 +12308,6 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y
# CONFIG_NMI_CHECK_CPU is not set # CONFIG_NMI_CHECK_CPU is not set
# CONFIG_DEBUG_IRQFLAGS is not set # CONFIG_DEBUG_IRQFLAGS is not set
CONFIG_STACKTRACE=y CONFIG_STACKTRACE=y
# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
# CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_KOBJECT is not set
# #
@@ -12345,7 +12344,7 @@ CONFIG_HAVE_RETHOOK=y
CONFIG_RETHOOK=y CONFIG_RETHOOK=y
CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_RETVAL=y CONFIG_HAVE_FUNCTION_GRAPH_FREGS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y

View File

@@ -1,16 +1,16 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/arm64 6.12.73 Kernel Configuration # Linux/arm64 6.12.76 Kernel Configuration
# #
CONFIG_CC_VERSION_TEXT="clang version 21.1.8" CONFIG_CC_VERSION_TEXT="clang version 22.1.0"
CONFIG_GCC_VERSION=0 CONFIG_GCC_VERSION=0
CONFIG_CC_IS_CLANG=y CONFIG_CC_IS_CLANG=y
CONFIG_CLANG_VERSION=210108 CONFIG_CLANG_VERSION=220100
CONFIG_AS_IS_LLVM=y CONFIG_AS_IS_LLVM=y
CONFIG_AS_VERSION=210108 CONFIG_AS_VERSION=220100
CONFIG_LD_VERSION=0 CONFIG_LD_VERSION=0
CONFIG_LD_IS_LLD=y CONFIG_LD_IS_LLD=y
CONFIG_LLD_VERSION=210108 CONFIG_LLD_VERSION=220100
CONFIG_RUSTC_VERSION=0 CONFIG_RUSTC_VERSION=0
CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_RUSTC_LLVM_VERSION=0
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
@@ -4984,7 +4984,7 @@ CONFIG_SERIAL_TEGRA_TCU=m
CONFIG_SERIAL_MAX3100=m CONFIG_SERIAL_MAX3100=m
CONFIG_SERIAL_MAX310X=m CONFIG_SERIAL_MAX310X=m
CONFIG_SERIAL_IMX=m CONFIG_SERIAL_IMX=m
CONFIG_SERIAL_IMX_CONSOLE=m # CONFIG_SERIAL_IMX_CONSOLE is not set
CONFIG_SERIAL_IMX_EARLYCON=y CONFIG_SERIAL_IMX_EARLYCON=y
CONFIG_SERIAL_UARTLITE=m CONFIG_SERIAL_UARTLITE=m
CONFIG_SERIAL_UARTLITE_NR_UARTS=1 CONFIG_SERIAL_UARTLITE_NR_UARTS=1
@@ -5772,6 +5772,7 @@ CONFIG_GPIO_MADERA=m
CONFIG_GPIO_MAX77650=m CONFIG_GPIO_MAX77650=m
CONFIG_GPIO_PMIC_EIC_SPRD=m CONFIG_GPIO_PMIC_EIC_SPRD=m
CONFIG_GPIO_SL28CPLD=m CONFIG_GPIO_SL28CPLD=m
CONFIG_GPIO_TN48M_CPLD=m
CONFIG_GPIO_TPS65086=m CONFIG_GPIO_TPS65086=m
CONFIG_GPIO_TPS65218=m CONFIG_GPIO_TPS65218=m
CONFIG_GPIO_TPS65219=m CONFIG_GPIO_TPS65219=m
@@ -6471,6 +6472,7 @@ CONFIG_MFD_MAX5970=m
# CONFIG_MFD_CS47L85 is not set # CONFIG_MFD_CS47L85 is not set
# CONFIG_MFD_CS47L90 is not set # CONFIG_MFD_CS47L90 is not set
# CONFIG_MFD_CS47L92 is not set # CONFIG_MFD_CS47L92 is not set
CONFIG_MFD_TN48M_CPLD=m
# CONFIG_MFD_DA9052_SPI is not set # CONFIG_MFD_DA9052_SPI is not set
CONFIG_MFD_DA9062=m CONFIG_MFD_DA9062=m
CONFIG_MFD_DA9063=m CONFIG_MFD_DA9063=m
@@ -12532,6 +12534,7 @@ CONFIG_RESET_SUNXI=y
CONFIG_RESET_TI_SCI=m CONFIG_RESET_TI_SCI=m
CONFIG_RESET_TI_SYSCON=m CONFIG_RESET_TI_SYSCON=m
CONFIG_RESET_TI_TPS380X=m CONFIG_RESET_TI_TPS380X=m
CONFIG_RESET_TN48M_CPLD=m
CONFIG_RESET_UNIPHIER=m CONFIG_RESET_UNIPHIER=m
CONFIG_RESET_UNIPHIER_GLUE=m CONFIG_RESET_UNIPHIER_GLUE=m
CONFIG_RESET_ZYNQMP=y CONFIG_RESET_ZYNQMP=y
@@ -14022,7 +14025,6 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y
# CONFIG_DEBUG_IRQFLAGS is not set # CONFIG_DEBUG_IRQFLAGS is not set
CONFIG_STACKTRACE=y CONFIG_STACKTRACE=y
# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
# CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_KOBJECT is not set
# #
@@ -14057,7 +14059,7 @@ CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_NOP_TRACER=y CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_RETVAL=y CONFIG_HAVE_FUNCTION_GRAPH_FREGS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newKmod() pkg.Artifact { func (t Toolchain) newKmod() (pkg.Artifact, string) {
const ( const (
version = "34.2" version = "34.2"
checksum = "0K7POeTKxMhExsaTsnKAC6LUNsRSfe6sSZxWONPbOu-GI_pXOw3toU_BIoqfBhJV" checksum = "0K7POeTKxMhExsaTsnKAC6LUNsRSfe6sSZxWONPbOu-GI_pXOw3toU_BIoqfBhJV"
@@ -28,6 +28,16 @@ func (t Toolchain) newKmod() pkg.Artifact {
Zstd, Zstd,
OpenSSL, OpenSSL,
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[Kmod] = Metadata{
f: Toolchain.newKmod,
Name: "kmod",
Description: "a set of tools to handle common tasks with Linux kernel modules",
Website: "https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git",
ID: 1517,
}
} }
func init() { artifactsF[Kmod] = Toolchain.newKmod }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newLibcap() pkg.Artifact { func (t Toolchain) newLibcap() (pkg.Artifact, string) {
const ( const (
version = "2.77" version = "2.77"
checksum = "2GOTFU4cl2QoS7Dv5wh0c9-hxsQwIzMB9Y_gfAo5xKHqcM13fiHt1RbPkfemzjmB" checksum = "2GOTFU4cl2QoS7Dv5wh0c9-hxsQwIzMB9Y_gfAo5xKHqcM13fiHt1RbPkfemzjmB"
@@ -39,6 +39,16 @@ ln -s ../system/bin/bash /bin/
}, },
Bash, Bash,
Diffutils, Diffutils,
) ), version
}
func init() {
artifactsM[Libcap] = Metadata{
f: Toolchain.newLibcap,
Name: "libcap",
Description: "a library for getting and setting POSIX.1e draft 15 capabilities",
Website: "https://sites.google.com/site/fullycapable/",
ID: 1569,
}
} }
func init() { artifactsF[Libcap] = Toolchain.newLibcap }

View File

@@ -6,10 +6,10 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newLibexpat() pkg.Artifact { func (t Toolchain) newLibexpat() (pkg.Artifact, string) {
const ( const (
version = "2.7.3" version = "2.7.4"
checksum = "GmkoD23nRi9cMT0cgG1XRMrZWD82UcOMzkkvP1gkwSFWCBgeSXMuoLpa8-v8kxW-" checksum = "W6NI2FESBjrTqRPcvs15fK5c3nwF6f9RT8U-XHKQKblXVzJB3nt_ez5B5jO0ZVDG"
) )
return t.NewPackage("libexpat", version, pkg.NewHTTPGetTar( return t.NewPackage("libexpat", version, pkg.NewHTTPGetTar(
nil, "https://github.com/libexpat/libexpat/releases/download/"+ nil, "https://github.com/libexpat/libexpat/releases/download/"+
@@ -19,6 +19,16 @@ func (t Toolchain) newLibexpat() pkg.Artifact {
pkg.TarBzip2, pkg.TarBzip2,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
Bash, Bash,
) ), version
}
func init() {
artifactsM[Libexpat] = Metadata{
f: Toolchain.newLibexpat,
Name: "libexpat",
Description: "a stream-oriented XML parser library",
Website: "https://libexpat.github.io/",
ID: 770,
}
} }
func init() { artifactsF[Libexpat] = Toolchain.newLibexpat }

View File

@@ -2,10 +2,10 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newLibffi() pkg.Artifact { func (t Toolchain) newLibffi() (pkg.Artifact, string) {
const ( const (
version = "3.4.5" version = "3.5.2"
checksum = "apIJzypF4rDudeRoI_n3K7N-zCeBLTbQlHRn9NSAZqdLAWA80mR0gXPTpHsL7oMl" checksum = "2_Q-ZNBBbVhltfL5zEr0wljxPegUimTK4VeMSiwJEGksls3n4gj3lV0Ly3vviSFH"
) )
return t.NewPackage("libffi", version, pkg.NewHTTPGetTar( return t.NewPackage("libffi", version, pkg.NewHTTPGetTar(
nil, "https://github.com/libffi/libffi/releases/download/"+ nil, "https://github.com/libffi/libffi/releases/download/"+
@@ -14,6 +14,16 @@ func (t Toolchain) newLibffi() pkg.Artifact {
pkg.TarGzip, pkg.TarGzip,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[Libffi] = Metadata{
f: Toolchain.newLibffi,
Name: "libffi",
Description: "a portable, high level programming interface to various calling conventions",
Website: "https://sourceware.org/libffi/",
ID: 1611,
}
} }
func init() { artifactsF[Libffi] = Toolchain.newLibffi }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newLibgd() pkg.Artifact { func (t Toolchain) newLibgd() (pkg.Artifact, string) {
const ( const (
version = "2.3.3" version = "2.3.3"
checksum = "8T-sh1_FJT9K9aajgxzh8ot6vWIF-xxjcKAHvTak9MgGUcsFfzP8cAvvv44u2r36" checksum = "8T-sh1_FJT9K9aajgxzh8ot6vWIF-xxjcKAHvTak9MgGUcsFfzP8cAvvv44u2r36"
@@ -21,6 +21,16 @@ mkdir /dev/shm/gd
`, `,
}, (*MakeHelper)(nil), }, (*MakeHelper)(nil),
Zlib, Zlib,
) ), version
}
func init() {
artifactsM[Libgd] = Metadata{
f: Toolchain.newLibgd,
Name: "libgd",
Description: "an open source code library for the dynamic creation of images",
Website: "https://libgd.github.io/",
ID: 880,
}
} }
func init() { artifactsF[Libgd] = Toolchain.newLibgd }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newLibpsl() pkg.Artifact { func (t Toolchain) newLibpsl() (pkg.Artifact, string) {
const ( const (
version = "0.21.5" version = "0.21.5"
checksum = "XjfxSzh7peG2Vg4vJlL8z4JZJLcXqbuP6pLWkrGCmRxlnYUFTKNBqWGHCxEOlCad" checksum = "XjfxSzh7peG2Vg4vJlL8z4JZJLcXqbuP6pLWkrGCmRxlnYUFTKNBqWGHCxEOlCad"
@@ -21,6 +21,16 @@ test_disable 'int main(){return 0;}' tests/test-is-public-builtin.c
`, `,
}, (*MakeHelper)(nil), }, (*MakeHelper)(nil),
Python, Python,
) ), version
}
func init() {
artifactsM[Libpsl] = Metadata{
f: Toolchain.newLibpsl,
Name: "libpsl",
Description: "provides functions to work with the Mozilla Public Suffix List",
Website: "https://rockdaboot.github.io/libpsl/",
ID: 7305,
}
} }
func init() { artifactsF[Libpsl] = Toolchain.newLibpsl }

View File

@@ -1,10 +1,8 @@
package rosa package rosa
import ( import "hakurei.app/internal/pkg"
"hakurei.app/internal/pkg"
)
func (t Toolchain) newLibseccomp() pkg.Artifact { func (t Toolchain) newLibseccomp() (pkg.Artifact, string) {
const ( const (
version = "2.6.0" version = "2.6.0"
checksum = "mMu-iR71guPjFbb31u-YexBaanKE_nYPjPux-vuBiPfS_0kbwJdfCGlkofaUm-EY" checksum = "mMu-iR71guPjFbb31u-YexBaanKE_nYPjPux-vuBiPfS_0kbwJdfCGlkofaUm-EY"
@@ -24,6 +22,16 @@ ln -s ../system/bin/bash /bin/
Gperf, Gperf,
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[Libseccomp] = Metadata{
f: Toolchain.newLibseccomp,
Name: "libseccomp",
Description: "an interface to the Linux Kernel's syscall filtering mechanism",
Website: "https://github.com/seccomp/libseccomp/",
ID: 13823,
}
} }
func init() { artifactsF[Libseccomp] = Toolchain.newLibseccomp }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newLibucontext() pkg.Artifact { func (t Toolchain) newLibucontext() (pkg.Artifact, string) {
const ( const (
version = "1.5" version = "1.5"
checksum = "Ggk7FMmDNBdCx1Z9PcNWWW6LSpjGYssn2vU0GK5BLXJYw7ZxZbA2m_eSgT9TFnIG" checksum = "Ggk7FMmDNBdCx1Z9PcNWWW6LSpjGYssn2vU0GK5BLXJYw7ZxZbA2m_eSgT9TFnIG"
@@ -25,6 +25,16 @@ func (t Toolchain) newLibucontext() pkg.Artifact {
"ARCH=" + linuxArch(), "ARCH=" + linuxArch(),
}, },
Install: "make prefix=/system DESTDIR=/work install", Install: "make prefix=/system DESTDIR=/work install",
}) }), version
}
func init() {
artifactsM[Libucontext] = Metadata{
f: Toolchain.newLibucontext,
Name: "libucontext",
Description: "ucontext implementation featuring glibc-compatible ABI",
Website: "https://github.com/kaniini/libucontext/",
ID: 17085,
}
} }
func init() { artifactsF[Libucontext] = Toolchain.newLibucontext }

View File

@@ -6,10 +6,10 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newLibxml2() pkg.Artifact { func (t Toolchain) newLibxml2() (pkg.Artifact, string) {
const ( const (
version = "2.15.1" version = "2.15.2"
checksum = "pYzAR3cNrEHezhEMirgiq7jbboLzwMj5GD7SQp0jhSIMdgoU4G9oU9Gxun3zzUIU" checksum = "xba8VCofMsbWmQypA2__M9_RXNq9HDEuccjib6-tOni6OPngplRoAsYdY3NdYf8o"
) )
return t.NewPackage("libxml2", version, pkg.NewHTTPGet( return t.NewPackage("libxml2", version, pkg.NewHTTPGet(
nil, "https://download.gnome.org/sources/libxml2/"+ nil, "https://download.gnome.org/sources/libxml2/"+
@@ -21,6 +21,16 @@ func (t Toolchain) newLibxml2() pkg.Artifact {
}, (*MakeHelper)(nil), }, (*MakeHelper)(nil),
Diffutils, Diffutils,
XZ, XZ,
) ), version
}
func init() {
artifactsM[Libxml2] = Metadata{
f: Toolchain.newLibxml2,
Name: "libxml2",
Description: "an XML toolkit implemented in C",
Website: "https://gitlab.gnome.org/GNOME/libxml2/",
ID: 1783,
}
} }
func init() { artifactsF[Libxml2] = Toolchain.newLibxml2 }

View File

@@ -6,7 +6,7 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newLibxslt() pkg.Artifact { func (t Toolchain) newLibxslt() (pkg.Artifact, string) {
const ( const (
version = "1.1.45" version = "1.1.45"
checksum = "vw72UbREQnA3YDYuZ9-93hDr9BYCaKV6oh_U4Kt4n1Js_na4E-nFj-ksZnZ0kvEK" checksum = "vw72UbREQnA3YDYuZ9-93hDr9BYCaKV6oh_U4Kt4n1Js_na4E-nFj-ksZnZ0kvEK"
@@ -23,10 +23,21 @@ func (t Toolchain) newLibxslt() pkg.Artifact {
SkipCheck: true, SkipCheck: true,
}, },
XZ, XZ,
Zlib,
Python, Python,
PkgConfig, PkgConfig,
Libxml2, Libxml2,
) ), version
}
func init() {
artifactsM[Libxslt] = Metadata{
f: Toolchain.newLibxslt,
Name: "libxslt",
Description: "an XSLT processor based on libxml2",
Website: "https://gitlab.gnome.org/GNOME/libxslt/",
ID: 13301,
}
} }
func init() { artifactsF[Libxslt] = Toolchain.newLibxslt }

View File

@@ -73,12 +73,15 @@ func llvmFlagName(flag int) string {
} }
} }
const (
llvmVersionMajor = "22"
llvmVersion = llvmVersionMajor + ".1.0"
)
// newLLVMVariant returns a [pkg.Artifact] containing a LLVM variant. // newLLVMVariant returns a [pkg.Artifact] containing a LLVM variant.
func (t Toolchain) newLLVMVariant(variant string, attr *llvmAttr) pkg.Artifact { func (t Toolchain) newLLVMVariant(variant string, attr *llvmAttr) pkg.Artifact {
const ( const checksum = "-_Tu5Lt8xkWoxm2VDVV7crh0WqZQbbblN3fYamMdPTDSy_54FAkD2ii7afSymPVV"
version = "21.1.8"
checksum = "8SUpqDkcgwOPsqHVtmf9kXfFeVmjVxl4LMn-qSE1AI_Xoeju-9HaoPNGtidyxyka"
)
if attr == nil { if attr == nil {
panic("LLVM attr must be non-nil") panic("LLVM attr must be non-nil")
} }
@@ -161,9 +164,9 @@ ln -s ld.lld /work/system/bin/ld
) )
} }
return t.NewPackage("llvm", version, pkg.NewHTTPGetTar( return t.NewPackage("llvm", llvmVersion, pkg.NewHTTPGetTar(
nil, "https://github.com/llvm/llvm-project/archive/refs/tags/"+ nil, "https://github.com/llvm/llvm-project/archive/refs/tags/"+
"llvmorg-"+version+".tar.gz", "llvmorg-"+llvmVersion+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), &PackageAttr{ ), &PackageAttr{
@@ -184,6 +187,7 @@ ln -s ld.lld /work/system/bin/ld
Append: cmakeAppend, Append: cmakeAppend,
Script: script + attr.script, Script: script + attr.script,
}, },
Zlib,
Libffi, Libffi,
Python, Python,
Perl, Perl,
@@ -216,6 +220,10 @@ func (t Toolchain) newLLVM() (musl, compilerRT, runtimes, clang pkg.Artifact) {
{"LLVM_ENABLE_LIBXML2", "OFF"}, {"LLVM_ENABLE_LIBXML2", "OFF"},
} }
muslHeaders, _ := t.newMusl(true, []string{
"CC=clang",
})
compilerRT = t.newLLVMVariant("compiler-rt", &llvmAttr{ compilerRT = t.newLLVMVariant("compiler-rt", &llvmAttr{
env: stage0ExclConcat(t, []string{}, env: stage0ExclConcat(t, []string{},
"LDFLAGS="+earlyLDFLAGS(false), "LDFLAGS="+earlyLDFLAGS(false),
@@ -237,14 +245,14 @@ func (t Toolchain) newLLVM() (musl, compilerRT, runtimes, clang pkg.Artifact) {
{"COMPILER_RT_BUILD_XRAY", "OFF"}, {"COMPILER_RT_BUILD_XRAY", "OFF"},
}, },
append: []string{"compiler-rt"}, append: []string{"compiler-rt"},
nonStage0: []pkg.Artifact{t.newMusl(true, []string{ nonStage0: []pkg.Artifact{
"CC=clang", muslHeaders,
})}, },
script: ` script: `
mkdir -p "/work/system/lib/clang/21/lib/" mkdir -p "/work/system/lib/clang/` + llvmVersionMajor + `/lib/"
ln -s \ ln -s \
"../../../${ROSA_TRIPLE}" \ "../../../${ROSA_TRIPLE}" \
"/work/system/lib/clang/21/lib/" "/work/system/lib/clang/` + llvmVersionMajor + `/lib/"
ln -s \ ln -s \
"clang_rt.crtbegin-` + linuxArch() + `.o" \ "clang_rt.crtbegin-` + linuxArch() + `.o" \
@@ -255,9 +263,9 @@ ln -s \
`, `,
}) })
musl = t.newMusl(false, stage0ExclConcat(t, []string{ musl, _ = t.newMusl(false, stage0ExclConcat(t, []string{
"CC=clang", "CC=clang",
"LIBCC=/system/lib/clang/21/lib/" + "LIBCC=/system/lib/clang/" + llvmVersionMajor + "/lib/" +
triplet() + "/libclang_rt.builtins.a", triplet() + "/libclang_rt.builtins.a",
"AR=ar", "AR=ar",
"RANLIB=ranlib", "RANLIB=ranlib",
@@ -310,10 +318,10 @@ ninja check-all
patches: [][2]string{ patches: [][2]string{
{"add-rosa-vendor", `diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h {"add-rosa-vendor", `diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 657f4230379e..12c305756184 100644 index 9c83abeeb3b1..5acfe5836a23 100644
--- a/llvm/include/llvm/TargetParser/Triple.h --- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -185,6 +185,7 @@ public: @@ -190,6 +190,7 @@ public:
Apple, Apple,
PC, PC,
@@ -322,25 +330,25 @@ index 657f4230379e..12c305756184 100644
Freescale, Freescale,
IBM, IBM,
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 0584c941d2e6..e4d6ef963cc7 100644 index a4f9dd42c0fe..cb5a12387034 100644
--- a/llvm/lib/TargetParser/Triple.cpp --- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp
@@ -269,6 +269,7 @@ StringRef Triple::getVendorTypeName(VendorType Kind) { @@ -279,6 +279,7 @@ StringRef Triple::getVendorTypeName(VendorType Kind) {
case NVIDIA: return "nvidia"; case NVIDIA: return "nvidia";
case OpenEmbedded: return "oe"; case OpenEmbedded: return "oe";
case PC: return "pc"; case PC: return "pc";
+ case Rosa: return "rosa"; + case Rosa: return "rosa";
case SCEI: return "scei"; case SCEI: return "scei";
case SUSE: return "suse"; case SUSE: return "suse";
} case Meta:
@@ -669,6 +670,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) { @@ -689,6 +690,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) {
.Case("suse", Triple::SUSE) return StringSwitch<Triple::VendorType>(VendorName)
.Case("oe", Triple::OpenEmbedded) .Case("apple", Triple::Apple)
.Case("intel", Triple::Intel) .Case("pc", Triple::PC)
+ .Case("rosa", Triple::Rosa) + .Case("rosa", Triple::Rosa)
.Default(Triple::UnknownVendor); .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 {"xfail-broken-tests", `diff --git a/clang/test/Modules/timestamps.c b/clang/test/Modules/timestamps.c
@@ -485,6 +493,42 @@ index 64324a3f8b01..15ce70b68217 100644
return return
} }
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
},
Name: "llvm-runtimes",
Description: "LLVM runtimes: libunwind, libcxx, libcxxabi",
Website: "https://llvm.org/",
}
artifactsM[LLVMClang] = Metadata{
f: func(t Toolchain) (pkg.Artifact, string) {
_, _, _, clang := t.newLLVM()
return clang, llvmVersion
},
Name: "clang",
Description: `an "LLVM native" C/C++/Objective-C compiler`,
Website: "https://llvm.org/",
ID: 1830,
}
}
var ( var (
// llvm stores the result of Toolchain.newLLVM. // llvm stores the result of Toolchain.newLLVM.

View File

@@ -7,7 +7,7 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newMake() pkg.Artifact { func (t Toolchain) newMake() (pkg.Artifact, string) {
const ( const (
version = "4.4.1" version = "4.4.1"
checksum = "YS_B07ZcAy9PbaK5_vKGj64SrxO2VMpnMKfc9I0Q9IC1rn0RwOH7802pJoj2Mq4a" checksum = "YS_B07ZcAy9PbaK5_vKGj64SrxO2VMpnMKfc9I0Q9IC1rn0RwOH7802pJoj2Mq4a"
@@ -24,9 +24,19 @@ cd "$(mktemp -d)"
nil, "https://ftpmirror.gnu.org/gnu/make/make-"+version+".tar.gz", nil, "https://ftpmirror.gnu.org/gnu/make/make-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
))) ))), version
}
func init() {
artifactsM[Make] = Metadata{
f: Toolchain.newMake,
Name: "make",
Description: "a tool which controls the generation of executables and other non-source files",
Website: "https://www.gnu.org/software/make/",
ID: 1877,
}
} }
func init() { artifactsF[Make] = Toolchain.newMake }
// MakeHelper is the [Make] build system helper. // MakeHelper is the [Make] build system helper.
type MakeHelper struct { type MakeHelper struct {

View File

@@ -7,12 +7,13 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newMeson() pkg.Artifact { func (t Toolchain) newMeson() (pkg.Artifact, string) {
const ( const (
version = "1.10.1" version = "1.10.1"
checksum = "w895BXF_icncnXatT_OLCFe2PYEtg4KrKooMgUYdN-nQVvbFX3PvYWHGEpogsHtd" checksum = "w895BXF_icncnXatT_OLCFe2PYEtg4KrKooMgUYdN-nQVvbFX3PvYWHGEpogsHtd"
) )
return t.New("meson-"+version, 0, []pkg.Artifact{ return t.New("meson-"+version, 0, []pkg.Artifact{
t.Load(Zlib),
t.Load(Python), t.Load(Python),
t.Load(Setuptools), t.Load(Setuptools),
}, nil, nil, ` }, nil, nil, `
@@ -27,9 +28,19 @@ python3 setup.py \
version+"/meson-"+version+".tar.gz", version+"/meson-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
))) ))), version
}
func init() {
artifactsM[Meson] = Metadata{
f: Toolchain.newMeson,
Name: "meson",
Description: "an open source build system",
Website: "https://mesonbuild.com/",
ID: 6472,
}
} }
func init() { artifactsF[Meson] = Toolchain.newMeson }
// MesonHelper is the [Meson] build system helper. // MesonHelper is the [Meson] build system helper.
type MesonHelper struct { type MesonHelper struct {
@@ -56,6 +67,7 @@ func (*MesonHelper) name(name, version string) string {
// extra returns hardcoded meson runtime dependencies. // extra returns hardcoded meson runtime dependencies.
func (*MesonHelper) extra(int) []PArtifact { func (*MesonHelper) extra(int) []PArtifact {
return []PArtifact{ return []PArtifact{
Zlib,
Python, Python,
Meson, Meson,
Ninja, Ninja,

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newMksh() pkg.Artifact { func (t Toolchain) newMksh() (pkg.Artifact, string) {
const ( const (
version = "59c" version = "59c"
checksum = "0Zj-k4nXEu3IuJY4lvwD2OrC2t27GdZj8SPy4DoaeuBRH1padWb7oREpYgwY8JNq" checksum = "0Zj-k4nXEu3IuJY4lvwD2OrC2t27GdZj8SPy4DoaeuBRH1padWb7oREpYgwY8JNq"
@@ -31,6 +31,16 @@ ln -vs ../system/bin/sh /work/bin/
"https://mbsd.evolvis.org/MirOS/dist/mir/mksh/mksh-R"+version+".tgz", "https://mbsd.evolvis.org/MirOS/dist/mir/mksh/mksh-R"+version+".tgz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
))) ))), version
}
func init() {
artifactsM[Mksh] = Metadata{
f: Toolchain.newMksh,
Name: "mksh",
Description: "MirBSD Korn Shell",
Website: "https://www.mirbsd.org/mksh",
ID: 5590,
}
} }
func init() { artifactsF[Mksh] = Toolchain.newMksh }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newMuslFts() pkg.Artifact { func (t Toolchain) newMuslFts() (pkg.Artifact, string) {
const ( const (
version = "1.2.7" version = "1.2.7"
checksum = "N_p_ZApX3eHt7xoDCw1hLf6XdJOw7ZSx7xPvpvAP0knG2zgU0zeN5w8tt5Pg60XJ" checksum = "N_p_ZApX3eHt7xoDCw1hLf6XdJOw7ZSx7xPvpvAP0knG2zgU0zeN5w8tt5Pg60XJ"
@@ -25,6 +25,16 @@ func (t Toolchain) newMuslFts() pkg.Artifact {
Automake, Automake,
Libtool, Libtool,
PkgConfig, PkgConfig,
) ), version
}
func init() {
artifactsM[MuslFts] = Metadata{
f: Toolchain.newMuslFts,
Name: "musl-fts",
Description: "implementation of fts(3) functions which are missing in musl libc",
Website: "https://github.com/void-linux/musl-fts",
ID: 26980,
}
} }
func init() { artifactsF[MuslFts] = Toolchain.newMuslFts }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newMuslObstack() pkg.Artifact { func (t Toolchain) newMuslObstack() (pkg.Artifact, string) {
const ( const (
version = "1.2.3" version = "1.2.3"
checksum = "tVRY_KjIlkkMszcaRlkKdBVQHIXTT_T_TiMxbwErlILXrOBosocg8KklppZhNdCG" checksum = "tVRY_KjIlkkMszcaRlkKdBVQHIXTT_T_TiMxbwErlILXrOBosocg8KklppZhNdCG"
@@ -25,6 +25,16 @@ func (t Toolchain) newMuslObstack() pkg.Artifact {
Automake, Automake,
Libtool, Libtool,
PkgConfig, PkgConfig,
) ), version
}
func init() {
artifactsM[MuslObstack] = Metadata{
f: Toolchain.newMuslObstack,
Name: "musl-obstack",
Description: "obstack functions and macros separated from glibc",
Website: "https://github.com/void-linux/musl-obstack",
ID: 146206,
}
} }
func init() { artifactsF[MuslObstack] = Toolchain.newMuslObstack }

View File

@@ -6,7 +6,7 @@ func (t Toolchain) newMusl(
headers bool, headers bool,
env []string, env []string,
extra ...pkg.Artifact, extra ...pkg.Artifact,
) pkg.Artifact { ) (pkg.Artifact, string) {
const ( const (
version = "1.2.5" version = "1.2.5"
checksum = "y6USdIeSdHER_Fw2eT2CNjqShEye85oEg2jnOur96D073ukmIpIqDOLmECQroyDb" checksum = "y6USdIeSdHER_Fw2eT2CNjqShEye85oEg2jnOur96D073ukmIpIqDOLmECQroyDb"
@@ -50,10 +50,18 @@ rmdir -v /work/lib
Env: env, Env: env,
}, &helper, }, &helper,
Coreutils, Coreutils,
) ), version
} }
func init() { func init() {
artifactsF[Musl] = func(t Toolchain) pkg.Artifact { artifactsM[Musl] = Metadata{
return t.newMusl(false, nil) f: func(t Toolchain) (pkg.Artifact, string) {
return t.newMusl(false, nil)
},
Name: "musl",
Description: "an implementation of the C standard library",
Website: "https://musl.libc.org/",
ID: 11688,
} }
} }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newNcurses() pkg.Artifact { func (t Toolchain) newNcurses() (pkg.Artifact, string) {
const ( const (
version = "6.6" version = "6.6"
checksum = "XvWp4xi6hR_hH8XUoGY26L_pqBSDapJYulhzZqPuR0KNklqypqNc1yNXU-nOjf5w" checksum = "XvWp4xi6hR_hH8XUoGY26L_pqBSDapJYulhzZqPuR0KNklqypqNc1yNXU-nOjf5w"
@@ -21,6 +21,16 @@ func (t Toolchain) newNcurses() pkg.Artifact {
}, },
}, },
PkgConfig, PkgConfig,
) ), version
}
func init() {
artifactsM[Ncurses] = Metadata{
f: Toolchain.newNcurses,
Name: "ncurses",
Description: "a free software emulation of curses in System V Release 4.0 (SVr4)",
Website: "https://invisible-island.net/ncurses/",
ID: 373226,
}
} }
func init() { artifactsF[Ncurses] = Toolchain.newNcurses }

31
internal/rosa/nettle.go Normal file
View File

@@ -0,0 +1,31 @@
package rosa
import "hakurei.app/internal/pkg"
func (t Toolchain) newNettle() (pkg.Artifact, string) {
const (
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),
pkg.TarGzip,
), nil, (*MakeHelper)(nil),
M4,
Diffutils,
GMP,
), version
}
func init() {
artifactsM[Nettle] = Metadata{
f: Toolchain.newNettle,
Name: "nettle",
Description: "a low-level cryptographic library",
Website: "https://www.lysator.liu.se/~nisse/nettle/",
ID: 2073,
}
}

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newNinja() pkg.Artifact { func (t Toolchain) newNinja() (pkg.Artifact, string) {
const ( const (
version = "1.13.2" version = "1.13.2"
checksum = "ygKWMa0YV2lWKiFro5hnL-vcKbc_-RACZuPu0Io8qDvgQlZ0dxv7hPNSFkt4214v" checksum = "ygKWMa0YV2lWKiFro5hnL-vcKbc_-RACZuPu0Io8qDvgQlZ0dxv7hPNSFkt4214v"
@@ -33,6 +33,16 @@ cp ninja /work/system/bin/
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), false, ), false,
))) ))), version
}
func init() {
artifactsM[Ninja] = Metadata{
f: Toolchain.newNinja,
Name: "ninja",
Description: "a small build system with a focus on speed",
Website: "https://ninja-build.org/",
ID: 2089,
}
} }
func init() { artifactsF[Ninja] = Toolchain.newNinja }

View File

@@ -2,10 +2,10 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newOpenSSL() pkg.Artifact { func (t Toolchain) newOpenSSL() (pkg.Artifact, string) {
const ( const (
version = "3.5.5" version = "3.6.1"
checksum = "I2Hp1LxcTR8j4G6LFEQMVy6EJH-Na1byI9Ti-ThBot6EMLNRnjGXGq-WXrim3Fkz" checksum = "boMAj2SIVIFXHswZva3qHJuFEpc32rxCCu07wjMPsVe9nn_976BGMmW_5P1zthgg"
) )
return t.NewPackage("openssl", version, pkg.NewHTTPGetTar( return t.NewPackage("openssl", version, pkg.NewHTTPGetTar(
nil, "https://github.com/openssl/openssl/releases/download/"+ nil, "https://github.com/openssl/openssl/releases/download/"+
@@ -35,6 +35,19 @@ func (t Toolchain) newOpenSSL() pkg.Artifact {
Zlib, Zlib,
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[OpenSSL] = Metadata{
f: Toolchain.newOpenSSL,
Name: "openssl",
Description: "TLS/SSL and crypto library",
Website: "https://www.openssl.org/",
ID: 2566,
// strange malformed tags treated as pre-releases in Anitya
latest: (*Versions).getStable,
}
} }
func init() { artifactsF[OpenSSL] = Toolchain.newOpenSSL }

View File

@@ -4,10 +4,10 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newPCRE2() pkg.Artifact { func (t Toolchain) newPCRE2() (pkg.Artifact, string) {
const ( const (
version = "10.43" version = "10.47"
checksum = "iyNw-POPSJwiZVJfUK5qACA6q2uMzP-84WieimN_CskaEkuw5fRnRTZhEv6ry2Yo" checksum = "IbC24vVayju6nB9EhrBPSDexk22wDecdpyrjgC3nCZXkwTnUjq4CD2q5sopqu6CW"
) )
return t.NewPackage("pcre2", version, pkg.NewHTTPGetTar( return t.NewPackage("pcre2", version, pkg.NewHTTPGetTar(
nil, "https://github.com/PCRE2Project/pcre2/releases/download/"+ nil, "https://github.com/PCRE2Project/pcre2/releases/download/"+
@@ -28,6 +28,16 @@ ln -s ../system/bin/toybox /bin/echo
}, },
}, },
Diffutils, Diffutils,
) ), version
}
func init() {
artifactsM[PCRE2] = Metadata{
f: Toolchain.newPCRE2,
Name: "pcre2",
Description: "a set of C functions that implement regular expression pattern matching",
Website: "https://pcre2project.github.io/pcre2/",
ID: 5832,
}
} }
func init() { artifactsF[PCRE2] = Toolchain.newPCRE2 }

View File

@@ -6,7 +6,7 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newPerl() pkg.Artifact { func (t Toolchain) newPerl() (pkg.Artifact, string) {
const ( const (
version = "5.42.0" version = "5.42.0"
checksum = "2KR7Jbpk-ZVn1a30LQRwbgUvg2AXlPQZfzrqCr31qD5-yEsTwVQ_W76eZH-EdxM9" checksum = "2KR7Jbpk-ZVn1a30LQRwbgUvg2AXlPQZfzrqCr31qD5-yEsTwVQ_W76eZH-EdxM9"
@@ -39,15 +39,29 @@ rm -f /system/bin/ps # perl does not like toybox ps
{"Dldflags", `"${LDFLAGS:-''}"`}, {"Dldflags", `"${LDFLAGS:-''}"`},
{"Doptimize", "'-O2 -fno-strict-aliasing'"}, {"Doptimize", "'-O2 -fno-strict-aliasing'"},
{"Duseithreads"}, {"Duseithreads"},
{"Duseshrplib"},
}, },
Check: []string{ Check: []string{
"TEST_JOBS=256", "TEST_JOBS=256",
"test_harness", "test_harness",
}, },
Install: "./perl -Ilib -I. installperl --destdir=/work", Install: `LD_LIBRARY_PATH="$PWD" ./perl -Ilib -I. installperl --destdir=/work`,
}) }), version
}
func init() {
artifactsM[Perl] = Metadata{
f: Toolchain.newPerl,
Name: "perl",
Description: "The Perl Programming language",
Website: "https://www.perl.org/",
ID: 13599,
// odd-even versioning
latest: (*Versions).getStable,
}
} }
func init() { artifactsF[Perl] = Toolchain.newPerl }
// newViaPerlModuleBuild installs a perl module via Build.PL. // newViaPerlModuleBuild installs a perl module via Build.PL.
func (t Toolchain) newViaPerlModuleBuild( func (t Toolchain) newViaPerlModuleBuild(
@@ -72,7 +86,7 @@ perl Build.PL --prefix=/system
))) )))
} }
func (t Toolchain) newPerlModuleBuild() pkg.Artifact { func (t Toolchain) newPerlModuleBuild() (pkg.Artifact, string) {
const ( const (
version = "0.4234" version = "0.4234"
checksum = "ZKxEFG4hE1rqZt52zBL2LRZBMkYzhjb5-cTBXcsyA52EbPeeYyVxU176yAea8-Di" checksum = "ZKxEFG4hE1rqZt52zBL2LRZBMkYzhjb5-cTBXcsyA52EbPeeYyVxU176yAea8-Di"
@@ -82,9 +96,17 @@ func (t Toolchain) newPerlModuleBuild() pkg.Artifact {
"Module-Build-"+version+".tar.gz", "Module-Build-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), nil) ), nil), version
}
func init() {
artifactsM[PerlModuleBuild] = Metadata{
f: Toolchain.newPerlModuleBuild,
Name: "perl-Module::Build",
Description: "build and install Perl modules",
Website: "https://metacpan.org/release/Module-Build",
}
} }
func init() { artifactsF[PerlModuleBuild] = Toolchain.newPerlModuleBuild }
// newViaPerlMakeMaker installs a perl module via Makefile.PL. // newViaPerlMakeMaker installs a perl module via Makefile.PL.
func (t Toolchain) newViaPerlMakeMaker( func (t Toolchain) newViaPerlMakeMaker(
@@ -114,7 +136,7 @@ func (t Toolchain) newViaPerlMakeMaker(
})...) })...)
} }
func (t Toolchain) newPerlLocaleGettext() pkg.Artifact { func (t Toolchain) newPerlLocaleGettext() (pkg.Artifact, string) {
const ( const (
version = "1.07" version = "1.07"
checksum = "cFq4BKFD1MWSoa7lsrPjpdo9kzPqd0jlRcBFUyL1L1isw8m3D_Sge_ff0MAu_9J3" checksum = "cFq4BKFD1MWSoa7lsrPjpdo9kzPqd0jlRcBFUyL1L1isw8m3D_Sge_ff0MAu_9J3"
@@ -124,11 +146,19 @@ func (t Toolchain) newPerlLocaleGettext() pkg.Artifact {
"Locale-gettext-"+version+".tar.gz", "Locale-gettext-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), nil) ), nil), version
} }
func init() { artifactsF[PerlLocaleGettext] = Toolchain.newPerlLocaleGettext } func init() {
artifactsM[PerlLocaleGettext] = Metadata{
f: Toolchain.newPerlLocaleGettext,
func (t Toolchain) newPerlPodParser() pkg.Artifact { Name: "perl-Locale::gettext",
Description: "message handling functions",
Website: "https://metacpan.org/release/Locale-gettext",
}
}
func (t Toolchain) newPerlPodParser() (pkg.Artifact, string) {
const ( const (
version = "1.67" version = "1.67"
checksum = "RdURu9mOfExk_loCp6abxlcQV3FycSNbTqhRS9i6JUqnYfGGEgercK30g0gjYyqe" checksum = "RdURu9mOfExk_loCp6abxlcQV3FycSNbTqhRS9i6JUqnYfGGEgercK30g0gjYyqe"
@@ -138,11 +168,19 @@ func (t Toolchain) newPerlPodParser() pkg.Artifact {
"Pod-Parser-"+version+".tar.gz", "Pod-Parser-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), nil) ), nil), version
} }
func init() { artifactsF[PerlPodParser] = Toolchain.newPerlPodParser } func init() {
artifactsM[PerlPodParser] = Metadata{
f: Toolchain.newPerlPodParser,
func (t Toolchain) newPerlSGMLS() pkg.Artifact { Name: "perl-Pod::Parser",
Description: "base class for creating POD filters and translators",
Website: "https://metacpan.org/release/Pod-Parser",
}
}
func (t Toolchain) newPerlSGMLS() (pkg.Artifact, string) {
const ( const (
version = "1.1" version = "1.1"
checksum = "aZijn4MUqD-wfyZgdcCruCwl4SgDdu25cNmJ4_UvdAk9a7uz4gzMQdoeB6DQ6QOy" checksum = "aZijn4MUqD-wfyZgdcCruCwl4SgDdu25cNmJ4_UvdAk9a7uz4gzMQdoeB6DQ6QOy"
@@ -152,11 +190,19 @@ func (t Toolchain) newPerlSGMLS() pkg.Artifact {
"SGMLSpm-"+version+".tar.gz", "SGMLSpm-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), nil) ), nil), version
} }
func init() { artifactsF[PerlSGMLS] = Toolchain.newPerlSGMLS } func init() {
artifactsM[PerlSGMLS] = Metadata{
f: Toolchain.newPerlSGMLS,
func (t Toolchain) newPerlTermReadKey() pkg.Artifact { Name: "perl-SGMLS",
Description: "class for postprocessing the output from the sgmls and nsgmls parsers",
Website: "https://metacpan.org/release/RAAB/SGMLSpm-1.1",
}
}
func (t Toolchain) newPerlTermReadKey() (pkg.Artifact, string) {
const ( const (
version = "2.38" version = "2.38"
checksum = "qerL8Xo7kD0f42PZoiEbmE8Roc_S9pOa27LXelY4DN_0UNy_u5wLrGHI8utNlaiI" checksum = "qerL8Xo7kD0f42PZoiEbmE8Roc_S9pOa27LXelY4DN_0UNy_u5wLrGHI8utNlaiI"
@@ -166,11 +212,19 @@ func (t Toolchain) newPerlTermReadKey() pkg.Artifact {
"TermReadKey-"+version+".tar.gz", "TermReadKey-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), nil) ), nil), version
} }
func init() { artifactsF[PerlTermReadKey] = Toolchain.newPerlTermReadKey } func init() {
artifactsM[PerlTermReadKey] = Metadata{
f: Toolchain.newPerlTermReadKey,
func (t Toolchain) newPerlTextCharWidth() pkg.Artifact { Name: "perl-Term::ReadKey",
Description: "a perl module for simple terminal control",
Website: "https://metacpan.org/release/TermReadKey",
}
}
func (t Toolchain) newPerlTextCharWidth() (pkg.Artifact, string) {
const ( const (
version = "0.04" version = "0.04"
checksum = "G2p5RHU4_HiZ23ZusBA_enTlVMxz0J4esUx4CGcOPhY6xYTbp-aXWRN6lYZpzBw2" checksum = "G2p5RHU4_HiZ23ZusBA_enTlVMxz0J4esUx4CGcOPhY6xYTbp-aXWRN6lYZpzBw2"
@@ -180,11 +234,19 @@ func (t Toolchain) newPerlTextCharWidth() pkg.Artifact {
"Text-CharWidth-"+version+".tar.gz", "Text-CharWidth-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), nil) ), nil), version
} }
func init() { artifactsF[PerlTextCharWidth] = Toolchain.newPerlTextCharWidth } func init() {
artifactsM[PerlTextCharWidth] = Metadata{
f: Toolchain.newPerlTextCharWidth,
func (t Toolchain) newPerlTextWrapI18N() pkg.Artifact { Name: "perl-Text::CharWidth",
Description: "get number of occupied columns of a string on terminal",
Website: "https://metacpan.org/release/Text-CharWidth",
}
}
func (t Toolchain) newPerlTextWrapI18N() (pkg.Artifact, string) {
const ( const (
version = "0.06" version = "0.06"
checksum = "Vmo89qLgxUqyQ6QmWJVqu60aQAUjrNKRjFQSXGnvClxofzRjiCa6idzPgJ4VkixM" checksum = "Vmo89qLgxUqyQ6QmWJVqu60aQAUjrNKRjFQSXGnvClxofzRjiCa6idzPgJ4VkixM"
@@ -196,11 +258,19 @@ func (t Toolchain) newPerlTextWrapI18N() pkg.Artifact {
pkg.TarGzip, pkg.TarGzip,
), nil, ), nil,
PerlTextCharWidth, PerlTextCharWidth,
) ), version
} }
func init() { artifactsF[PerlTextWrapI18N] = Toolchain.newPerlTextWrapI18N } func init() {
artifactsM[PerlTextWrapI18N] = Metadata{
f: Toolchain.newPerlTextWrapI18N,
func (t Toolchain) newPerlMIMECharset() pkg.Artifact { Name: "perl-Text::WrapI18N",
Description: "line wrapping module",
Website: "https://metacpan.org/release/Text-WrapI18N",
}
}
func (t Toolchain) newPerlMIMECharset() (pkg.Artifact, string) {
const ( const (
version = "1.013.1" version = "1.013.1"
checksum = "Ou_ukcrOa1cgtE3mptinb-os3bdL1SXzbRDFZQF3prrJj-drc3rp_huay7iDLJol" checksum = "Ou_ukcrOa1cgtE3mptinb-os3bdL1SXzbRDFZQF3prrJj-drc3rp_huay7iDLJol"
@@ -210,11 +280,19 @@ func (t Toolchain) newPerlMIMECharset() pkg.Artifact {
"MIME-Charset-"+version+".tar.gz", "MIME-Charset-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), nil) ), nil), version
} }
func init() { artifactsF[PerlMIMECharset] = Toolchain.newPerlMIMECharset } func init() {
artifactsM[PerlMIMECharset] = Metadata{
f: Toolchain.newPerlMIMECharset,
func (t Toolchain) newPerlUnicodeGCString() pkg.Artifact { Name: "perl-MIME::Charset",
Description: "Charset Information for MIME",
Website: "https://metacpan.org/release/MIME-Charset",
}
}
func (t Toolchain) newPerlUnicodeGCString() (pkg.Artifact, string) {
const ( const (
version = "2019.001" version = "2019.001"
checksum = "ZHVkh7EDgAUHnTpvXsnPAuWpgNoBImtY_9_8TIbo2co_WgUwEb0MtXPhI8pAZ5OH" checksum = "ZHVkh7EDgAUHnTpvXsnPAuWpgNoBImtY_9_8TIbo2co_WgUwEb0MtXPhI8pAZ5OH"
@@ -226,11 +304,19 @@ func (t Toolchain) newPerlUnicodeGCString() pkg.Artifact {
pkg.TarGzip, pkg.TarGzip,
), nil, ), nil,
PerlMIMECharset, PerlMIMECharset,
) ), version
} }
func init() { artifactsF[PerlUnicodeGCString] = Toolchain.newPerlUnicodeGCString } func init() {
artifactsM[PerlUnicodeGCString] = Metadata{
f: Toolchain.newPerlUnicodeGCString,
func (t Toolchain) newPerlYAMLTiny() pkg.Artifact { Name: "perl-Unicode::GCString",
Description: "String as Sequence of UAX #29 Grapheme Clusters",
Website: "https://metacpan.org/release/Unicode-LineBreak",
}
}
func (t Toolchain) newPerlYAMLTiny() (pkg.Artifact, string) {
const ( const (
version = "1.76" version = "1.76"
checksum = "V1MV4KPym1LxSw8CRXqPR3K-l1hGHbT5Ob4t-9xju6R9X_CWyw6hI8wsMaNdHdBY" checksum = "V1MV4KPym1LxSw8CRXqPR3K-l1hGHbT5Ob4t-9xju6R9X_CWyw6hI8wsMaNdHdBY"
@@ -240,6 +326,14 @@ func (t Toolchain) newPerlYAMLTiny() pkg.Artifact {
"YAML-Tiny-"+version+".tar.gz", "YAML-Tiny-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), nil) ), nil), version
}
func init() {
artifactsM[PerlYAMLTiny] = Metadata{
f: Toolchain.newPerlYAMLTiny,
Name: "perl-YAML::Tiny",
Description: "read/write YAML files with as little code as possible",
Website: "https://metacpan.org/release/YAML-Tiny",
}
} }
func init() { artifactsF[PerlYAMLTiny] = Toolchain.newPerlYAMLTiny }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newPkgConfig() pkg.Artifact { func (t Toolchain) newPkgConfig() (pkg.Artifact, string) {
const ( const (
version = "0.29.2" version = "0.29.2"
checksum = "gi7yAvkwo20Inys1tHbeYZ3Wjdm5VPkrnO0Q6_QZPCAwa1zrA8F4a63cdZDd-717" checksum = "gi7yAvkwo20Inys1tHbeYZ3Wjdm5VPkrnO0Q6_QZPCAwa1zrA8F4a63cdZDd-717"
@@ -17,6 +17,16 @@ func (t Toolchain) newPkgConfig() pkg.Artifact {
{"CFLAGS", "'-Wno-int-conversion'"}, {"CFLAGS", "'-Wno-int-conversion'"},
{"with-internal-glib"}, {"with-internal-glib"},
}, },
}) }), version
}
func init() {
artifactsM[PkgConfig] = Metadata{
f: Toolchain.newPkgConfig,
Name: "pkg-config",
Description: "a helper tool used when compiling applications and libraries",
Website: "https://pkgconfig.freedesktop.org/",
ID: 3649,
}
} }
func init() { artifactsF[PkgConfig] = Toolchain.newPkgConfig }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newProcps() pkg.Artifact { func (t Toolchain) newProcps() (pkg.Artifact, string) {
const ( const (
version = "4.0.6" version = "4.0.6"
checksum = "pl_fZLvDlv6iZTkm8l_tHFpzTDVFGCiSJEs3eu0zAX6u36AV36P_En8K7JPScRWM" checksum = "pl_fZLvDlv6iZTkm8l_tHFpzTDVFGCiSJEs3eu0zAX6u36AV36P_En8K7JPScRWM"
@@ -27,6 +27,16 @@ func (t Toolchain) newProcps() pkg.Artifact {
Gzip, Gzip,
PkgConfig, PkgConfig,
) ), version
}
func init() {
artifactsM[Procps] = Metadata{
f: Toolchain.newProcps,
Name: "procps",
Description: "command line and full screen utilities for browsing procfs",
Website: "https://gitlab.com/procps-ng/procps",
ID: 3708,
}
} }
func init() { artifactsF[Procps] = Toolchain.newProcps }

View File

@@ -7,10 +7,10 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newPython() pkg.Artifact { func (t Toolchain) newPython() (pkg.Artifact, string) {
const ( const (
version = "3.14.2" version = "3.14.3"
checksum = "7nZunVMGj0viB-CnxpcRego2C90X5wFsMTgsoewd5z-KSZY2zLuqaBwG-14zmKys" checksum = "ajEC32WPmn9Jvll0n4gGvlTvhMPUHb2H_j5_h9jf_esHmkZBRfAumDcKY7nTTsCH"
) )
return t.NewPackage("python", version, pkg.NewHTTPGetTar( return t.NewPackage("python", version, pkg.NewHTTPGetTar(
nil, "https://www.python.org/ftp/python/"+version+ nil, "https://www.python.org/ftp/python/"+version+
@@ -59,36 +59,61 @@ func (t Toolchain) newPython() pkg.Artifact {
OpenSSL, OpenSSL,
Bzip2, Bzip2,
XZ, XZ,
) ), version
}
func init() {
artifactsM[Python] = Metadata{
f: Toolchain.newPython,
Name: "python",
Description: "the Python programming language interpreter",
Website: "https://www.python.org/",
ID: 13254,
}
} }
func init() { artifactsF[Python] = Toolchain.newPython }
// newViaPip is a helper for installing python dependencies via pip. // newViaPip is a helper for installing python dependencies via pip.
func (t Toolchain) newViaPip( func newViaPip(
name, version, abi, platform, checksum, prefix string, name, description, version, interpreter, abi, platform, checksum, prefix string,
extra ...pkg.Artifact, extra ...PArtifact,
) pkg.Artifact { ) Metadata {
wname := name + "-" + version + "-py3-" + abi + "-" + platform + ".whl" wname := name + "-" + version + "-" + interpreter + "-" + abi + "-" + platform + ".whl"
return t.New(name+"-"+version, 0, slices.Concat([]pkg.Artifact{ return Metadata{
t.Load(Python), f: func(t Toolchain) (pkg.Artifact, string) {
}, extra), nil, nil, ` extraRes := make([]pkg.Artifact, len(extra))
for i, p := range extra {
extraRes[i] = t.Load(p)
}
return t.New(name+"-"+version, 0, slices.Concat([]pkg.Artifact{
t.Load(Zlib),
t.Load(Python),
}, extraRes), nil, nil, `
pip3 install \ pip3 install \
--no-index \ --no-index \
--prefix=/system \ --prefix=/system \
--root=/work \ --root=/work \
/usr/src/`+wname+` /usr/src/`+wname+`
`, pkg.Path(AbsUsrSrc.Append(wname), false, pkg.NewHTTPGet( `, pkg.Path(AbsUsrSrc.Append(wname), false, pkg.NewHTTPGet(
nil, prefix+wname, nil, prefix+wname,
mustDecode(checksum), mustDecode(checksum),
))) ))), version
},
Name: "python-" + name,
Description: description,
Website: "https://pypi.org/project/" + name + "/",
}
} }
func (t Toolchain) newSetuptools() pkg.Artifact { func (t Toolchain) newSetuptools() (pkg.Artifact, string) {
const ( const (
version = "80.10.1" version = "82.0.0"
checksum = "p3rlwEmy1krcUH1KabprQz1TCYjJ8ZUjOQknQsWh3q-XEqLGEd3P4VrCc7ouHGXU" checksum = "K9f8Yi7Gg95zjmQsE1LLw9UBb8NglI6EY6pQpdD6DM0Pmc_Td5w2qs1SMngTI6Jp"
) )
return t.New("setuptools-"+version, 0, []pkg.Artifact{ return t.New("setuptools-"+version, 0, []pkg.Artifact{
t.Load(Zlib),
t.Load(Python), t.Load(Python),
}, nil, nil, ` }, nil, nil, `
pip3 install \ pip3 install \
@@ -101,53 +126,172 @@ pip3 install \
"v"+version+".tar.gz", "v"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
))) ))), version
} }
func init() { artifactsF[Setuptools] = Toolchain.newSetuptools } func init() {
artifactsM[Setuptools] = Metadata{
f: Toolchain.newSetuptools,
func (t Toolchain) newPygments() pkg.Artifact { Name: "setuptools",
return t.newViaPip("pygments", "2.19.2", "none", "any", Description: "the autotools of the Python ecosystem",
Website: "https://pypi.org/project/setuptools/",
ID: 4021,
}
}
func init() {
artifactsM[PythonPygments] = newViaPip(
"pygments",
" a syntax highlighting package written in Python",
"2.19.2", "py3", "none", "any",
"ak_lwTalmSr7W4Mjy2XBZPG9I6a0gwSy2pS87N8x4QEuZYif0ie9z0OcfRfi9msd", "ak_lwTalmSr7W4Mjy2XBZPG9I6a0gwSy2pS87N8x4QEuZYif0ie9z0OcfRfi9msd",
"https://files.pythonhosted.org/packages/"+ "https://files.pythonhosted.org/packages/"+
"c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/") "c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/",
} )
func init() { artifactsF[Pygments] = Toolchain.newPygments }
func (t Toolchain) newPluggy() pkg.Artifact { artifactsM[PythonPluggy] = newViaPip(
return t.newViaPip("pluggy", "1.6.0", "none", "any", "pluggy",
"the core framework used by the pytest, tox, and devpi projects",
"1.6.0", "py3", "none", "any",
"2HWYBaEwM66-y1hSUcWI1MyE7dVVuNNRW24XD6iJBey4YaUdAK8WeXdtFMQGC-4J", "2HWYBaEwM66-y1hSUcWI1MyE7dVVuNNRW24XD6iJBey4YaUdAK8WeXdtFMQGC-4J",
"https://files.pythonhosted.org/packages/"+ "https://files.pythonhosted.org/packages/"+
"54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/") "54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/",
} )
func init() { artifactsF[Pluggy] = Toolchain.newPluggy }
func (t Toolchain) newPackaging() pkg.Artifact { artifactsM[PythonPackaging] = newViaPip(
return t.newViaPip("packaging", "26.0", "none", "any", "packaging",
"reusable core utilities for various Python Packaging interoperability specifications",
"26.0", "py3", "none", "any",
"iVVXcqdwHDskPKoCFUlh2x8J0Gyq-bhO4ns9DvUJ7oJjeOegRYtSIvLV33Bki-pP", "iVVXcqdwHDskPKoCFUlh2x8J0Gyq-bhO4ns9DvUJ7oJjeOegRYtSIvLV33Bki-pP",
"https://files.pythonhosted.org/packages/"+ "https://files.pythonhosted.org/packages/"+
"b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/") "b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/",
} )
func init() { artifactsF[Packaging] = Toolchain.newPackaging }
func (t Toolchain) newIniConfig() pkg.Artifact { artifactsM[PythonIniConfig] = newViaPip(
const version = "2.3.0" "iniconfig",
return t.newViaPip("iniconfig", version, "none", "any", "a small and simple INI-file parser module",
"2.3.0", "py3", "none", "any",
"SDgs4S5bXi77aVOeKTPv2TUrS3M9rduiK4DpU0hCmDsSBWqnZcWInq9lsx6INxut", "SDgs4S5bXi77aVOeKTPv2TUrS3M9rduiK4DpU0hCmDsSBWqnZcWInq9lsx6INxut",
"https://github.com/pytest-dev/iniconfig/releases/download/"+ "https://files.pythonhosted.org/packages/"+
"v"+version+"/") "cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/",
} )
func init() { artifactsF[IniConfig] = Toolchain.newIniConfig }
func (t Toolchain) newPyTest() pkg.Artifact { artifactsM[PythonPyTest] = newViaPip(
const version = "9.0.2" "pytest",
return t.newViaPip("pytest", version, "none", "any", "the pytest framework",
"9.0.2", "py3", "none", "any",
"IM2wDbLke1EtZhF92zvAjUl_Hms1uKDtM7U8Dt4acOaChMnDg1pW7ib8U0wYGDLH", "IM2wDbLke1EtZhF92zvAjUl_Hms1uKDtM7U8Dt4acOaChMnDg1pW7ib8U0wYGDLH",
"https://github.com/pytest-dev/pytest/releases/download/"+ "https://files.pythonhosted.org/packages/"+
version+"/", "3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/",
t.Load(IniConfig), PythonIniConfig,
t.Load(Packaging), PythonPackaging,
t.Load(Pluggy), PythonPluggy,
t.Load(Pygments), PythonPygments,
)
artifactsM[PythonCfgv] = newViaPip(
"cfgv",
"validate configuration and produce human readable error messages",
"3.5.0", "py2.py3", "none", "any",
"yFKTyVRlmnLKAxvvge15kAd_GOP1Xh3fZ0NFImO5pBdD5e0zj3GRmA6Q1HdtLTYO",
"https://files.pythonhosted.org/packages/"+
"db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/",
)
artifactsM[PythonIdentify] = newViaPip(
"identify",
"file identification library for Python",
"2.6.17", "py2.py3", "none", "any",
"9RxK3igO-Pxxof5AuCAGiF_L1SWi4SpuSF1fWNXCzE2D4oTRSob-9VpFMLlybrSv",
"https://files.pythonhosted.org/packages/"+
"40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/",
)
artifactsM[PythonNodeenv] = newViaPip(
"nodeenv",
"a tool to create isolated node.js environments",
"1.10.0", "py2.py3", "none", "any",
"ihUb4-WQXYIhYOOKSsXlKIzjzQieOYl6ojro9H-0DFzGheaRTtuyZgsCmriq58sq",
"https://files.pythonhosted.org/packages/"+
"88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/",
)
artifactsM[PythonPyYAML] = newViaPip(
"pyyaml",
"a complete YAML 1.1 parser",
"6.0.3", "cp314", "cp314", "musllinux_1_2_x86_64",
"4_jhCFpUNtyrFp2HOMqUisR005u90MHId53eS7rkUbcGXkoaJ7JRsY21dREHEfGN",
"https://files.pythonhosted.org/packages/"+
"d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/",
)
artifactsM[PythonDistlib] = newViaPip(
"distlib",
"used as the basis for third-party packaging tools",
"0.4.0", "py2.py3", "none", "any",
"lGLLfYVhUhXOTw_84zULaH2K8n6pk1OOVXmJfGavev7N42msbtHoq-XY5D_xULI_",
"https://files.pythonhosted.org/packages/"+
"33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/",
)
artifactsM[PythonFilelock] = newViaPip(
"filelock",
"a platform-independent file locking library for Python",
"3.25.0", "py3", "none", "any",
"0gSQIYNUEjOs1JBxXjGwfLnwFPFINwqyU_Zqgj7fT_EGafv_HaD5h3Xv2Rq_qQ44",
"https://files.pythonhosted.org/packages/"+
"f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/",
)
artifactsM[PythonPlatformdirs] = newViaPip(
"platformdirs",
"a Python package for determining platform-specific directories",
"4.9.4", "py3", "none", "any",
"JGNpMCX2JMn-7c9bk3QzOSNDgJRR_5lH-jIqfy0zXMZppRCdLsTNbdp4V7QFwxOI",
"https://files.pythonhosted.org/packages/"+
"63/d7/97f7e3a6abb67d8080dd406fd4df842c2be0efaf712d1c899c32a075027c/",
)
artifactsM[PythonDiscovery] = newViaPip(
"python_discovery",
"looks for a python installation",
"1.1.1", "py3", "none", "any",
"Jk_qGMfZYm0fdNOSvMdVQZuQbJlqu3NWRm7T2fRtiBXmHLQyOdJE3ypI_it1OJR0",
"https://files.pythonhosted.org/packages/"+
"75/0f/2bf7e3b5a4a65f623cb820feb5793e243fad58ae561015ee15a6152f67a2/",
PythonFilelock,
PythonPlatformdirs,
)
artifactsM[PythonVirtualenv] = newViaPip(
"virtualenv",
"a tool for creating isolated virtual python environments",
"21.1.0", "py3", "none", "any",
"SLvdr3gJZ7GTS-kiRyq2RvJdrQ8SZYC1pglbViWCMLCuAIcbLNjVEUJZ4hDtKUxm",
"https://files.pythonhosted.org/packages/"+
"78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/",
PythonDistlib,
PythonFilelock,
PythonPlatformdirs,
PythonDiscovery,
)
artifactsM[PythonPreCommit] = newViaPip(
"pre_commit",
"a framework for managing and maintaining multi-language pre-commit hooks",
"4.5.1", "py2.py3", "none", "any",
"9G2Hv5JpvXFZVfw4pv_KAsmHD6bvot9Z0YBDmW6JeJizqTA4xEQCKel-pCERqQFK",
"https://files.pythonhosted.org/packages/"+
"5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/",
PythonCfgv,
PythonIdentify,
PythonNodeenv,
PythonPyYAML,
PythonDistlib,
PythonFilelock,
PythonPlatformdirs,
PythonDiscovery,
PythonVirtualenv,
) )
} }
func init() { artifactsF[PyTest] = Toolchain.newPyTest }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newQEMU() pkg.Artifact { func (t Toolchain) newQEMU() (pkg.Artifact, string) {
const ( const (
version = "10.2.1" version = "10.2.1"
checksum = "rjLTSgHJd3X3Vgpxrsus_ZZiaYLiNix1YhcHaGbLd_odYixwZjCcAIt8CVQPJGdZ" checksum = "rjLTSgHJd3X3Vgpxrsus_ZZiaYLiNix1YhcHaGbLd_odYixwZjCcAIt8CVQPJGdZ"
@@ -93,6 +93,16 @@ EOF
Zstd, Zstd,
DTC, DTC,
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[QEMU] = Metadata{
f: Toolchain.newQEMU,
Name: "qemu",
Description: "a generic and open source machine emulator and virtualizer",
Website: "https://www.qemu.org/",
ID: 13607,
}
} }
func init() { artifactsF[QEMU] = Toolchain.newQEMU }

33
internal/rosa/rdfind.go Normal file
View File

@@ -0,0 +1,33 @@
package rosa
import "hakurei.app/internal/pkg"
func (t Toolchain) newRdfind() (pkg.Artifact, string) {
const (
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),
pkg.TarGzip,
), nil, &MakeHelper{
// test suite hard codes /bin/echo
ScriptCheckEarly: `
ln -s ../system/bin/toybox /bin/echo
`,
},
Nettle,
), version
}
func init() {
artifactsM[Rdfind] = Metadata{
f: Toolchain.newRdfind,
Name: "rdfind",
Description: "a program that finds duplicate files",
Website: "https://rdfind.pauldreik.se/",
ID: 231641,
}
}

235
internal/rosa/report.go Normal file
View File

@@ -0,0 +1,235 @@
package rosa
import (
"encoding/binary"
"errors"
"fmt"
"io"
"os"
"runtime"
"runtime/debug"
"strconv"
"sync"
"syscall"
"unique"
"unsafe"
"hakurei.app/internal/pkg"
"hakurei.app/message"
)
// wordSize is the boundary which binary segments are always aligned to.
const wordSize = 8
// padSize returns the padding size for aligning sz.
func padSize[T int | int64](sz T) T {
return (wordSize - (sz)%wordSize) % wordSize
}
// WriteReport writes a report of all available [PArtifact] to w.
func WriteReport(msg message.Msg, w io.Writer, c *pkg.Cache) error {
var (
zero [wordSize]byte
buf [len(pkg.ID{}) + wordSize]byte
)
for i := range PresetEnd {
a := Std.Load(PArtifact(i))
if _, ok := a.(pkg.FileArtifact); ok {
msg.Verbosef("skipping file artifact %s", artifactsM[i].Name)
continue
}
id := c.Ident(a)
var f *os.File
if r, err := c.OpenStatus(a); err != nil {
if errors.Is(err, os.ErrNotExist) {
msg.Verbosef("artifact %s unavailable", artifactsM[i].Name)
continue
}
return err
} else {
f = r.(*os.File)
}
msg.Verbosef("writing artifact %s...", artifactsM[i].Name)
var sz int64
if fi, err := f.Stat(); err != nil {
_ = f.Close()
return err
} else {
sz = fi.Size()
}
*(*pkg.ID)(buf[:]) = id.Value()
binary.LittleEndian.PutUint64(buf[len(pkg.ID{}):], uint64(sz))
if _, err := w.Write(buf[:]); err != nil {
_ = f.Close()
return err
}
if n, err := io.Copy(w, f); err != nil {
_ = f.Close()
return err
} else if n != sz {
_ = f.Close()
return fmt.Errorf("strange status file copy: %d != %d", n, sz)
} else if err = f.Close(); err != nil {
return err
}
if psz := padSize(sz); psz > 0 {
if _, err := w.Write(zero[:psz]); err != nil {
return err
}
}
// existence of status implies cured artifact
var n int
if pathname, _, err := c.Cure(a); err != nil {
return err
} else if n, err = pkg.Flatten(
os.DirFS(pathname.String()), ".",
io.Discard,
); err != nil {
return err
}
binary.LittleEndian.PutUint64(buf[:], uint64(n))
if _, err := w.Write(buf[:wordSize]); err != nil {
return err
}
}
return nil
}
// Report provides efficient access to a report file populated by [WriteReport].
type Report struct {
// Slice backed by the underlying file.
//
// Access must be prepared by HandleAccess.
data []byte
// Offsets into data for each identifier.
offsets map[unique.Handle[pkg.ID]]int
// Outcome of a call to Close.
closeErr error
// Synchronises calls to Close.
closeOnce sync.Once
}
// OpenReport opens a file populated by [WriteReport]
func OpenReport(pathname string) (rp *Report, err error) {
var f *os.File
if f, err = os.Open(pathname); err != nil {
return
}
var fi os.FileInfo
if fi, err = f.Stat(); err != nil {
_ = f.Close()
return
}
var r Report
if r.data, err = syscall.Mmap(
int(f.Fd()),
0,
int(fi.Size()),
syscall.PROT_READ,
syscall.MAP_PRIVATE,
); err != nil {
_ = f.Close()
return
}
if err = f.Close(); err != nil {
_ = r.Close()
return
}
defer r.HandleAccess(&err)()
var offset int
r.offsets = make(map[unique.Handle[pkg.ID]]int)
for offset < len(r.data) {
id := unique.Make((pkg.ID)(r.data[offset:]))
offset += len(pkg.ID{})
r.offsets[id] = offset
offset += int(binary.LittleEndian.Uint64(r.data[offset:])) + wordSize
offset += padSize(offset)
offset += wordSize
}
return &r, nil
}
// ReportIOError describes an I/O error while accessing a [Report].
type ReportIOError struct {
Offset int
Err error
}
// Unwrap returns the underlying runtime error.
func (e *ReportIOError) Unwrap() error { return e.Err }
// Error returns a description of the error offset.
func (e *ReportIOError) Error() string {
return "report I/O error at offset " + strconv.Itoa(e.Offset)
}
// HandleAccess prepares for accessing memory returned by a method of [Report]
// and returns a function that must be deferred by the caller.
func (r *Report) HandleAccess(errP *error) func() {
pof := debug.SetPanicOnFault(true)
return func() {
debug.SetPanicOnFault(pof)
v := recover()
if v == nil {
return
}
if err, ok := v.(error); !ok {
panic(v)
} else if *errP != nil {
return
} else {
*errP = err
}
var runtimeError interface {
Addr() uintptr
runtime.Error
}
if errors.As(*errP, &runtimeError) {
offset := int(runtimeError.Addr() - uintptr(unsafe.Pointer(unsafe.SliceData(r.data))))
// best effort for fragile uintptr
if offset >= 0 {
*errP = &ReportIOError{offset, *errP}
}
}
}
}
// ArtifactOf returns information of a [pkg.Artifact] corresponding to id.
func (r *Report) ArtifactOf(id unique.Handle[pkg.ID]) (status []byte, n int64) {
if offset, ok := r.offsets[id]; !ok {
n = -1
} else {
sz := int(binary.LittleEndian.Uint64(r.data[offset:]))
offset += wordSize
status = r.data[offset : offset+sz]
offset += sz + padSize(sz)
n = int64(binary.LittleEndian.Uint64(r.data[offset:]))
}
return
}
// Close closes the underlying file and releases all associated resources.
func (r *Report) Close() error {
r.closeOnce.Do(func() { r.closeErr = syscall.Munmap(r.data) })
return r.closeErr
}

View File

@@ -0,0 +1,57 @@
package rosa_test
import (
"errors"
"os"
"path"
"syscall"
"testing"
"unique"
"hakurei.app/internal/pkg"
"hakurei.app/internal/rosa"
)
func TestReportZeroLength(t *testing.T) {
report := path.Join(t.TempDir(), "report")
if err := os.WriteFile(report, nil, 0400); err != nil {
t.Fatal(err)
}
if _, err := rosa.OpenReport(report); !errors.Is(err, syscall.EINVAL) {
t.Fatalf("OpenReport: error = %v", err)
}
}
func TestReportSIGSEGV(t *testing.T) {
report := path.Join(t.TempDir(), "report")
if err := os.WriteFile(report, make([]byte, 64), 0400); err != nil {
t.Fatal(err)
}
if r, err := rosa.OpenReport(report); err != nil {
t.Fatalf("OpenReport: error = %v", err)
} else {
status, n := r.ArtifactOf(unique.Make(pkg.ID{}))
if len(status) != 0 {
t.Errorf("ArtifactsOf: status = %#v", status)
}
if n != 0 {
t.Errorf("ArtifactsOf: n = %d", n)
}
if err = r.Close(); err != nil {
t.Fatalf("Close: error = %v", err)
}
defer func() {
ioErr := err.(*rosa.ReportIOError)
if ioErr.Offset != 48 {
panic(ioErr)
}
}()
defer r.HandleAccess(&err)()
r.ArtifactOf(unique.Make(pkg.ID{}))
}
}

View File

@@ -329,7 +329,7 @@ mkdir -vp /work/system/bin
"AR=ar", "AR=ar",
"RANLIB=ranlib", "RANLIB=ranlib",
"LIBCC=/system/lib/clang/21/lib/" + triplet() + "LIBCC=/system/lib/clang/" + llvmVersionMajor + "/lib/" + triplet() +
"/libclang_rt.builtins.a", "/libclang_rt.builtins.a",
}, "/system/bin", "/bin") }, "/system/bin", "/bin")

View File

@@ -0,0 +1,93 @@
package rosa_test
import (
"context"
"log"
"os"
"os/signal"
"sync"
"syscall"
"testing"
"hakurei.app/container"
"hakurei.app/container/check"
"hakurei.app/internal/pkg"
"hakurei.app/internal/rosa"
"hakurei.app/message"
)
var (
// skipBuildTest caches whether build tests are skipped.
skipBuildTest bool
// buildTestCache is populated by getCache and must not be accessed directly.
buildTestCache *pkg.Cache
// buildTestCacheCancel cancels buildTestCache.
buildTestCacheCancel context.CancelFunc
// buildTestCacheOnce synchronises access to buildTestCache.
buildTestCacheOnce sync.Once
)
func TestMain(m *testing.M) {
container.TryArgv0(nil)
code := m.Run()
if buildTestCache != nil {
buildTestCacheCancel()
buildTestCache.Close()
}
os.Exit(code)
}
func getCache(t *testing.T) *pkg.Cache {
t.Helper()
const env = "ROSA_BUILD_TEST_CACHE_DIR"
if !testing.Verbose() {
t.Skip("verbose flag not set")
}
buildTestCacheOnce.Do(func() {
if p, ok := os.LookupEnv(env); !ok {
skipBuildTest = true
return
} else if a, err := check.NewAbs(p); err != nil {
t.Fatal(err)
} else {
var ctx context.Context
ctx, buildTestCacheCancel = signal.NotifyContext(context.Background(),
syscall.SIGINT, syscall.SIGTERM)
msg := message.New(log.New(os.Stderr, "rosa: ", 0))
msg.SwapVerbose(true)
if buildTestCache, err = pkg.Open(ctx, msg, 0, a); err != nil {
t.Fatal(err)
}
}
})
if skipBuildTest {
t.Skip(env + " not set")
}
return buildTestCache
}
func TestCureAll(t *testing.T) {
cache := getCache(t)
t.Parallel()
for i := range rosa.PresetEnd {
p := rosa.PArtifact(i)
meta := rosa.GetMetadata(p)
a := rosa.Std.Load(p)
t.Run(meta.Name, func(t *testing.T) {
t.Parallel()
if pathname, _, err := cache.Cure(a); err != nil {
t.Fatal(err)
} else {
t.Log(pathname)
}
})
}
}

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newRsync() pkg.Artifact { func (t Toolchain) newRsync() (pkg.Artifact, string) {
const ( const (
version = "3.4.1" version = "3.4.1"
checksum = "VBlTsBWd9z3r2-ex7GkWeWxkUc5OrlgDzikAC0pK7ufTjAJ0MbmC_N04oSVTGPiv" checksum = "VBlTsBWd9z3r2-ex7GkWeWxkUc5OrlgDzikAC0pK7ufTjAJ0MbmC_N04oSVTGPiv"
@@ -24,6 +24,16 @@ func (t Toolchain) newRsync() pkg.Artifact {
// circular dependency // circular dependency
SkipCheck: true, SkipCheck: true,
}) }), version
}
func init() {
artifactsM[Rsync] = Metadata{
f: Toolchain.newRsync,
Name: "rsync",
Description: "an open source utility that provides fast incremental file transfer",
Website: "https://rsync.samba.org/",
ID: 4217,
}
} }
func init() { artifactsF[Rsync] = Toolchain.newRsync }

View File

@@ -2,10 +2,10 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newSquashfsTools() pkg.Artifact { func (t Toolchain) newSquashfsTools() (pkg.Artifact, string) {
const ( const (
version = "4.7.4" version = "4.7.5"
checksum = "pG0E_wkRJFS6bvPYF-hTKZT-cWnvo5BbIzCDZrJZVQDgJOx2Vc3ZfNSEV7Di7cSW" checksum = "rF52wLQP-jeAmcD-48wqJcck8ZWRFwkax3T-7snaRf5EBnCQQh0YypMY9lwcivLz"
) )
return t.NewPackage("squashfs-tools", version, pkg.NewHTTPGetTar( return t.NewPackage("squashfs-tools", version, pkg.NewHTTPGetTar(
nil, "https://github.com/plougher/squashfs-tools/releases/"+ nil, "https://github.com/plougher/squashfs-tools/releases/"+
@@ -14,9 +14,8 @@ func (t Toolchain) newSquashfsTools() pkg.Artifact {
pkg.TarGzip, pkg.TarGzip,
), &PackageAttr{ ), &PackageAttr{
// uses source tree as scratch space // uses source tree as scratch space
Writable: true, Writable: true,
Chmod: true, Chmod: true,
EnterSource: true,
Env: []string{ Env: []string{
"CONFIG=1", "CONFIG=1",
@@ -26,8 +25,8 @@ func (t Toolchain) newSquashfsTools() pkg.Artifact {
"COMP_DEFAULT=zstd", "COMP_DEFAULT=zstd",
"USE_PREBUILT_MANPAGES=y", "USE_PREBUILT_MANPAGES=y",
}, },
ScriptEarly: "cd squashfs-tools",
}, &MakeHelper{ }, &MakeHelper{
SkipConfigure: true, SkipConfigure: true,
InPlace: true, InPlace: true,
@@ -39,6 +38,16 @@ func (t Toolchain) newSquashfsTools() pkg.Artifact {
Zstd, Zstd,
Gzip, Gzip,
Zlib, Zlib,
) ), version
}
func init() {
artifactsM[SquashfsTools] = Metadata{
f: Toolchain.newSquashfsTools,
Name: "squashfs-tools",
Description: "tools to create and extract Squashfs filesystems",
Website: "https://github.com/plougher/squashfs-tools",
ID: 4879,
}
} }
func init() { artifactsF[SquashfsTools] = Toolchain.newSquashfsTools }

View File

@@ -1,20 +1,22 @@
package rosa package rosa
import ( import (
"strings"
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newNSS() pkg.Artifact { func (t Toolchain) newNSS() (pkg.Artifact, string) {
const ( const (
version = "3_120" version = "3.121"
checksum = "9M0SNMrj9BJp6RH2rQnMm6bZWtP0Kgj64D5JNPHF7Cxr2_8kfy3msubIcvEPwC35" checksum = "MTS4Eg-1vBN3T7gdUAdNO0y_e9x9BE3f_k_DHdM_BIovc7y57vhsZTfB5f6BeQfi"
version0 = "4_38_2" version0 = "4_38_2"
checksum0 = "25x2uJeQnOHIiq_zj17b4sYqKgeoU8-IsySUptoPcdHZ52PohFZfGuIisBreWzx0" checksum0 = "25x2uJeQnOHIiq_zj17b4sYqKgeoU8-IsySUptoPcdHZ52PohFZfGuIisBreWzx0"
) )
return t.NewPackage("nss", version, pkg.NewHTTPGetTar( return t.NewPackage("nss", version, pkg.NewHTTPGetTar(
nil, "https://github.com/nss-dev/nss/archive/refs/tags/"+ nil, "https://github.com/nss-dev/nss/archive/refs/tags/"+
"NSS_"+version+"_RTM.tar.gz", "NSS_"+strings.Join(strings.SplitN(version, ".", 2), "_")+"_RTM.tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), &PackageAttr{ ), &PackageAttr{
@@ -63,21 +65,35 @@ cp -r \
Zlib, Zlib,
KernelHeaders, KernelHeaders,
) ), version
} }
func init() { artifactsF[NSS] = Toolchain.newNSS } func init() {
artifactsM[NSS] = Metadata{
f: Toolchain.newNSS,
func (t Toolchain) newBuildCATrust() pkg.Artifact { Name: "nss",
Description: "Network Security Services",
Website: "https://firefox-source-docs.mozilla.org/security/nss/index.html",
ID: 2503,
}
}
func init() {
const version = "0.4.0" const version = "0.4.0"
return t.newViaPip("buildcatrust", version, "none", "any", artifactsM[buildcatrust] = newViaPip(
"buildcatrust",
"transform certificate stores between formats",
version, "py3", "none", "any",
"k_FGzkRCLjbTWBkuBLzQJ1S8FPAz19neJZlMHm0t10F2Y0hElmvVwdSBRc03Rjo1", "k_FGzkRCLjbTWBkuBLzQJ1S8FPAz19neJZlMHm0t10F2Y0hElmvVwdSBRc03Rjo1",
"https://github.com/nix-community/buildcatrust/"+ "https://github.com/nix-community/buildcatrust/"+
"releases/download/v"+version+"/") "releases/download/v"+version+"/",
)
} }
func init() { artifactsF[buildcatrust] = Toolchain.newBuildCATrust }
func (t Toolchain) newNSSCACert() pkg.Artifact { func (t Toolchain) newNSSCACert() (pkg.Artifact, string) {
return t.New("nss-cacert", 0, []pkg.Artifact{ return t.New("nss-cacert", 0, []pkg.Artifact{
t.Load(Zlib),
t.Load(Bash), t.Load(Bash),
t.Load(Python), t.Load(Python),
@@ -92,6 +108,14 @@ buildcatrust \
--ca_unpacked_output /work/system/etc/ssl/certs/unbundled \ --ca_unpacked_output /work/system/etc/ssl/certs/unbundled \
--ca_hashed_unpacked_output /work/system/etc/ssl/certs/hashed \ --ca_hashed_unpacked_output /work/system/etc/ssl/certs/hashed \
--p11kit_output /work/system/etc/ssl/trust-source/ca-bundle.trust.p11-kit --p11kit_output /work/system/etc/ssl/trust-source/ca-bundle.trust.p11-kit
`) `), Unversioned
}
func init() {
artifactsM[NSSCACert] = Metadata{
f: Toolchain.newNSSCACert,
Name: "nss-cacert",
Description: "bundle of X.509 certificates of public Certificate Authorities",
Website: "https://curl.se/docs/caextract.html",
}
} }
func init() { artifactsF[NSSCACert] = Toolchain.newNSSCACert }

View File

@@ -7,7 +7,7 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newStage0() pkg.Artifact { func (t Toolchain) newStage0() (pkg.Artifact, string) {
musl, compilerRT, runtimes, clang := t.NewLLVM() musl, compilerRT, runtimes, clang := t.NewLLVM()
return t.New("rosa-stage0", 0, []pkg.Artifact{ return t.New("rosa-stage0", 0, []pkg.Artifact{
musl, musl,
@@ -15,6 +15,7 @@ func (t Toolchain) newStage0() pkg.Artifact {
runtimes, runtimes,
clang, clang,
t.Load(Zlib),
t.Load(Bzip2), t.Load(Bzip2),
t.Load(Patch), t.Load(Patch),
@@ -39,9 +40,16 @@ tar \
-C / \ -C / \
-f /work/stage0-`+triplet()+`.tar.bz2 \ -f /work/stage0-`+triplet()+`.tar.bz2 \
system bin usr/bin/env system bin usr/bin/env
`) `), Unversioned
}
func init() {
artifactsM[Stage0] = Metadata{
f: Toolchain.newStage0,
Name: "rosa-stage0",
Description: "Rosa OS stage0 toolchain tarball for bootstrap",
}
} }
func init() { artifactsF[Stage0] = Toolchain.newStage0 }
var ( var (
// stage0 stores the tarball unpack artifact. // stage0 stores the tarball unpack artifact.

View File

@@ -6,7 +6,7 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newTamaGo() pkg.Artifact { func (t Toolchain) newTamaGo() (pkg.Artifact, string) {
const ( const (
version = "1.26.0" version = "1.26.0"
checksum = "5XkfbpTpSdPJfwtTfUegfdu4LUy8nuZ7sCondiRIxTJI9eQONi8z_O_dq9yDkjw8" checksum = "5XkfbpTpSdPJfwtTfUegfdu4LUy8nuZ7sCondiRIxTJI9eQONi8z_O_dq9yDkjw8"
@@ -35,6 +35,16 @@ rm \
"tamago-go"+version+".tar.gz", "tamago-go"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
))) ))), version
}
func init() {
artifactsM[TamaGo] = Metadata{
f: Toolchain.newTamaGo,
Name: "tamago",
Description: "a Go toolchain extended with support for bare metal execution",
Website: "https://github.com/usbarmory/tamago-go",
ID: 388872,
}
} }
func init() { artifactsF[TamaGo] = Toolchain.newTamaGo }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newToybox(suffix, script string) pkg.Artifact { func (t Toolchain) newToybox(suffix, script string) (pkg.Artifact, string) {
const ( const (
version = "0.8.13" version = "0.8.13"
checksum = "rZ1V1ATDte2WeQZanxLVoiRGdfPXhMlEo5-exX-e-ml8cGn9qOv0ABEUVZpX3wTI" checksum = "rZ1V1ATDte2WeQZanxLVoiRGdfPXhMlEo5-exX-e-ml8cGn9qOv0ABEUVZpX3wTI"
@@ -56,15 +56,24 @@ ln -s ../../system/bin/env /work/usr/bin
Gzip, Gzip,
KernelHeaders, KernelHeaders,
) ), version
} }
func init() { func init() {
artifactsF[Toybox] = func(t Toolchain) pkg.Artifact { artifactsM[Toybox] = Metadata{
return t.newToybox("", "") f: func(t Toolchain) (pkg.Artifact, string) {
return t.newToybox("", "")
},
Name: "toybox",
Description: "many common Linux command line utilities",
Website: "https://landley.net/toybox/",
ID: 13818,
} }
artifactsF[toyboxEarly] = func(t Toolchain) pkg.Artifact { artifactsM[toyboxEarly] = Metadata{
return t.newToybox("-early", ` f: func(t Toolchain) (pkg.Artifact, string) {
return t.newToybox("-early", `
echo ' echo '
CONFIG_EXPR=y CONFIG_EXPR=y
CONFIG_TR=y CONFIG_TR=y
@@ -72,5 +81,10 @@ CONFIG_AWK=y
CONFIG_DIFF=y CONFIG_DIFF=y
' >> .config ' >> .config
`) `)
},
Name: "toybox-early",
Description: "a build of toybox with unfinished tools enabled to break dependency loops",
Website: "https://landley.net/toybox/",
} }
} }

View File

@@ -6,7 +6,7 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newUnzip() pkg.Artifact { func (t Toolchain) newUnzip() (pkg.Artifact, string) {
const ( const (
version = "6.0" version = "6.0"
checksum = "fcqjB1IOVRNJ16K5gTGEDt3zCJDVBc7EDSra9w3H93stqkNwH1vaPQs_QGOpQZu1" checksum = "fcqjB1IOVRNJ16K5gTGEDt3zCJDVBc7EDSra9w3H93stqkNwH1vaPQs_QGOpQZu1"
@@ -29,6 +29,16 @@ mv unzip /work/system/bin/
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), false, ), false,
))) ))), version
}
func init() {
artifactsM[Unzip] = Metadata{
f: Toolchain.newUnzip,
Name: "unzip",
Description: "portable compression/archiver utilities",
Website: "https://infozip.sourceforge.net/",
ID: 8684,
}
} }
func init() { artifactsF[Unzip] = Toolchain.newUnzip }

View File

@@ -6,7 +6,7 @@ import (
"hakurei.app/internal/pkg" "hakurei.app/internal/pkg"
) )
func (t Toolchain) newUtilLinux() pkg.Artifact { func (t Toolchain) newUtilLinux() (pkg.Artifact, string) {
const ( const (
version = "2.41.3" version = "2.41.3"
checksum = "gPTd5JJ2ho_Rd0qainuogcLiiWwKSXEZPXN3yCCRl0m0KBgMaqwFuMjYgu9z8zCH" checksum = "gPTd5JJ2ho_Rd0qainuogcLiiWwKSXEZPXN3yCCRl0m0KBgMaqwFuMjYgu9z8zCH"
@@ -44,6 +44,19 @@ ln -s ../system/bin/bash /bin/
Bash, Bash,
KernelHeaders, KernelHeaders,
) ), version
}
func init() {
artifactsM[UtilLinux] = Metadata{
f: Toolchain.newUtilLinux,
Name: "util-linux",
Description: "a random collection of Linux utilities",
Website: "https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git",
ID: 8179,
// release candidates confuse Anitya
latest: (*Versions).getStable,
}
} }
func init() { artifactsF[UtilLinux] = Toolchain.newUtilLinux }

View File

@@ -2,10 +2,10 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newWayland() pkg.Artifact { func (t Toolchain) newWayland() (pkg.Artifact, string) {
const ( const (
version = "1.24.0" version = "1.24.91"
checksum = "JxgLiFRRGw2D3uhVw8ZeDbs3V7K_d4z_ypDog2LBqiA_5y2vVbUAk5NT6D5ozm0m" checksum = "SQkjYShk2TutoBOfmeJcdLU9iDExVKOg0DZhLeL8U_qjc9olLTC7h3vuUBvVtx9w"
) )
return t.NewPackage("wayland", version, pkg.NewHTTPGetTar( return t.NewPackage("wayland", version, pkg.NewHTTPGetTar(
nil, "https://gitlab.freedesktop.org/wayland/wayland/"+ nil, "https://gitlab.freedesktop.org/wayland/wayland/"+
@@ -32,11 +32,21 @@ echo 'int main(){}' > tests/sanity-test.c
Libffi, Libffi,
Libexpat, Libexpat,
Libxml2, Libxml2,
) ), version
} }
func init() { artifactsF[Wayland] = Toolchain.newWayland } func init() {
artifactsM[Wayland] = Metadata{
f: Toolchain.newWayland,
func (t Toolchain) newWaylandProtocols() pkg.Artifact { Name: "wayland",
Description: "core Wayland window system code and protocol",
Website: "https://wayland.freedesktop.org/",
ID: 10061,
}
}
func (t Toolchain) newWaylandProtocols() (pkg.Artifact, string) {
const ( const (
version = "1.47" version = "1.47"
checksum = "B_NodZ7AQfCstcx7kgbaVjpkYOzbAQq0a4NOk-SA8bQixAE20FY3p1-6gsbPgHn9" checksum = "B_NodZ7AQfCstcx7kgbaVjpkYOzbAQq0a4NOk-SA8bQixAE20FY3p1-6gsbPgHn9"
@@ -105,6 +115,16 @@ GitLab
Libffi, Libffi,
Libexpat, Libexpat,
Libxml2, Libxml2,
) ), version
}
func init() {
artifactsM[WaylandProtocols] = Metadata{
f: Toolchain.newWaylandProtocols,
Name: "wayland-protocols",
Description: "Additional standard Wayland protocols",
Website: "https://wayland.freedesktop.org/",
ID: 13997,
}
} }
func init() { artifactsF[WaylandProtocols] = Toolchain.newWaylandProtocols }

View File

@@ -2,27 +2,37 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newUtilMacros() pkg.Artifact { func (t Toolchain) newUtilMacros() (pkg.Artifact, string) {
const ( const (
version = "1.17" version = "1.20.2"
checksum = "vYPO4Qq3B_WGcsBjG0-lfwZ6DZ7ayyrOLqfDrVOgTDcyLChuMGOAAVAa_UXLu5tD" checksum = "Ze8QH3Z3emC0pWFP-0nUYeMy7aBW3L_dxBBmVgcumIHNzEKc1iGTR-yUFR3JcM1G"
) )
return t.NewPackage("util-macros", version, pkg.NewHTTPGetTar( return t.NewPackage("util-macros", version, pkg.NewHTTPGetTar(
nil, "https://www.x.org/releases/X11R7.7/src/util/"+ nil, "https://www.x.org/releases/individual/util/"+
"util-macros-"+version+".tar.bz2", "util-macros-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarBzip2, pkg.TarGzip,
), nil, (*MakeHelper)(nil)) ), nil, (*MakeHelper)(nil)), version
} }
func init() { artifactsF[utilMacros] = Toolchain.newUtilMacros } func init() {
artifactsM[utilMacros] = Metadata{
f: Toolchain.newUtilMacros,
func (t Toolchain) newXproto() pkg.Artifact { Name: "util-macros",
Description: "X.Org Autotools macros",
Website: "https://xorg.freedesktop.org/",
ID: 5252,
}
}
func (t Toolchain) newXproto() (pkg.Artifact, string) {
const ( const (
version = "7.0.23" version = "7.0.31"
checksum = "goxwWxV0jZ_3pNczXFltZWHAhq92x-aEreUGyp5Ns8dBOoOmgbpeNIu1nv0Zx07z" checksum = "Cm69urWY5RctKpR78eGzuwrjDEfXGkvHRdodj6sjypOGy5FF4-lmnUttVHYV1ydg"
) )
return t.NewPackage("xproto", version, pkg.NewHTTPGetTar( return t.NewPackage("xproto", version, pkg.NewHTTPGetTar(
nil, "https://www.x.org/releases/X11R7.7/src/proto/"+ nil, "https://www.x.org/releases/individual/proto/"+
"xproto-"+version+".tar.bz2", "xproto-"+version+".tar.bz2",
mustDecode(checksum), mustDecode(checksum),
pkg.TarBzip2, pkg.TarBzip2,
@@ -37,20 +47,30 @@ func (t Toolchain) newXproto() pkg.Artifact {
PkgConfig, PkgConfig,
utilMacros, utilMacros,
) ), version
} }
func init() { artifactsF[Xproto] = Toolchain.newXproto } func init() {
artifactsM[Xproto] = Metadata{
f: Toolchain.newXproto,
func (t Toolchain) newLibXau() pkg.Artifact { Name: "xproto",
Description: "X Window System unified protocol definitions",
Website: "https://gitlab.freedesktop.org/xorg/proto/xorgproto",
ID: 13650,
}
}
func (t Toolchain) newLibXau() (pkg.Artifact, string) {
const ( const (
version = "1.0.7" version = "1.0.12"
checksum = "bm768RoZZnHRe9VjNU1Dw3BhfE60DyS9D_bgSR-JLkEEyUWT_Hb_lQripxrXto8j" checksum = "G9AjnU_C160q814MCdjFOVt_mQz_pIt4wf4GNOQmGJS3UuuyMw53sfPvJ7WOqwXN"
) )
return t.NewPackage("libXau", version, pkg.NewHTTPGetTar( return t.NewPackage("libXau", version, pkg.NewHTTPGetTar(
nil, "https://www.x.org/releases/X11R7.7/src/lib/"+ nil, "https://www.x.org/releases/individual/lib/"+
"libXau-"+version+".tar.bz2", "libXau-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarBzip2, pkg.TarGzip,
), nil, &MakeHelper{ ), nil, &MakeHelper{
// ancient configure script // ancient configure script
Generate: "autoreconf -if", Generate: "autoreconf -if",
@@ -64,6 +84,16 @@ func (t Toolchain) newLibXau() pkg.Artifact {
utilMacros, utilMacros,
Xproto, Xproto,
) ), version
}
func init() {
artifactsM[LibXau] = Metadata{
f: Toolchain.newLibXau,
Name: "libXau",
Description: "functions for handling Xauthority files and entries",
Website: "https://gitlab.freedesktop.org/xorg/lib/libxau",
ID: 1765,
}
} }
func init() { artifactsF[LibXau] = Toolchain.newLibXau }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newXCBProto() pkg.Artifact { func (t Toolchain) newXCBProto() (pkg.Artifact, string) {
const ( const (
version = "1.17.0" version = "1.17.0"
checksum = "_NtbKaJ_iyT7XiJz25mXQ7y-niTzE8sHPvLXZPcqtNoV_-vTzqkezJ8Hp2U1enCv" checksum = "_NtbKaJ_iyT7XiJz25mXQ7y-niTzE8sHPvLXZPcqtNoV_-vTzqkezJ8Hp2U1enCv"
@@ -13,11 +13,21 @@ func (t Toolchain) newXCBProto() pkg.Artifact {
pkg.TarGzip, pkg.TarGzip,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
Python, Python,
) ), version
} }
func init() { artifactsF[XCBProto] = Toolchain.newXCBProto } func init() {
artifactsM[XCBProto] = Metadata{
f: Toolchain.newXCBProto,
func (t Toolchain) newXCB() pkg.Artifact { Name: "xcb-proto",
Description: "XML-XCB protocol descriptions used by libxcb for the X11 protocol & extensions",
Website: "https://gitlab.freedesktop.org/xorg/proto/xcbproto",
ID: 13646,
}
}
func (t Toolchain) newXCB() (pkg.Artifact, string) {
const ( const (
version = "1.17.0" version = "1.17.0"
checksum = "hjjsc79LpWM_hZjNWbDDS6qRQUXREjjekS6UbUsDq-RR1_AjgNDxhRvZf-1_kzDd" checksum = "hjjsc79LpWM_hZjNWbDDS6qRQUXREjjekS6UbUsDq-RR1_AjgNDxhRvZf-1_kzDd"
@@ -33,6 +43,16 @@ func (t Toolchain) newXCB() pkg.Artifact {
XCBProto, XCBProto,
Xproto, Xproto,
LibXau, LibXau,
) ), version
}
func init() {
artifactsM[XCB] = Metadata{
f: Toolchain.newXCB,
Name: "xcb",
Description: "The X protocol C-language Binding",
Website: "https://xcb.freedesktop.org/",
ID: 1767,
}
} }
func init() { artifactsF[XCB] = Toolchain.newXCB }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newXZ() pkg.Artifact { func (t Toolchain) newXZ() (pkg.Artifact, string) {
const ( const (
version = "5.8.2" version = "5.8.2"
checksum = "rXT-XCp9R2q6cXqJ5qenp0cmGPfiENQiU3BWtUVeVgArfRmSsISeUJgvCR3zI0a0" checksum = "rXT-XCp9R2q6cXqJ5qenp0cmGPfiENQiU3BWtUVeVgArfRmSsISeUJgvCR3zI0a0"
@@ -14,6 +14,16 @@ func (t Toolchain) newXZ() pkg.Artifact {
pkg.TarBzip2, pkg.TarBzip2,
), nil, (*MakeHelper)(nil), ), nil, (*MakeHelper)(nil),
Diffutils, Diffutils,
) ), version
}
func init() {
artifactsM[XZ] = Metadata{
f: Toolchain.newXZ,
Name: "xz",
Description: "XZ Utils",
Website: "https://tukaani.org/xz/",
ID: 5277,
}
} }
func init() { artifactsF[XZ] = Toolchain.newXZ }

View File

@@ -2,24 +2,40 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newZlib() pkg.Artifact { func (t Toolchain) newZlib() (pkg.Artifact, string) {
const ( const (
version = "1.3.1" version = "1.3.2"
checksum = "E-eIpNzE8oJ5DsqH4UuA_0GDKuQF5csqI8ooDx2w7Vx-woJ2mb-YtSbEyIMN44mH" checksum = "KHZrePe42vL2XvOUE3KlJkp1UgWhWkl0jjT_BOvFhuM4GzieEH9S7CioepOFVGYB"
) )
return t.NewPackage("zlib", version, pkg.NewHTTPGetTar( return t.NewPackage("zlib", version, pkg.NewHTTPGetTar(
nil, "https://zlib.net/zlib-"+version+".tar.gz", nil, "https://www.zlib.net/fossils/zlib-"+version+".tar.gz",
mustDecode(checksum), mustDecode(checksum),
pkg.TarGzip, pkg.TarGzip,
), &PackageAttr{ ), nil, &CMakeHelper{
Env: []string{ Cache: [][2]string{
"CC=clang -fPIC", {"CMAKE_BUILD_TYPE", "Release"},
},
}, &MakeHelper{
OmitDefaults: true,
Host: `""`, {"ZLIB_BUILD_TESTING", "OFF"},
Build: `""`, {"ZLIB_BUILD_SHARED", "ON"},
}) {"ZLIB_BUILD_STATIC", "ON"},
{"ZLIB_BUILD_MINIZIP", "OFF"},
{"ZLIB_INSTALL", "ON"},
{"ZLIB_PREFIX", "OFF"},
},
// ninja dependency loop
Make: true,
}), version
}
func init() {
artifactsM[Zlib] = Metadata{
f: Toolchain.newZlib,
Name: "zlib",
Description: "lossless data-compression library",
Website: "https://zlib.net/",
ID: 5303,
}
} }
func init() { artifactsF[Zlib] = Toolchain.newZlib }

View File

@@ -2,7 +2,7 @@ package rosa
import "hakurei.app/internal/pkg" import "hakurei.app/internal/pkg"
func (t Toolchain) newZstd() pkg.Artifact { func (t Toolchain) newZstd() (pkg.Artifact, string) {
const ( const (
version = "1.5.7" version = "1.5.7"
checksum = "4XhfR7DwVkwo1R-TmYDAJOcx9YXv9WSFhcFUe3hWEAMmdMLPhFaznCqYIA19_xxV" checksum = "4XhfR7DwVkwo1R-TmYDAJOcx9YXv9WSFhcFUe3hWEAMmdMLPhFaznCqYIA19_xxV"
@@ -16,8 +16,17 @@ func (t Toolchain) newZstd() pkg.Artifact {
Append: []string{"build", "cmake"}, Append: []string{"build", "cmake"},
Cache: [][2]string{ Cache: [][2]string{
{"CMAKE_BUILD_TYPE", "Release"}, {"CMAKE_BUILD_TYPE", "Release"},
{"CMAKE_INSTALL_LIBDIR", "lib"},
}, },
}) }), version
}
func init() {
artifactsM[Zstd] = Metadata{
f: Toolchain.newZstd,
Name: "zstd",
Description: "a fast compression algorithm",
Website: "https://facebook.github.io/zstd/",
ID: 12083,
}
} }
func init() { artifactsF[Zstd] = Toolchain.newZstd }

View File

@@ -35,7 +35,7 @@ package
*Default:* *Default:*
` <derivation hakurei-static-x86_64-unknown-linux-musl-0.3.5> ` ` <derivation hakurei-static-x86_64-unknown-linux-musl-0.3.6> `
@@ -805,7 +805,7 @@ package
*Default:* *Default:*
` <derivation hakurei-hsu-0.3.5> ` ` <derivation hakurei-hsu-0.3.6> `

View File

@@ -30,7 +30,7 @@
buildGoModule rec { buildGoModule rec {
pname = "hakurei"; pname = "hakurei";
version = "0.3.5"; version = "0.3.6";
srcFiltered = builtins.path { srcFiltered = builtins.path {
name = "${pname}-src"; name = "${pname}-src";