6 Commits

Author SHA1 Message Date
marv7000 f51dab51db shit 2026-06-02 21:38:47 +02:00
marv7000 d3c949b8a2 profile changes 2026-05-30 23:09:34 +02:00
Marvin Friedrich afb13bb8ad build_deps 2026-05-30 19:18:25 +02:00
marv7000 fc97bc4bb2 bash: Fix build 2026-05-26 23:55:28 +02:00
marv7000 3253dfe87b host-llvm: Fix recipe 2026-05-26 23:55:18 +02:00
marv7000 b6e18c474e *: Switch to python 2026-05-26 03:06:26 +02:00
125 changed files with 17424 additions and 3441 deletions
+5 -2
View File
@@ -1,2 +1,5 @@
/target
/build
__pycache__/
/cache
/build*
/sources
/sysroot
Generated
-1814
View File
File diff suppressed because it is too large Load Diff
-15
View File
@@ -1,15 +0,0 @@
[package]
name = "builder"
version = "0.1.0"
edition = "2024"
[dependencies]
allocative = "0.3.4"
anyhow = "1.0.102"
clap = { version = "4.6.1", features = ["derive"] }
either = "1.16.0"
petgraph = "0.8.3"
smallvec = "1.15.1"
starlark = "0.13.0"
starlark_derive = "0.13.0"
thiserror = "2.0.18"
+67
View File
@@ -0,0 +1,67 @@
FROM alpine:edge
RUN mkdir -p /sources /build /pkgs /sysroot /dest /tools /files
RUN apk add --no-cache \
apk-tools \
build-base \
bash \
patch \
tar \
xz \
zstd \
file \
findutils \
coreutils \
diffutils \
grep \
sed \
gawk \
musl-dev \
linux-headers \
gmp-dev \
mpfr-dev \
mpc1-dev \
isl-dev \
zlib-dev \
git \
pkgconf \
kmod \
patchelf \
gperf \
python3 \
python3-dev \
py3-mako \
py3-yaml \
py3-packaging \
py3-docutils \
py3-passlib \
perl \
m4 \
libtool \
gettext-dev \
bison \
flex \
which \
ca-certificates \
rsync \
mtools \
nasm \
cmake \
ninja \
meson \
glslang \
py3-jinja2 \
wayland-dev \
wayland-protocols \
glib-dev \
elfutils-dev \
libffi-dev \
expat-dev \
libxml2-dev \
pcre2-dev \
openssl-dev \
openssl \
ncurses
WORKDIR /build
-64
View File
@@ -1,64 +0,0 @@
arch = "x86_64"
libc = "glibc"
if libc == "glibc":
env = "gnu"
elif libc == "musl":
env = "musl"
else:
fail(f"Unknown libc: {libc}")
prefix = path("/usr")
host_cflags = ["-O2", "-pipe"]
host_cxxflags = host_cflags + []
host_ldflags = ["-Wl,-O1", "-Wl,--sort-common", "-Wl,--as-needed"]
target_cflags = host_cflags + []
target_cxxflags = host_cxxflags + []
target_ldflags = host_ldflags + ["-Wl,-z,now"]
if arch == "x86_64":
flags = [
"-march=x86-64-v3",
"-mtune=generic",
"-fstack-clash-protection",
"-fstack-protector-strong",
"-fcf-protection",
]
target_cflags += flags
target_cxxflags += flags
target_ldflags += ["-Wl,-z,pack-relative-relocs"]
config(
arch = arch,
recipes_dir = path("./recipes"),
host_recipes_dir = path("./host-recipes"),
container = podman(
image = "local/builder:latest",
dockerfile = path("./Dockerfile"),
),
target_arch = arch,
target_triple = f"{arch}-orchid-linux-{env}",
libc = libc,
prefix = prefix,
bindir = prefix / "bin",
sbindir = prefix / "bin",
libdir = prefix / "lib",
libexecdir = prefix / "libexec",
includedir = prefix / "include",
sysconfdir = path("/etc"),
localstatedir = path("/var"),
host_cflags = " ".join(host_cflags),
host_cxxflags = " ".join(host_cxxflags),
host_ldflags = " ".join(host_ldflags),
cflags = " ".join(target_cflags),
cxxflags = " ".join(target_cxxflags),
ldflags = " ".join(target_ldflags),
)
+21
View File
@@ -0,0 +1,21 @@
version = "2.72"
revision = 1
description = "GNU autoconf"
license = "GPL-3.0-or-later"
url = "https://www.gnu.org/software/autoconf/"
source = tarball(
url=f"https://ftp.gnu.org/gnu/autoconf/autoconf-{version}.tar.xz",
sha256="ba885c1319578d6c94d46e9b0dceb4014caafe2490e437a0dbca3f270a223f5a",
)
def configure(self):
self.run(self.source_dir / "configure", f"--prefix={self.prefix}")
def build(self):
autotools_build(self)
def install(self):
autotools_install(self)
+22
View File
@@ -0,0 +1,22 @@
version = "1.17"
revision = 1
description = "GNU automake"
license = "GPL-2.0-or-later"
url = "https://www.gnu.org/software/automake/"
source = tarball(
url=f"https://ftp.gnu.org/gnu/automake/automake-{version}.tar.xz",
sha256="8920c1fc411e13b90bf704ef9db6f29d540e76d232cb3b2c9f4dc4cc599bd990",
)
host_deps = ["autoconf"]
def configure(self):
self.run(self.source_dir / "configure", f"--prefix={self.prefix}")
def build(self):
autotools_build(self)
def install(self):
autotools_install(self)
+39
View File
@@ -0,0 +1,39 @@
version = "2.46.0"
revision = 1
description = "GNU binutils cross-compiled for the target triple"
license = "GPL-3.0-or-later"
source = tarball(
url=f"https://ftp.gnu.org/gnu/binutils/binutils-{version}.tar.xz",
sha256="d75a94f4d73e7a4086f7513e67e439e8fcdcbb726ffe63f4661744e6256b2cf2",
)
def configure(self):
self.run(
self.source_dir / "configure",
f"--prefix={self.prefix}",
f"--target={self.triple}",
f"--with-sysroot={self.sysroot}",
"--with-pic",
"--enable-cet",
"--enable-default-execstack=no",
"--enable-deterministic-archives",
"--enable-ld=default",
"--enable-new-dtags",
"--enable-plugins",
"--enable-relro",
"--enable-separate-code",
"--enable-threads",
"--disable-nls",
"--disable-werror",
# gprofng's libcollector relies on glibc-specific internals.
"--disable-gprofng",
env={
"CFLAGS": self.profile["host_cflags"],
"CXXFLAGS": self.profile["host_cxxflags"],
"LDFLAGS": self.profile["host_ldflags"],
},
)
_, build, install = autotools()
-39
View File
@@ -1,39 +0,0 @@
version = "2.46.0"
revision = 1
metadata = meta(
description = "GNU binutils cross-compiled for the target triple",
license = "GPL-3.0-or-later",
)
source = tarball(
url = f"https://ftp.gnu.org/gnu/binutils/binutils-{version}.tar.xz",
sha256 = "d75a94f4d73e7a4086f7513e67e439e8fcdcbb726ffe63f4661744e6256b2cf2",
strip_components = 1,
)
def configure(ctx):
ctx.run(
ctx.source_dir / "configure",
"--prefix=" + options.prefix,
"--target=" + options.target_triple,
"--with-sysroot=" + ctx.sysroot_dir,
"--with-pic",
"--enable-cet",
"--enable-default-execstack=no",
"--enable-deterministic-archives",
"--enable-ld=default",
"--enable-new-dtags",
"--enable-plugins",
"--enable-relro",
"--enable-separate-code",
"--enable-threads",
"--disable-nls",
"--disable-werror",
# gprofng's libcollector relies on glibc-specific internals.
"--disable-gprofng",
env = {
"CFLAGS": options.host_cflags,
"CXXFLAGS": options.host_cxxflags,
"LDFLAGS": options.host_ldflags,
})
_, build, install = autotools()
+47
View File
@@ -0,0 +1,47 @@
version = "16.1.0"
revision = 1
description = "GNU GCC cross-compiler (bootstrap stage, C/C++ only)"
license = "GPL-3.0-or-later"
source = tarball(
url=f"https://ftp.gnu.org/gnu/gcc/gcc-{version}/gcc-{version}.tar.xz",
sha256="50efb4d94c3397aff3b0d61a5abd748b4dd31d9d3f2ab7be05b171d36a510f79",
)
host_deps = ["binutils"]
def configure(self):
self.run(
self.source_dir / "configure",
f"--target={self.triple}",
f"--prefix={self.prefix}",
f"--with-sysroot={self.sysroot}",
"--without-headers",
"--with-newlib",
"--enable-languages=c,c++",
"--enable-default-pie",
"--enable-default-ssp",
"--disable-nls",
"--disable-shared",
"--disable-threads",
"--disable-libssp",
"--disable-libgomp",
"--disable-libquadmath",
"--disable-libatomic",
"--disable-libvtv",
"--disable-multilib",
env={
"CFLAGS": self.profile["host_cflags"],
"CXXFLAGS": self.profile["host_cxxflags"],
"LDFLAGS": self.profile["host_ldflags"],
},
)
def build(self):
self.run("make", f"-j{self.jobs}", "all-gcc")
self.run("make", f"-j{self.jobs}", "all-target-libgcc")
def install(self):
self.run("make", "install-gcc", env={"DESTDIR": str(self.dest_dir)})
self.run("make", "install-target-libgcc", env={"DESTDIR": str(self.dest_dir)})
+54
View File
@@ -0,0 +1,54 @@
version = "16.1.0"
revision = 1
description = "GNU GCC cross-compiler targeting the system triple"
license = "GPL-3.0-or-later"
url = "https://gcc.gnu.org/"
source = tarball(
url=f"https://ftp.gnu.org/gnu/gcc/gcc-{version}/gcc-{version}.tar.xz",
sha256="50efb4d94c3397aff3b0d61a5abd748b4dd31d9d3f2ab7be05b171d36a510f79",
)
host_deps = ["binutils", "gcc-bootstrap"]
deps = [profile["libc"], "linux-headers"]
def configure(self):
self.run(
self.source_dir / "configure",
f"--target={self.triple}",
f"--prefix={self.prefix}",
f"--with-sysroot={self.sysroot}",
f"--with-build-sysroot={self.sysroot}",
f"--with-gxx-include-dir={self.sysroot}{self.profile['includedir']}/c++/{version}",
"--enable-languages=c,c++,lto",
"--disable-bootstrap",
"--enable-default-pie",
"--enable-default-ssp",
"--enable-lto",
"--enable-threads=posix",
"--enable-tls",
"--enable-libstdcxx-time",
"--enable-checking=release",
"--enable-cet=auto",
"--enable-linker-build-id",
"--disable-nls",
"--disable-multilib",
"--disable-fixed-point",
"--disable-werror",
"--disable-libsanitizer",
"--disable-symvers",
env={
"CFLAGS": self.profile["host_cflags"],
"CXXFLAGS": self.profile["host_cxxflags"],
"LDFLAGS": self.profile["host_ldflags"],
},
)
def build(self):
self.run("make", f"-j{self.jobs}")
def install(self):
self.run("make", "install-strip", env={"DESTDIR": str(self.dest_dir)})
# Drop libtool archives.
self.run("find", self.dest_dir, "-name", "*.la", "-delete")
+47
View File
@@ -0,0 +1,47 @@
version = "22.1.6"
revision = 1
description = "LLVM compiler infrastructure with clang and lld"
license = "Apache-2.0 WITH LLVM-exception"
url = "https://llvm.org/"
source = tarball(
url=f"https://github.com/llvm/llvm-project/releases/download/llvmorg-{version}/llvm-project-{version}.src.tar.xz",
sha256="4579051e3c255fb4bb795d54324f5a7f3ef79bd9181e44293d7ee9a7f62aad9a",
)
host_deps = ["binutils"]
def configure(self):
self.run(
"cmake",
"-S",
self.source_dir / "llvm",
"-B",
self.build_dir,
"-GNinja",
f"-DDEFAULT_SYSROOT={self.sysroot}",
f"-DCMAKE_INSTALL_PREFIX={self.prefix}",
"-UBUILD_SHARED_LIBS",
"-UENABLE_STATIC",
"-DCMAKE_BUILD_TYPE=Release",
"-DLLVM_LINK_LLVM_DYLIB=ON",
"-DLLVM_ENABLE_FFI=ON",
"-DLLVM_ENABLE_EH=ON",
"-DLLVM_ENABLE_RTTI=ON",
"-DLLVM_ENABLE_PROJECTS=clang;lld;clang-tools-extra",
f"-DLLVM_DEFAULT_TARGET_TRIPLE={self.triple}",
f"-DLLVM_HOST_TRIPLE={self.triple}",
"-Wno-dev",
env={
"CFLAGS": self.profile["host_cflags"],
"CXXFLAGS": self.profile["host_cxxflags"],
"LDFLAGS": self.profile["host_ldflags"],
},
)
def build(self):
self.run("cmake", "--build", self.build_dir, f"-j{self.jobs}")
def install(self):
self.run("cmake", "--install", self.build_dir, env={"DESTDIR": str(self.dest_dir)})
+50
View File
@@ -0,0 +1,50 @@
version = "2.5.1"
revision = 1
description = "Lightweight pkg-config implementation (cross host build)"
license = "ISC"
url = "http://pkgconf.org/"
source = tarball(
url=f"https://distfiles.ariadne.space/pkgconf/pkgconf-{version}.tar.xz",
sha256="cd05c9589b9f86ecf044c10a2269822bc9eb001eced2582cfffd658b0a50c243",
)
host_deps = ["autoconf", "automake", "binutils", "gcc"]
def configure(self):
self.run(
self.source_dir / "configure",
f"--prefix={self.prefix}",
"--with-system-libdir=/usr/lib",
"--with-system-includedir=/usr/include",
env={
"CFLAGS": self.profile["host_cflags"],
"LDFLAGS": self.profile["host_ldflags"],
},
)
def build(self):
autotools_build(self)
def install(self):
autotools_install(self)
triple = self.triple
bindir = f"{self.dest_dir}{self.prefix}/bin"
persdir = f"{self.dest_dir}{self.prefix}/share/pkgconfig/personality.d"
personality = f"""Triplet: {triple}
SysrootDir: /sysroot
DefaultSearchPaths: /sysroot/usr/lib/pkgconfig:/sysroot/usr/share/pkgconfig
SystemIncludePaths: /sysroot/usr/include
SystemLibraryPaths: /sysroot/usr/lib
"""
self.run(
"sh",
"-c",
f"set -e; "
f"mkdir -p {persdir}; "
f"cat > {persdir}/{triple}.personality <<'__EOF__'\n{personality}__EOF__\n"
f"ln -sf pkgconf {bindir}/{triple}-pkgconf; "
f"ln -sf pkgconf {bindir}/{triple}-pkg-config",
)
Symlink
+1
View File
@@ -0,0 +1 @@
src/__main__.py
+23
View File
@@ -0,0 +1,23 @@
def profile(base):
# The base profile supplies defaults for every other profile, so it has no
# parent of its own (``base`` is None here). It deliberately omits the
# target-identifying core fields (arch/triple/libc); concrete profiles must
# provide those.
return Profile(
container_image="localhost/orchid-builder:latest",
options={
# Install layout (where files land in the target system).
"prefix": "/usr",
"bindir": "/usr/bin",
"sbindir": "/usr/bin",
"libdir": "/usr/lib",
"libexecdir": "/usr/libexec",
"includedir": "/usr/include",
"sysconfdir": "/etc",
"localstatedir": "/var",
# Flags for tools built to run on the build machine (host).
"host_cflags": "-O2 -pipe",
"host_cxxflags": "-O2 -pipe",
"host_ldflags": "-Wl,-O1 -Wl,--sort-common -Wl,--as-needed",
},
)
+17
View File
@@ -0,0 +1,17 @@
def profile(base):
arch = "x86_64"
target_flags = (
"-march=x86-64-v3 -mtune=generic -fstack-clash-protection "
"-fstack-protector-strong -fcf-protection"
)
return Profile(
arch=arch,
triple=f"{arch}-orchid-linux-gnu",
options={
"libc": "glibc",
# Target flags build on the base host flags.
"cflags": f"{base['host_cflags']} {target_flags}",
"cxxflags": f"{base['host_cflags']} {target_flags}",
"ldflags": f"{base['host_ldflags']} -Wl,-z,now -Wl,-z,pack-relative-relocs",
},
)
+18
View File
@@ -0,0 +1,18 @@
def profile(base):
arch = "x86_64"
libc = "musl"
target_flags = (
"-march=x86-64-v3 -mtune=generic -fstack-clash-protection "
"-fstack-protector-strong -fcf-protection"
)
return Profile(
arch=arch,
triple=f"{arch}-orchid-linux-{libc}",
options={
"libc": libc,
# Target flags build on the base host flags.
"cflags": f"{base['host_cflags']} {target_flags}",
"cxxflags": f"{base['host_cflags']} {target_flags}",
"ldflags": f"{base['host_ldflags']} -Wl,-z,now -Wl,-z,pack-relative-relocs",
},
)
+6
View File
@@ -0,0 +1,6 @@
{
"ignore": [
"recipes",
"host-recipes"
]
}
+7
View File
@@ -0,0 +1,7 @@
# <file system> <dir> <type> <options> <dump> <pass>
proc /proc proc nosuid,noexec,nodev 0 0
sysfs /sys sysfs nosuid,noexec,nodev 0 0
devtmpfs /dev devtmpfs nosuid 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /run tmpfs nosuid,nodev 0 0
tmpfs /dev/shm tmpfs nosuid,nodev 0 0
+12
View File
@@ -0,0 +1,12 @@
root:x:0:
tty:x:5:user
disk:x:6:
kmem:x:9:
wheel:x:10:user
kvm:x:24:user
video:x:27:user
input:x:28:user
seat:x:29:user
render:x:30:user
nobody:x:65534:
user:x:1000:
+1
View File
@@ -0,0 +1 @@
orchid
+3
View File
@@ -0,0 +1,3 @@
/lib
/usr/lib
/usr/lib64
+5
View File
@@ -0,0 +1,5 @@
NAME="Orchid"
PRETTY_NAME="Orchid Linux"
ID=orchid
ANSI_COLOR="0;35"
HOME_URL="https://example.invalid/"
+3
View File
@@ -0,0 +1,3 @@
root:x:0:0:root:/root:/bin/bash
user:x:1000:1000:Orchid User:/home/user:/bin/bash
nobody:x:65534:65534:Nobody:/:/usr/bin/nologin
+9
View File
@@ -0,0 +1,9 @@
# System-wide shell profile (POSIX sh / bash login shells).
export PATH=/usr/local/bin:/usr/bin:/bin
export PAGER=less
umask 022
for _f in /etc/profile.d/*.sh; do
[ -r "$_f" ] && . "$_f"
done
unset _f
@@ -0,0 +1,12 @@
# Launch Weston automatically after autologin on the first VT.
# seatd (running as a service) grants access to DRM/input devices, and
# XDG_RUNTIME_DIR is created here since there is no logind to do it.
if [ "$(tty)" = "/dev/tty1" ] && [ -z "${WAYLAND_DISPLAY:-}" ] && [ -z "${DISPLAY:-}" ]; then
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
if [ ! -d "$XDG_RUNTIME_DIR" ]; then
mkdir -p "$XDG_RUNTIME_DIR"
fi
chmod 0700 "$XDG_RUNTIME_DIR"
export XDG_SESSION_TYPE=wayland
exec weston
fi
+3
View File
@@ -0,0 +1,3 @@
root:!:19700:0:99999:7:::
user::19700:0:99999:7:::
nobody:!:19700:0:99999:7:::
@@ -0,0 +1,16 @@
[core]
idle-time=0
require-input=false
xwayland=false
[shell]
background-color=0xff1e1e2e
panel-position=top
locking=false
[keyboard]
keymap_layout=us
[terminal]
font=DejaVu Sans Mono
font-size=14
+41
View File
@@ -0,0 +1,41 @@
version = "0.1"
revision = 1
description = "Base filesystem layout, accounts and system configuration"
license = "MIT"
url = "https://example.invalid/"
# Config-only package: no upstream source, just static files + an install phase.
# Install the full target set (`orchid install <dest>`) to get a bootable system;
# this package supplies the glue (accounts, fstab, /sbin/init, weston.ini).
host_deps = []
# bash provides the system shell; base-files points /usr/bin/sh at it.
deps = ["bash"]
def install(self):
d = self.dest_dir
self.run(
"sh",
"-c",
"set -e; "
f"install -d -m0755 '{d}/etc' '{d}/etc/profile.d' '{d}/etc/xdg/weston' "
f"'{d}/etc/udev/rules.d' '{d}/sbin' '{d}/usr/bin' '{d}/root' '{d}/home/user' "
f"'{d}/run' '{d}/var' '{d}/proc' '{d}/sys' '{d}/dev'; "
# POSIX shell for #!/bin/sh scripts (dinit services, etc.).
f"ln -sf bash '{d}/usr/bin/sh'; "
# Static config tree from files/.
f"cp -rp '{self.files}/etc/.' '{d}/etc/'; "
# dinit as PID 1 (boot with kernel cmdline init=/sbin/init).
f"ln -sf /usr/bin/dinit '{d}/sbin/init'; "
# Conventional compat symlinks: the ELF interpreter is /lib64/ld-linux,
# but glibc lives in /lib; programs/shells live in /usr/bin.
f"ln -sf lib '{d}/lib64'; "
f"ln -sf usr/bin '{d}/bin'; "
# /var/run -> /run (dinit binds its control socket at /var/run/dinitctl).
f"ln -sf /run '{d}/var/run'; "
# Ownership + sensitive perms.
f"chown -R 0:0 '{d}/etc' '{d}/root'; "
f"chmod 0600 '{d}/etc/shadow'; "
f"chmod 0700 '{d}/root'; "
f"chown -R 1000:1000 '{d}/home/user'; "
f"chmod 0755 '{d}/home/user'",
)
+31
View File
@@ -0,0 +1,31 @@
version = "5.3"
revision = 1
description = "GNU Bourne-Again SHell"
license = "GPL-3.0-or-later"
url = "https://www.gnu.org/software/bash/"
source = tarball(
url=f"https://ftp.gnu.org/gnu/bash/bash-{version}.tar.gz",
sha256="0d5cd86965f869a26cf64f4b71be7b96f90a3ba8b3d74e27e8e9d9d5550f31ba",
)
host_deps = ["autoconf", "automake", "binutils", "gcc"]
deps = [profile["libc"], "ncurses", "readline"]
configure, build, install = autotools(
configure_args=[
"--without-bash-malloc",
"--disable-nls",
"--with-curses",
"--enable-readline",
"--with-installed-readline",
],
configure_env={
"bash_cv_termcap_lib": "libtinfo",
"CFLAGS": profile["cflags"] + " -std=gnu17",
"CFLAGS_FOR_BUILD": profile["host_cflags"] + " -std=gnu17",
},
# HACK: Fixes cross-compile issues
build_args=[
"READLINE_LDFLAGS=-L=/usr/lib",
"HISTORY_LDFLAGS=-L=/usr/lib",
],
)
+15
View File
@@ -0,0 +1,15 @@
version = "1.1.0"
revision = 1
description = "Generic-purpose lossless compression algorithm (Brotli)"
license = "MIT"
url = "https://github.com/google/brotli"
source = tarball(
url=f"https://github.com/google/brotli/archive/refs/tags/v{version}.tar.gz",
sha256="e720a6ca29428b803f4ad165371771f5398faba397edf6778837a18599ea13ff",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = cmake(
configure_args=["-DBROTLI_DISABLE_TESTS=ON"],
)
+22
View File
@@ -0,0 +1,22 @@
version = "1.18.4"
revision = 1
description = "2D graphics library with multiple output backends"
license = "LGPL-2.1-only OR MPL-1.1"
url = "https://www.cairographics.org/"
source = tarball(
url=f"https://www.cairographics.org/releases/cairo-{version}.tar.xz",
sha256="445ed8208a6e4823de1226a74ca319d3600e83f6369f99b14265006599c32ccb",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "pixman", "freetype2", "fontconfig", "libpng", "glib2", "zlib"]
configure, build, install = meson(
configure_args=[
# Wayland-only: no X backends. (cairo 1.18 has no GL-backend option.)
"-Dxlib=disabled",
"-Dxcb=disabled",
"-Dtests=disabled",
"-Dspectre=disabled",
"-Dsymbol-lookup=disabled", # avoids a libbfd/binutils dependency
],
)
+20
View File
@@ -0,0 +1,20 @@
version = "9.6"
revision = 1
description = "GNU core utilities (file, shell, and text manipulation)"
license = "GPL-3.0-or-later"
url = "https://www.gnu.org/software/coreutils/"
source = tarball(
url=f"https://ftp.gnu.org/gnu/coreutils/coreutils-{version}.tar.xz",
sha256="7a0124327b398fd9eb1a6abde583389821422c744ffa10734b24f557610d3283",
)
host_deps = ["autoconf", "automake", "binutils", "gcc"]
deps = [profile["libc"]]
configure, build, install = autotools(
configure_args=[
"--enable-no-install-program=kill,uptime",
"--without-selinux",
"--without-openssl",
],
configure_env={"FORCE_UNSAFE_CONFIGURE": "1"},
)
+9
View File
@@ -0,0 +1,9 @@
# Default boot target. dinit starts this service as PID 1; it pulls in the
# rest of the system. waits-for (rather than depends-on) keeps the machine
# coming up even if an individual service fails.
type = internal
waits-for = early-fs
waits-for = udevd
waits-for = udev-trigger
waits-for = seatd
waits-for = tty1
+4
View File
@@ -0,0 +1,4 @@
# Mount the early virtual filesystems needed before anything else runs.
type = scripted
command = /etc/dinit.d/scripts/early-fs.sh
restart = false
@@ -0,0 +1,17 @@
#!/bin/sh
# Bring up the kernel virtual filesystems and runtime dirs before other
# services start. Safe to re-run: each mount is guarded by mountpoint checks.
set -eu
export PATH=/usr/bin:/usr/sbin:/bin:/sbin
mountpoint -q /proc || mount -t proc proc /proc
mountpoint -q /sys || mount -t sysfs sysfs /sys
mountpoint -q /dev || mount -t devtmpfs devtmpfs /dev
mkdir -p /dev/pts /dev/shm
mountpoint -q /dev/pts || mount -t devpts devpts /dev/pts
mountpoint -q /dev/shm || mount -t tmpfs tmpfs /dev/shm
# NOTE: /run is intentionally NOT remounted here. dinit (PID 1) binds its
# control socket under /run before this script runs; on the all-RAM initramfs
# boot /run is already writable, and a fresh tmpfs mount would hide that socket.
# (A disk-rooted system should instead mount /run before starting dinit.)
mkdir -p /run/user /run/udev
@@ -0,0 +1,14 @@
#!/bin/sh
# Coldplug devices that already existed before udevd started: replay "add"
# uevents for subsystems then devices, and wait for processing to finish so
# DRM/input nodes (and their autoloaded modules) are present before Weston.
set -eu
export PATH=/usr/bin:/usr/sbin:/bin:/sbin
udevadm trigger --action=add --type=subsystems
udevadm trigger --action=add --type=devices
udevadm settle || true
# Safety net for QEMU/virtio: ensure the virtio-gpu DRM driver is loaded even if
# coldplug autoload missed it. (Input/evdev is built into the kernel.)
modprobe virtio_gpu 2>/dev/null || true
+6
View File
@@ -0,0 +1,6 @@
# Seat management daemon. Weston (via libseat) asks seatd to open DRM/input
# devices, so no logind is needed. The "seat" group may use the seatd socket.
type = process
command = /usr/bin/seatd -g seat
restart = true
depends-on = early-fs
+7
View File
@@ -0,0 +1,7 @@
# Autologin getty on tty1. login runs the user's profile, which launches Weston
# (see /etc/profile.d/weston.sh shipped by base-files).
type = process
command = /usr/bin/agetty --autologin user --noclear --login-program /usr/bin/login tty1 linux
restart = true
depends-on = seatd
depends-on = udev-trigger
+5
View File
@@ -0,0 +1,5 @@
# Coldplug: replay add events so udev autoloads DRM/input modules, then settle.
type = scripted
command = /etc/dinit.d/scripts/udev-trigger.sh
restart = false
depends-on = udevd
+5
View File
@@ -0,0 +1,5 @@
# eudev device manager daemon (udevd). Loads/uevents DRM/input drivers.
type = process
command = /usr/bin/udevd
restart = true
depends-on = early-fs
+51
View File
@@ -0,0 +1,51 @@
version = "0.20.0"
revision = 1
description = "Service manager / init system (dinit)"
license = "Apache-2.0"
url = "https://davmac.org/projects/dinit/"
source = tarball(
url=f"https://github.com/davmac314/dinit/archive/refs/tags/v{version}.tar.gz",
sha256="cd75b572a2eab4a9bd0610a2bb8cc154da7e80074e61cb1059a996dfd977baae",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "libstdc++"]
def configure(self):
# dinit's hand-written configure expects an in-tree build and reads the
# toolchain from the environment; CXX_FOR_BUILD compiles its small build-time
# helper with the native compiler.
self.run("cp", "-rp", f"{self.source_dir}/.", self.build_dir)
self.run(
"./configure",
"--prefix=/usr",
"--sbindir=/usr/bin",
"--enable-utmpx",
"--enable-shutdown",
"--disable-strip",
env={
"CXX": f"{self.triple}-g++",
"CXX_FOR_BUILD": "g++",
# dinit 0.20.0 uses std::allocator<T>::construct(), removed from the
# default C++ mode in GCC 16's libstdc++; build it as C++17 where it
# still exists.
"CXXFLAGS": self.options["cxxflags"] + " -std=gnu++17",
"LDFLAGS": self.options["ldflags"],
},
)
def build(self):
self.run("make", f"-j{self.jobs}")
def install(self):
self.run("make", "install", f"DESTDIR={self.dest_dir}")
# Ship the dinit service set (boot target + udev/seatd/agetty services).
self.run("install", "-d", self.dest_dir / "etc/dinit.d")
self.run(
"sh",
"-c",
f"cp -rp {self.files}/dinit.d/. {self.dest_dir}/etc/dinit.d/ && "
f"chmod +x {self.dest_dir}/etc/dinit.d/scripts/*.sh",
)
+39
View File
@@ -0,0 +1,39 @@
version = "0.192"
revision = 1
description = "ELF object file access library and utilities (libelf)"
license = "GPL-3.0-or-later AND LGPL-3.0-or-later"
url = "https://sourceware.org/elfutils/"
source = tarball(
url=f"https://sourceware.org/elfutils/ftp/{version}/elfutils-{version}.tar.bz2",
sha256="616099beae24aba11f9b63d86ca6cc8d566d968b802391334c91df54eab416b4",
)
host_deps = ["binutils", "gcc", "pkgconf"]
# libstdc++: elfutils builds a C++ tool (srcfiles) needing the C++ headers.
deps = [profile["libc"], "libstdc++", "zlib", "xz", "zstd"]
def configure(self):
# debuginfod would pull libcurl/microhttpd; we only need libelf for Mesa.
# elfutils builds with -Werror by default, which GCC 16 trips on.
autotools_configure(
self,
[
"--disable-debuginfod",
"--disable-libdebuginfod",
"--disable-nls",
"--enable-deterministic-archives",
"--program-prefix=eu-",
],
{
"CFLAGS": self.options["cflags"] + " -Wno-error",
"CXXFLAGS": self.options["cxxflags"] + " -Wno-error",
},
)
def build(self):
autotools_build(self)
def install(self):
autotools_install(self)
+22
View File
@@ -0,0 +1,22 @@
version = "3.2.14"
revision = 1
description = "Standalone udev fork: device manager (udevd, udevadm, libudev)"
license = "GPL-2.0-only AND LGPL-2.1-or-later"
url = "https://github.com/eudev-project/eudev"
source = tarball(
url=f"https://github.com/eudev-project/eudev/releases/download/v{version}/eudev-{version}.tar.gz",
sha256="8da4319102f24abbf7fff5ce9c416af848df163b29590e666d334cc1927f006f",
)
host_deps = ["binutils", "gcc", "pkgconf"]
# blkid (libblkid/util-linux) and kmod (libkmod) builtins are enabled by default.
deps = [profile["libc"], "kmod", "util-linux"]
configure, build, install = autotools(
configure_args=[
"--disable-manpages",
"--disable-introspection",
"--enable-hwdb",
# Keep daemon/rules/libexec under /usr (merged-usr layout).
"--with-rootprefix=/usr",
],
)
+20
View File
@@ -0,0 +1,20 @@
version = "2.7.3"
revision = 1
description = "Stream-oriented XML parser library (Expat)"
license = "MIT"
url = "https://libexpat.github.io/"
_tag = "R_" + version.replace(".", "_")
source = tarball(
url=f"https://github.com/libexpat/libexpat/releases/download/{_tag}/expat-{version}.tar.xz",
sha256="71df8f40706a7bb0a80a5367079ea75d91da4f8c65c58ec59bcdfbf7decdab9f",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = autotools(
configure_args=[
"--without-docbook",
"--without-examples",
"--without-tests",
],
)
+19
View File
@@ -0,0 +1,19 @@
version = "2.16.2"
revision = 1
description = "Library for configuring and customizing font access"
license = "MIT"
url = "https://www.freedesktop.org/wiki/Software/fontconfig/"
source = tarball(
url=f"https://gitlab.freedesktop.org/fontconfig/fontconfig/-/archive/{version}/fontconfig-{version}.tar.gz",
sha256="8b9368ae99d9faf2fe26491645fbeebf0272d911cacc5d3e9cf954c2157c151e",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "freetype2", "expat"]
configure, build, install = meson(
configure_args=[
"-Ddoc=disabled",
"-Dtests=disabled",
"-Dtools=enabled",
],
)
+23
View File
@@ -0,0 +1,23 @@
version = "2.13.3"
revision = 1
description = "FreeType font rendering library"
license = "FTL OR GPL-2.0-or-later"
url = "https://freetype.org/"
source = tarball(
url=f"https://download.savannah.gnu.org/releases/freetype/freetype-{version}.tar.xz",
sha256="0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "zlib", "libpng", "brotli"]
configure, build, install = meson(
configure_args=[
# First pass without HarfBuzz to break the freetype<->harfbuzz cycle;
# HarfBuzz is built afterwards and links back against this freetype.
"-Dharfbuzz=disabled",
"-Dbrotli=enabled",
"-Dbzip2=disabled",
"-Dpng=enabled",
"-Dzlib=enabled",
],
)
+18
View File
@@ -0,0 +1,18 @@
version = "1.0.16"
revision = 1
description = "Free Implementation of the Unicode Bidirectional Algorithm"
license = "LGPL-2.1-or-later"
url = "https://github.com/fribidi/fribidi"
source = tarball(
url=f"https://github.com/fribidi/fribidi/releases/download/v{version}/fribidi-{version}.tar.xz",
sha256="1b1cde5b235d40479e91be2f0e88a309e3214c8ab470ec8a2744d82a5a9ea05c",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = meson(
configure_args=[
"-Dtests=false",
"-Ddocs=false",
],
)
+25
View File
@@ -0,0 +1,25 @@
version = "2.84.2"
revision = 1
description = "GLib core application building blocks (GLib/GObject/GIO)"
license = "LGPL-2.1-or-later"
url = "https://gitlab.gnome.org/GNOME/glib"
_series = ".".join(version.split(".")[:2])
source = tarball(
url=f"https://download.gnome.org/sources/glib/{_series}/glib-{version}.tar.xz",
sha256="88e960dd937057407d61fcb3b45a860704b25923c37ae2478b85f2ecb5a4021f",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "libffi", "pcre2", "zlib"]
configure, build, install = meson(
configure_args=[
"-Dtests=false",
"-Dman-pages=disabled",
# gobject-introspection needs to run target binaries; skip when cross.
"-Dintrospection=disabled",
"-Dselinux=disabled",
# Avoid pulling util-linux (libmount) into the GIO build.
"-Dlibmount=disabled",
"-Dnls=enabled",
],
)
+38
View File
@@ -0,0 +1,38 @@
version = "2.41"
revision = 1
description = "GNU C library"
license = "LGPL-2.1-or-later"
url = "https://www.gnu.org/software/libc/"
source = tarball(
url=f"https://ftp.gnu.org/gnu/glibc/glibc-{version}.tar.xz",
sha256="a5a26b22f545d6b7d7b3dd828e11e428f24f4fac43c934fb071b6a7d0828e901",
)
host_deps = ["autoconf", "automake", "binutils", "gcc-bootstrap"]
deps = ["linux-headers"]
build_if = profile["libc"] == "glibc"
def configure(self):
autotools_configure(
self,
[
f"--build={self.triple}",
f"--with-headers={self.sysroot}{self.profile['prefix']}/include",
"--enable-kernel=5.4",
"--enable-bind-now",
"--enable-stack-protector=strong",
"--enable-cet",
"--disable-werror",
"--disable-profile",
"--disable-nscd",
"--without-selinux",
"--without-gd",
"libc_cv_slibdir=/lib",
"libc_cv_rtlddir=/lib",
"libc_cv_forced_unwind=yes",
],
)
_, build, install = autotools()
+26
View File
@@ -0,0 +1,26 @@
version = "12.1.0"
revision = 1
description = "OpenType text shaping engine"
license = "MIT"
url = "https://harfbuzz.github.io/"
source = tarball(
url=f"https://github.com/harfbuzz/harfbuzz/releases/download/{version}/harfbuzz-{version}.tar.xz",
sha256="e5c81b7f6e0b102dfb000cfa424538b8e896ab78a2f4b8a5ec8cae62ab43369e",
)
host_deps = ["binutils", "gcc", "pkgconf"]
# C++ library: needs libstdc++ (its headers + runtime) in the sysroot.
deps = [profile["libc"], "libstdc++", "freetype2", "glib2", "fribidi"]
configure, build, install = meson(
configure_args=[
"-Dfreetype=enabled",
"-Dglib=enabled",
"-Dgobject=disabled",
"-Dicu=disabled",
# cairo support here would create a cycle (cairo is built after harfbuzz).
"-Dcairo=disabled",
"-Dtests=disabled",
"-Ddocs=disabled",
"-Dbenchmark=disabled",
],
)
+22
View File
@@ -0,0 +1,22 @@
version = "0.394"
revision = 1
description = "Hardware identification data (pci.ids, usb.ids, ...)"
license = "GPL-2.0-or-later OR XFree86-1.1"
url = "https://github.com/vcrhonek/hwdata"
source = tarball(
url=f"https://github.com/vcrhonek/hwdata/archive/v{version}/hwdata-{version}.tar.gz",
sha256="b7c3fd7214a3b7c49d2661db127a712dc11cffd1799f793947aa1cb20aaf3298",
)
host_deps = ["pkgconf"]
# Pure data + a hwdata.pc; nothing links against it.
deps = []
def configure(self):
# hwdata ships a hand-written configure that expects an in-tree build.
self.run("cp", "-rp", f"{self.source_dir}/.", self.build_dir)
self.run("./configure", "--prefix=/usr", "--disable-blacklist")
def install(self):
self.run("make", "install", f"DESTDIR={self.dest_dir}")
+23
View File
@@ -0,0 +1,23 @@
version = "33"
revision = 1
description = "Tools and library to handle kernel modules (modprobe/depmod/libkmod)"
license = "LGPL-2.1-or-later"
url = "https://github.com/kmod-project/kmod"
source = tarball(
url=f"https://www.kernel.org/pub/linux/utils/kernel/kmod/kmod-{version}.tar.xz",
sha256="dc768b3155172091f56dc69430b5481f2d76ecd9ccb54ead8c2540dbcf5ea9bc",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "zlib", "xz", "zstd"]
# The kernel.org release tarball ships the autotools build (no meson.build).
configure, build, install = autotools(
configure_args=[
"--with-zstd",
"--with-xz",
"--with-zlib",
"--without-openssl",
"--disable-manpages",
"--disable-test-modules",
],
)
+40
View File
@@ -0,0 +1,40 @@
version = "2.73"
revision = 1
description = "POSIX 1003.1e capabilities library"
license = "BSD-3-Clause OR GPL-2.0-only"
url = "https://sites.google.com/site/fullycapable/"
source = tarball(
url=f"https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-{version}.tar.xz",
sha256="6405f6089cf4cdd8c271540cd990654d78dd0b1989b2d9bda20f933a75a795a5",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
def _args(self):
# libcap is plain-make: CC builds target objects, BUILD_CC builds the small
# native code generator. No PAM/Go bindings; force lib= so it lands in /usr/lib.
return [
f"CC={self.triple}-gcc",
"BUILD_CC=gcc",
"GOLANG=no",
"PAM_CAP=no",
"lib=lib",
"prefix=/usr",
]
def build(self):
# libcap builds in-tree; /sources is read-only, so work in /build.
self.run("cp", "-rp", f"{self.source_dir}/.", self.build_dir)
self.run("make", f"-j{self.jobs}", *_args(self))
def install(self):
self.run(
"make",
"install",
f"DESTDIR={self.dest_dir}",
"RAISE_SETFCAP=no",
*_args(self),
)
+32
View File
@@ -0,0 +1,32 @@
version = "0.2.0"
revision = 1
description = "EDID and DisplayID parsing library"
license = "MIT"
url = "https://gitlab.freedesktop.org/emersion/libdisplay-info"
source = tarball(
url=f"https://gitlab.freedesktop.org/emersion/libdisplay-info/-/releases/{version}/downloads/libdisplay-info-{version}.tar.xz",
sha256="5a2f002a16f42dd3540c8846f80a90b8f4bdcd067a94b9d2087bc2feae974176",
)
host_deps = ["binutils", "gcc", "pkgconf"]
# Reads hwdata's pnp.ids at build time.
deps = [profile["libc"], "hwdata"]
def configure(self):
# libdisplay-info generates a C table from hwdata's pnp.ids at build time,
# looking on the *build* machine (/usr/share/hwdata/pnp.ids). Our hwdata is
# in the target sysroot, so stage the (arch-independent) data there first.
self.run(
"sh",
"-c",
"mkdir -p /usr/share/hwdata && "
"cp -f /sysroot/usr/share/hwdata/pnp.ids /usr/share/hwdata/pnp.ids",
)
meson_configure(self)
def build(self):
meson_build(self)
def install(self):
meson_install(self)
+31
View File
@@ -0,0 +1,31 @@
version = "2.4.124"
revision = 1
description = "Direct Rendering Manager userspace library"
license = "MIT"
url = "https://dri.freedesktop.org/"
source = tarball(
url=f"https://dri.freedesktop.org/libdrm/libdrm-{version}.tar.xz",
sha256="ac36293f61ca4aafaf4b16a2a7afff312aa4f5c37c9fbd797de9e3c0863ca379",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "libpciaccess"]
configure, build, install = meson(
configure_args=[
# udev support is optional and would create a cycle with systemd-udev,
# which itself is pulled in later; Mesa does not require it.
"-Dudev=false",
"-Dtests=false",
"-Dman-pages=disabled",
"-Dvalgrind=disabled",
# GPU-specific helper libs that Mesa's x86_64 drivers consume.
"-Dintel=enabled",
"-Dradeon=enabled",
"-Damdgpu=enabled",
"-Dnouveau=enabled",
# Embedded/SoC GPUs we don't target.
"-Dvc4=disabled",
"-Detnaviv=disabled",
"-Dfreedreno=disabled",
],
)
+18
View File
@@ -0,0 +1,18 @@
version = "1.13.6"
revision = 1
description = "Wrapper library for evdev input devices"
license = "MIT"
url = "https://gitlab.freedesktop.org/libevdev/libevdev"
source = tarball(
url=f"https://www.freedesktop.org/software/libevdev/libevdev-{version}.tar.xz",
sha256="73f215eccbd8233f414737ac06bca2687e67c44b97d2d7576091aa9718551110",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = meson(
configure_args=[
"-Dtests=disabled",
"-Ddocumentation=disabled",
],
)
+16
View File
@@ -0,0 +1,16 @@
version = "3.4.6"
revision = 1
description = "Portable foreign-function interface library"
license = "MIT"
url = "https://sourceware.org/libffi/"
source = tarball(
url=f"https://github.com/libffi/libffi/releases/download/v{version}/libffi-{version}.tar.gz",
sha256="b0dea9df23c863a7a50e825440f3ebffabd65df1497108e5d437747843895a4e",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = autotools(
# Install straight into ${libdir} rather than a gcc-triplet subdir.
configure_args=["--disable-multi-os-directory"],
)
+22
View File
@@ -0,0 +1,22 @@
version = "1.7.0"
revision = 1
description = "GL Vendor-Neutral Dispatch library"
license = "MIT"
url = "https://gitlab.freedesktop.org/glvnd/libglvnd"
source = tarball(
url=f"https://gitlab.freedesktop.org/glvnd/libglvnd/-/archive/v{version}/libglvnd-v{version}.tar.gz",
sha256="2b6e15b06aafb4c0b6e2348124808cbd9b291c647299eaaba2e3202f51ff2f3d",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = meson(
configure_args=[
# Wayland-only: no X11/GLX dispatch.
"-Dx11=disabled",
"-Dglx=disabled",
"-Degl=true",
"-Dgles1=true",
"-Dgles2=true",
],
)
+22
View File
@@ -0,0 +1,22 @@
version = "1.28.1"
revision = 1
description = "Input device handling library for Wayland compositors"
license = "MIT"
url = "https://gitlab.freedesktop.org/libinput/libinput"
source = tarball(
url=f"https://gitlab.freedesktop.org/libinput/libinput/-/archive/{version}/libinput-{version}.tar.gz",
sha256="a13f8c9a7d93df3c85c66afd135f0296701d8d32f911991b7aa4273fdd6a42a3",
)
host_deps = ["binutils", "gcc", "pkgconf"]
# eudev provides libudev here.
deps = [profile["libc"], "eudev", "libevdev", "mtdev"]
configure, build, install = meson(
configure_args=[
"-Dlibwacom=false",
"-Ddebug-gui=false",
"-Dtests=false",
"-Ddocumentation=false",
"-Dudev-dir=/usr/lib/udev",
],
)
+19
View File
@@ -0,0 +1,19 @@
version = "3.1.2"
revision = 1
description = "SIMD-accelerated libjpeg-compatible JPEG codec"
license = "BSD-3-Clause AND IJG"
url = "https://libjpeg-turbo.org/"
source = tarball(
url=f"https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/{version}/libjpeg-turbo-{version}.tar.gz",
sha256="8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = cmake(
configure_args=[
"-DENABLE_STATIC=OFF",
"-DENABLE_SHARED=ON",
"-DWITH_JPEG8=ON",
],
)
+13
View File
@@ -0,0 +1,13 @@
version = "0.18.1"
revision = 1
description = "Generic PCI access library"
license = "MIT"
url = "https://gitlab.freedesktop.org/xorg/lib/libpciaccess"
source = tarball(
url=f"https://www.x.org/archive/individual/lib/libpciaccess-{version}.tar.xz",
sha256="4af43444b38adb5545d0ed1c2ce46d9608cc47b31c2387fc5181656765a6fa76",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "zlib"]
configure, build, install = meson()
+13
View File
@@ -0,0 +1,13 @@
version = "1.6.58"
revision = 1
description = "Reference library for the PNG image format"
license = "libpng-2.0"
url = "http://www.libpng.org/pub/png/libpng.html"
source = tarball(
url=f"https://github.com/pnggroup/libpng/archive/refs/tags/v{version}.tar.gz",
sha256="a9d4df463d36a6e5f9c29bd6f4967312d17e996c1854f3511f833924eb1993cf",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "zlib"]
configure, build, install = autotools()
+59
View File
@@ -0,0 +1,59 @@
version = "16.1.0"
revision = 1
description = "GNU C++ standard library"
license = "GPL-3.0-or-later"
url = "https://gcc.gnu.org/"
source = tarball(
url=f"https://ftp.gnu.org/gnu/gcc/gcc-{version}/gcc-{version}.tar.xz",
sha256="50efb4d94c3397aff3b0d61a5abd748b4dd31d9d3f2ab7be05b171d36a510f79",
)
host_deps = ["binutils", "gcc"]
deps = [profile["libc"]]
def configure(self):
self.run(
self.source_dir / "configure",
f"--target={self.triple}",
f"--prefix={self.profile['prefix']}",
f"--libdir={self.profile['libdir']}",
f"--with-sysroot={self.sysroot}",
f"--with-build-sysroot={self.sysroot}",
f"--with-gxx-include-dir={self.profile['includedir']}/c++/{version}",
f"--with-toolexeclibdir={self.profile['libdir']}",
"--enable-languages=c,c++",
"--disable-bootstrap",
"--enable-default-pie",
"--enable-default-ssp",
"--enable-lto",
"--enable-threads=posix",
"--enable-tls",
"--enable-libstdcxx-time",
"--enable-checking=release",
"--enable-cet=auto",
"--enable-linker-build-id",
"--disable-nls",
"--disable-multilib",
"--disable-fixed-point",
"--disable-werror",
"--disable-libsanitizer",
"--disable-symvers",
env={
"CFLAGS": self.profile["host_cflags"],
"CXXFLAGS": self.profile["host_cxxflags"],
"LDFLAGS": self.profile["host_ldflags"],
},
)
def build(self):
self.run("make", f"-j{self.jobs}", "all-target-libstdc++-v3")
def install(self):
self.run(
"make",
"install-target-libstdc++-v3",
env={"DESTDIR": str(self.dest_dir)},
)
self.run("find", self.dest_dir, "-name", "*.la", "-delete")
+23
View File
@@ -0,0 +1,23 @@
version = "4.4.38"
revision = 1
description = (
"Extended crypt library (libcrypt: descrypt, md5crypt, sha*crypt, yescrypt)"
)
license = "LGPL-2.1-or-later"
url = "https://github.com/besser82/libxcrypt"
source = tarball(
url=f"https://github.com/besser82/libxcrypt/releases/download/v{version}/libxcrypt-{version}.tar.xz",
sha256="80304b9c306ea799327f01d9a7549bdb28317789182631f1b54f4511b4206dd6",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
# glibc no longer provides libcrypt/crypt(); libxcrypt is the replacement.
# Build the glibc-compatible libcrypt.so.1 with all hash methods.
configure, build, install = autotools(
configure_args=[
"--enable-obsolete-api=glibc",
"--enable-hashes=all",
"--disable-failure-tokens",
],
)
+21
View File
@@ -0,0 +1,21 @@
version = "1.9.2"
revision = 1
description = "Library to handle keyboard descriptions and key events"
license = "MIT"
url = "https://xkbcommon.org/"
source = tarball(
url=f"https://github.com/xkbcommon/libxkbcommon/archive/refs/tags/xkbcommon-{version}.tar.gz",
sha256="d2eab57e1ce79de991f8ceb3fcd726a6978b970382c8ac8c8f112b61ceaa9167",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "xkeyboard-config", "libxml2"]
configure, build, install = meson(
configure_args=[
# Weston uses core libxkbcommon; no X11/Wayland helper tools needed.
"-Denable-x11=false",
"-Denable-wayland=false",
"-Denable-docs=false",
"-Dxkb-config-root=/usr/share/X11/xkb",
],
)
+21
View File
@@ -0,0 +1,21 @@
version = "2.14.2"
revision = 1
description = "XML parsing and toolkit library (libxml2)"
license = "MIT"
url = "https://gitlab.gnome.org/GNOME/libxml2"
_series = ".".join(version.split(".")[:2])
source = tarball(
url=f"https://download.gnome.org/sources/libxml2/{_series}/libxml2-{version}.tar.xz",
sha256="353f3c83535d4224a4e5f1e88c90b5d4563ea8fec11f6407df640fd28fc8b8c6",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "zlib", "xz"]
configure, build, install = autotools(
configure_args=[
"--without-python",
"--with-zlib",
"--with-lzma",
"--without-icu",
],
)
+50
View File
@@ -0,0 +1,50 @@
version = "12.2.0"
revision = 1
description = "Modern, secure, portable, multiprotocol bootloader and boot manager"
license = "BSD-2-Clause"
url = "https://limine-bootloader.org"
source = tarball(
url=f"https://github.com/Limine-Bootloader/Limine/releases/download/v{version}/limine-{version}.tar.gz",
sha256="db8a119878cfeead63c0a78236c577c40539c5759496950ea0ed32a6cf567865",
)
host_deps = ["autoconf", "automake", "binutils", "gcc"]
deps = [profile["libc"]]
build_if = profile.arch in ("x86_64", "aarch64", "riscv64", "loongarch64")
arch_args = {
"x86_64": [
"--enable-uefi-x86-64",
"--enable-uefi-ia32",
"--enable-bios",
"--enable-bios-cd",
],
"aarch64": ["--enable-uefi-aarch64"],
"riscv64": ["--enable-uefi-riscv64"],
"loongarch64": ["--enable-uefi-loongarch64"],
}
configure, build, install = autotools(
configure_args=["--enable-uefi-cd", *arch_args[profile.arch]],
configure_env={"TOOLCHAIN_FOR_TARGET": profile.triple + "-"},
)
subpackages = [
subpackage(
"limine-uefi",
description="UEFI files",
files=[
"usr/share/limine/BOOT*.EFI",
"usr/share/limine/limine-uefi-*.bin",
],
),
]
if profile.arch == "x86_64":
subpackages.append(
subpackage(
"limine-bios",
description="BIOS files",
files=["usr/share/limine/limine-bios*"],
)
)
+38
View File
@@ -0,0 +1,38 @@
version = "7.0.9"
revision = 2
description = "Linux kernel headers for userspace development"
license = "GPL-2.0-only"
source = tarball(
url=f"https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-{version}.tar.xz",
sha256="ac07acdf76cf4621cc5187a2670270a1a699533c8a6b225e4878c416ad83f1c4",
)
linux_archs = {"aarch64": "arm64"}
def build(self):
# Stage the source into the (writable) build dir before invoking the kernel
# build system, which is not happy with a read-only source tree.
self.run("cp", "-rp", f"{self.source_dir}/.", self.build_dir)
arch = linux_archs.get(self.arch, self.arch)
self.run("make", "headers_install", f"ARCH={arch}")
self.run(
"find",
self.build_dir / "usr/include",
"-type",
"f",
"!",
"-name",
"*.h",
"-delete",
)
def install(self):
self.run("mkdir", "-p", self.dest_dir / self.profile["prefix"].lstrip("/"))
self.run(
"cp",
"-rp",
self.build_dir / "usr/include",
str(self.dest_dir) + self.profile["prefix"],
)
-20
View File
@@ -1,20 +0,0 @@
version = "7.0.9"
revision = 1
metadata = meta(
description = "Linux kernel headers for userspace development",
license = "GPL-2.0-only",
)
source = tarball(
url = f"https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-{version}.tar.xz",
sha256 = "ac07acdf76cf4621cc5187a2670270a1a699533c8a6b225e4878c416ad83f1c4",
strip_components = 1,
)
def build(ctx):
ctx.run("cp", "-rp", ctx.source_dir / ".", ctx.build_dir)
ctx.run("make", "headers_install", "ARCH=" + options.target_arch)
ctx.run("find", ctx.build_dir / "usr" / "include", "-type", "f", "!", "-name", "*.h", "-delete")
def install(ctx):
ctx.run("mkdir", "-p", ctx.dest_dir / options.prefix)
ctx.run("cp", "-rp", ctx.build_dir / "usr" / "include", ctx.dest_dir / options.prefix)
File diff suppressed because it is too large Load Diff
+78
View File
@@ -0,0 +1,78 @@
version = "7.0.9"
revision = 2
description = "Linux kernel"
license = "GPL-2.0-only"
source = tarball(
url=f"https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-{version}.tar.xz",
sha256="ac07acdf76cf4621cc5187a2670270a1a699533c8a6b225e4878c416ad83f1c4",
)
host_deps = ["binutils", "gcc"]
deps = [profile["libc"]]
linux_archs = {"aarch64": "arm64"}
linux_subarchs = {"x86_64": "x86"}
def _make(self, *extra):
arch = linux_archs.get(self.arch, self.arch)
subarch = linux_subarchs.get(self.arch)
subarch_arg = (f"SUBARCH={subarch}",) if subarch else ()
return (
"make",
f"ARCH={arch}",
*subarch_arg,
f"CROSS_COMPILE={self.triple}-",
f"-j{self.jobs}",
*extra,
)
def configure(self):
self.run("cp", "-rp", f"{self.source_dir}/.", self.build_dir)
self.run(
"cp", self.files / f"config.{self.arch}", self.build_dir / ".config"
)
self.run(*_make(self, "olddefconfig"))
def build(self):
self.run(*_make(self))
def install(self):
self.run(
"install",
"-Dm644",
self.build_dir / "arch/x86/boot/bzImage",
self.dest_dir / f"boot/vmlinuz-{self.version}",
)
self.run(
"install",
"-Dm644",
self.build_dir / ".config",
self.dest_dir / f"boot/config-{self.version}",
)
self.run(
"install",
"-Dm644",
self.build_dir / "System.map",
self.dest_dir / f"boot/System.map-{self.version}",
)
# Install loadable modules so udev can autoload DRM/input drivers at boot.
# The kernel's modules_install target runs depmod itself (host kmod).
self.run(
*_make(
self,
f"INSTALL_MOD_PATH={self.dest_dir}",
"INSTALL_MOD_STRIP=1",
"modules_install",
)
)
# Drop the dangling build/source symlinks that point at the (ephemeral)
# build tree; they are useless in the target image.
self.run(
"sh",
"-c",
f"rm -f {self.dest_dir}/lib/modules/*/build "
f"{self.dest_dir}/lib/modules/*/source",
)
+72
View File
@@ -0,0 +1,72 @@
version = "21.1.6"
revision = 1
description = "LLVM compiler infrastructure (target libLLVM for Mesa)"
license = "Apache-2.0 WITH LLVM-exception"
url = "https://llvm.org/"
source = tarball(
url=f"https://github.com/llvm/llvm-project/releases/download/llvmorg-{version}/llvm-project-{version}.src.tar.xz",
sha256="ae67086eb04bed7ca11ab880349b5f1ab6f50e1b88cda376eaf8a845b935762b",
)
host_deps = ["binutils", "gcc", "pkgconf"]
# Pinned independently of the host LLVM (22.x): this must be a release that
# Mesa 25.3 accepts. Provides target libLLVM for the llvmpipe/radeonsi gallium
# drivers; X86 + AMDGPU backends cover software rendering and AMD GPUs.
deps = [profile["libc"], "ncurses", "zlib", "zstd", "libffi", "libxml2"]
def configure(self):
p = self.options
self.run(
"cmake",
"-S",
self.source_dir / "llvm",
"-B",
self.build_dir,
"-GNinja",
"-DCMAKE_BUILD_TYPE=Release",
f"-DCMAKE_INSTALL_PREFIX={p.get('prefix', '/usr')}",
# Cross toolchain. CMAKE_CROSSCOMPILING triggers LLVM to build a native
# llvm-tblgen under build/NATIVE with the default host compiler.
"-DCMAKE_SYSTEM_NAME=Linux",
f"-DCMAKE_SYSTEM_PROCESSOR={self.arch}",
f"-DCMAKE_SYSROOT={self.sysroot}",
f"-DCMAKE_C_COMPILER={self.triple}-gcc",
f"-DCMAKE_CXX_COMPILER={self.triple}-g++",
"-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER",
"-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY",
"-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY",
"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY",
f"-DLLVM_HOST_TRIPLE={self.triple}",
f"-DLLVM_DEFAULT_TARGET_TRIPLE={self.triple}",
"-DLLVM_TARGETS_TO_BUILD=X86;AMDGPU",
"-DLLVM_BUILD_LLVM_DYLIB=ON",
"-DLLVM_LINK_LLVM_DYLIB=ON",
"-DLLVM_ENABLE_RTTI=ON",
"-DLLVM_ENABLE_FFI=ON",
"-DLLVM_ENABLE_ZLIB=FORCE_ON",
"-DLLVM_ENABLE_ZSTD=FORCE_ON",
"-DLLVM_ENABLE_LIBXML2=FORCE_ON",
"-DLLVM_ENABLE_TERMINFO=ON",
"-DLLVM_INCLUDE_TESTS=OFF",
"-DLLVM_INCLUDE_EXAMPLES=OFF",
"-DLLVM_INCLUDE_BENCHMARKS=OFF",
"-DLLVM_INCLUDE_DOCS=OFF",
"-DLLVM_ENABLE_PROJECTS=",
"-Wno-dev",
env={
"CFLAGS": p.get("cflags", ""),
"CXXFLAGS": p.get("cxxflags", ""),
"LDFLAGS": p.get("ldflags", ""),
},
)
def build(self):
self.run("cmake", "--build", self.build_dir, f"-j{self.jobs}")
def install(self):
self.run("cmake", "--install", self.build_dir, env={"DESTDIR": str(self.dest_dir)})
# Runtime needs the shared libLLVM + headers/llvm-config; static archives are
# large and unnecessary for Mesa.
self.run("sh", "-c", f"rm -f {self.dest_dir}/usr/lib/*.a")
+13
View File
@@ -0,0 +1,13 @@
version = "4.4.1"
revision = 1
description = "GNU make build automation tool"
license = "GPL-3.0-or-later"
url = "https://www.gnu.org/software/make/"
source = tarball(
url=f"https://ftp.gnu.org/gnu/make/make-{version}.tar.gz",
sha256="dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3",
)
host_deps = ["autoconf", "automake", "binutils", "gcc"]
deps = [profile["libc"]]
configure, build, install = autotools(configure_args=["--without-guile"])
+56
View File
@@ -0,0 +1,56 @@
version = "25.3.0"
revision = 1
description = "Mesa 3D graphics library (OpenGL/EGL/GLES, gallium drivers)"
license = "MIT"
url = "https://www.mesa3d.org/"
source = tarball(
url=f"https://archive.mesa3d.org/mesa-{version}.tar.xz",
sha256="0fd54fea7dbbddb154df05ac752b18621f26d97e27863db3be951417c6abe8ae",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [
profile["libc"],
"libstdc++", # C++ components need the libstdc++ headers/runtime
"libdrm",
"expat",
"llvm",
"zlib",
"zstd",
"wayland",
"wayland-protocols",
"libglvnd",
"hwdata",
"eudev", # libudev: DRM device enumeration
"libdisplay-info", # EDID/DisplayID parsing for the KMS backend
"elfutils", # libelf: required by the radeonsi gallium driver
]
_mesa_args = [
"-Dplatforms=wayland",
"-Dglx=disabled",
"-Degl=enabled",
"-Dgbm=enabled",
"-Dgles1=enabled",
"-Dgles2=enabled",
"-Dglvnd=enabled",
"-Dshared-glapi=enabled",
"-Dllvm=enabled",
"-Dshared-llvm=enabled",
"-Dexpat=enabled",
"-Dzstd=enabled",
"-Dvideo-codecs=all_free",
"-Db_ndebug=true",
"-Dbuild-tests=false",
# Broad HW + software gallium set (Weston's GL renderer uses these).
# NOTE: 'iris' (modern Intel) is omitted because it requires libclc
# (a clang-based OpenCL-bitcode build); 'crocus' covers older Intel.
# Add iris back once a libclc recipe exists.
"-Dgallium-drivers=radeonsi,r600,crocus,nouveau,virgl,svga,zink,llvmpipe,softpipe",
# Vulkan deferred: needs a vulkan-headers + SPIRV-Headers/Tools sub-stack
# and is not required for Weston's GL renderer. Add radv/anv/lavapipe later.
"-Dvulkan-drivers=",
]
# LLVM is found via the cross llvm-config emulator wired into the meson cross
# file (src/lib/meson.py), which reports sysroot paths — no target-binary exec.
configure, build, install = meson(configure_args=_mesa_args)
+13
View File
@@ -0,0 +1,13 @@
version = "1.1.7"
revision = 1
description = "Multitouch protocol translation library"
license = "MIT"
url = "https://bitmath.org/code/mtdev/"
source = tarball(
url=f"https://bitmath.org/code/mtdev/mtdev-{version}.tar.gz",
sha256="a55bd02a9af4dd266c0042ec608744fff3a017577614c057da09f1f4566ea32c",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = autotools()
+28
View File
@@ -0,0 +1,28 @@
version = "1.2.6"
revision = 1
description = "Small, standards-conformant implementation of libc"
license = "MIT"
source = tarball(
url=f"https://musl.libc.org/releases/musl-{version}.tar.gz",
sha256="d585fd3b613c66151fc3249e8ed44f77020cb5e6c1e635a616d3f9f82460512a",
)
host_deps = ["binutils", "gcc-bootstrap"]
build_if = profile["libc"] == "musl"
def configure(self):
self.run(
self.source_dir / "configure",
f"--target={self.triple}",
f"--prefix={self.profile['prefix']}",
"--syslibdir=/lib",
env={
"CC": f"{self.triple}-gcc",
"CFLAGS": self.profile["cflags"],
"LDFLAGS": self.profile["ldflags"],
},
)
_, build, install = autotools()
+48
View File
@@ -0,0 +1,48 @@
version = "6.5"
revision = 2
description = "Terminal control library with wide-character support"
license = "MIT"
url = "https://invisible-island.net/ncurses/"
source = tarball(
url=f"https://invisible-mirror.net/archives/ncurses/ncurses-{version}.tar.gz",
sha256="136d91bc269a9a5785e5f9e980bc76ab57428f604ce3e5a5a90cebc767971cc6",
)
host_deps = ["autoconf", "automake", "binutils", "gcc"]
deps = [profile["libc"], "libstdc++"]
configure, build, _ = autotools(
configure_args=[
"--with-shared",
"--without-debug",
"--without-ada",
"--enable-pc-files",
"--enable-widec",
"--with-termlib",
"--with-cxx-binding",
"--with-cxx-shared",
"--with-pkg-config-libdir=/usr/lib/pkgconfig",
"--with-tic-path=/usr/bin/tic",
"--with-infocmp-path=/usr/bin/infocmp",
"--mandir=/usr/share/man",
],
configure_env={
# Conflicts with GCC 16 headers.
"cf_cv_type_of_bool": "bool",
"cf_cv_cc_bool_type": "1",
"cf_cv_builtin_bool": "1",
"ac_cv_header_stdbool_h": "yes",
},
)
def install(self):
autotools_install(self, [f"DESTDIR={self.dest_dir}"])
libdir = self.dest_dir / "usr/lib"
pcdir = libdir / "pkgconfig"
for name in ("ncurses", "curses"):
self.run("ln", "-sf", "libncursesw.so", libdir / f"lib{name}.so")
self.run("ln", "-sf", "libncursesw.a", libdir / f"lib{name}.a")
self.run("ln", "-sf", "libtinfow.so", libdir / "libtinfo.so")
self.run("ln", "-sf", "libtinfow.a", libdir / "libtinfo.a")
self.run("ln", "-sf", "ncursesw.pc", pcdir / "ncurses.pc")
self.run("ln", "-sf", "tinfow.pc", pcdir / "tinfo.pc")
+60
View File
@@ -0,0 +1,60 @@
version = "3.4.1"
revision = 1
description = "Cryptography and TLS library (OpenSSL)"
license = "Apache-2.0"
url = "https://www.openssl.org/"
source = tarball(
url=f"https://github.com/openssl/openssl/releases/download/openssl-{version}/openssl-{version}.tar.gz",
sha256="002a2d6b30b58bf4bea46c43bdd96365aaf8daa6c428782aa4feee06da197df3",
)
host_deps = ["binutils", "gcc"]
deps = ["zlib"]
ossl_targets = {
"x86_64": "linux-x86_64",
"aarch64": "linux-aarch64",
"riscv64": "linux64-riscv64",
}
def configure(self):
target = ossl_targets.get(self.arch)
if target is None:
raise ValueError(f"openssl: unsupported arch {self.arch}")
self.run(
self.source_dir / "Configure",
target,
f"--prefix={self.profile['prefix']}",
"--openssldir=/etc/ssl",
"--libdir=lib",
"shared",
"zlib",
"no-tests",
"no-static-engine",
"enable-ktls",
env={
"CC": f"{self.triple}-gcc",
"AR": f"{self.triple}-ar",
"RANLIB": f"{self.triple}-ranlib",
"CFLAGS": self.profile["cflags"],
"LDFLAGS": self.profile["ldflags"],
},
)
def build(self):
self.run("make", f"-j{self.jobs}")
def install(self):
# OpenSSL's Makefile assigns `DESTDIR=` itself, so an environment DESTDIR is
# ignored; it must be passed as a make command-line variable to take effect.
# Without this, the (glibc) target libs install straight into the musl
# builder's /usr/lib and break it mid-install.
self.run(
"make",
"install_sw",
"install_ssldirs",
f"DESTDIR={self.dest_dir}",
)
+28
View File
@@ -0,0 +1,28 @@
version = "1.56.3"
revision = 1
description = "Library for laying out and rendering internationalized text"
license = "LGPL-2.1-or-later"
url = "https://www.gtk.org/"
_series = ".".join(version.split(".")[:2])
source = tarball(
url=f"https://download.gnome.org/sources/pango/{_series}/pango-{version}.tar.xz",
sha256="2606252bc25cd8d24e1b7f7e92c3a272b37acd6734347b73b47a482834ba2491",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [
profile["libc"],
"glib2",
"harfbuzz",
"fribidi",
"fontconfig",
"freetype2",
"cairo",
]
configure, build, install = meson(
configure_args=[
"-Dintrospection=disabled",
"-Dgtk_doc=false",
"-Dxft=disabled",
],
)
+19
View File
@@ -0,0 +1,19 @@
version = "10.45"
revision = 1
description = "Perl-compatible regular expression library (PCRE2)"
license = "BSD-3-Clause"
url = "https://www.pcre.org/"
source = tarball(
url=f"https://github.com/PCRE2Project/pcre2/releases/download/pcre2-{version}/pcre2-{version}.tar.gz",
sha256="0e138387df7835d7403b8351e2226c1377da804e0737db0e071b48f07c9d12ee",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = autotools(
configure_args=[
"--enable-pcre2-16",
"--enable-pcre2-32",
"--enable-jit",
],
)
+19
View File
@@ -0,0 +1,19 @@
version = "0.46.0"
revision = 1
description = "Low-level pixel manipulation library"
license = "MIT"
url = "https://www.pixman.org/"
source = tarball(
url=f"https://www.x.org/archive/individual/lib/pixman-{version}.tar.xz",
sha256="d2eab57e1ce79de991f8ceb3fcd726a6978b970382c8ac8c8f112b61ceaa9167",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "libpng"]
configure, build, install = meson(
configure_args=[
"-Dtests=disabled",
"-Ddemos=disabled",
"-Dgtk=disabled",
],
)
+18
View File
@@ -0,0 +1,18 @@
version = "2.5.1"
revision = 1
description = "Lightweight pkg-config implementation"
license = "ISC"
url = "http://pkgconf.org/"
source = tarball(
url=f"https://distfiles.ariadne.space/pkgconf/pkgconf-{version}.tar.xz",
sha256="cd05c9589b9f86ecf044c10a2269822bc9eb001eced2582cfffd658b0a50c243",
)
host_deps = ["autoconf", "automake", "binutils", "gcc"]
deps = [profile["libc"]]
configure, build, install = autotools(
configure_args=[
f"--with-system-libdir={profile['libdir']}",
f"--with-system-includedir={profile['includedir']}",
]
)
+22
View File
@@ -0,0 +1,22 @@
version = "8.3"
revision = 1
description = "Library for command-line editing"
license = "GPL-3.0-or-later"
url = "https://tiswww.case.edu/php/chet/readline/rltop.html"
source = tarball(
url=f"https://ftp.gnu.org/gnu/readline/readline-{version}.tar.gz",
sha256="fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc",
)
host_deps = ["autoconf", "automake", "binutils", "gcc"]
deps = [profile["libc"], "ncurses"]
configure, build, _ = autotools(
configure_args=["--with-curses", "--with-shared-termcap-library"],
# Force linking against system terminfo, not readline's internal termcap stub.
configure_env={"bash_cv_termcap_lib": "libtinfo"},
)
def install(self):
# readline overwrites DESTDIR on its own; pass explicitly.
autotools_install(self, [f"DESTDIR={self.dest_dir}"])
+23
View File
@@ -0,0 +1,23 @@
version = "0.6.3"
revision = 1
description = "Seat management daemon and libseat (logind-free)"
license = "MIT"
url = "https://git.sr.ht/~kennylevinsen/seatd"
source = tarball(
url=f"https://git.sr.ht/~kennylevinsen/seatd/archive/{version}.tar.gz",
sha256="5226850c163b485aebe71da0d3f4941761637e146a5c9393cb40c52617ad84a8",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
configure, build, install = meson(
configure_args=[
# No logind: libseat talks to the bundled seatd daemon, which Weston
# uses (via libseat) to open DRM/input devices on the user's behalf.
"-Dlibseat-logind=disabled",
"-Dlibseat-seatd=enabled",
"-Dserver=enabled",
"-Dexamples=disabled",
"-Dman-pages=disabled",
],
)
+33
View File
@@ -0,0 +1,33 @@
version = "4.16.0"
revision = 1
description = "Password and account management utilities (login, passwd, useradd)"
license = "BSD-3-Clause"
url = "https://github.com/shadow-maint/shadow"
source = tarball(
url=f"https://github.com/shadow-maint/shadow/releases/download/{version}/shadow-{version}.tar.xz",
sha256="b78e3921a95d53282a38e90628880624736bf6235e36eea50c50835f59a3530b",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "libxcrypt"]
configure, build, _ = autotools(
configure_args=[
"--without-libpam",
"--without-libbsd",
"--without-selinux",
"--without-acl",
"--without-attr",
],
)
def install(self):
autotools_install(self, [f"DESTDIR={self.dest_dir}"])
# `groups` is also shipped by coreutils; drop shadow's copy (and its man
# page) so the two packages don't conflict at install time.
self.run(
"sh",
"-c",
f"rm -f {self.dest_dir}/usr/bin/groups "
f"{self.dest_dir}/usr/share/man/man1/groups.1",
)
+18
View File
@@ -0,0 +1,18 @@
version = "2.37"
revision = 1
description = "DejaVu TrueType font family"
license = "Bitstream-Vera"
url = "https://dejavu-fonts.github.io/"
_tag = "version_" + version.replace(".", "_")
source = tarball(
url=f"https://github.com/dejavu-fonts/dejavu-fonts/releases/download/{_tag}/dejavu-fonts-ttf-{version}.tar.bz2",
sha256="fa9ca4d13871dd122f61258a80d01751d603b4d3ee14095d65453b4e846e17d7",
)
host_deps = []
deps = []
def install(self):
dest = self.dest_dir / "usr/share/fonts/dejavu"
self.run("install", "-d", dest)
self.run("sh", "-c", f"install -m644 {self.source_dir}/ttf/*.ttf {dest}/")
+58
View File
@@ -0,0 +1,58 @@
version = "2.41"
revision = 1
description = "Miscellaneous system utilities (agetty, mount, libblkid, libmount)"
license = "GPL-2.0-or-later AND LGPL-2.1-or-later"
url = "https://github.com/util-linux/util-linux"
_series = "v" + ".".join(version.split(".")[:2])
source = tarball(
url=f"https://www.kernel.org/pub/linux/utils/util-linux/{_series}/util-linux-{version}.tar.xz",
sha256="81ee93b3cfdfeb7d7c4090cedeba1d7bbce9141fd0b501b686b3fe475ddca4c6",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"], "zlib"]
configure, build, _ = autotools(
configure_args=[
# We need agetty + the libs (blkid/mount/uuid); login/su come from shadow
# to avoid a /usr/bin/login file conflict.
"--disable-login",
"--disable-su",
"--disable-nologin",
# liblastlog2 (new in 2.41) pulls in sqlite3; we don't need it.
"--disable-liblastlog2",
"--disable-pam-lastlog2",
# We only need agetty + the libs; skip the curses TUI tools (irqtop,
# cfdisk, ...) which otherwise trip over the ncurses termlib split.
"--without-ncurses",
"--without-ncursesw",
"--without-systemd",
"--without-systemdsystemunitdir",
"--without-python",
"--disable-bash-completion",
"--disable-rpath",
# These would chown/setuid during install, which fails unprivileged.
"--disable-makeinstall-chown",
"--disable-makeinstall-setuid",
],
)
def install(self):
autotools_install(self, [f"DESTDIR={self.dest_dir}"])
# libtool's install-time relink miscompiles libmount/libfdisk against the
# build host's musl libc instead of the target glibc (the pre-relink
# build-tree libs are correct). Restore the build-tree shared objects over
# the relinked ones and strip their build-tree rpath.
self.run(
"sh",
"-ec",
"for real in /build/.libs/lib*.so.*.*.*; do "
' [ -e "$real" ] || continue; '
' base=$(basename "$real"); '
f' dst="{self.dest_dir}/usr/lib/$base"; '
' [ -e "$dst" ] || continue; '
' cp -a "$real" "$dst"; '
' patchelf --remove-rpath "$dst" 2>/dev/null || true; '
"done",
)
+16
View File
@@ -0,0 +1,16 @@
version = "1.43"
revision = 1
description = "Wayland protocol extension definitions"
license = "MIT"
url = "https://gitlab.freedesktop.org/wayland/wayland-protocols"
source = tarball(
url=f"https://gitlab.freedesktop.org/wayland/wayland-protocols/-/releases/{version}/downloads/wayland-protocols-{version}.tar.xz",
sha256="ba3c3425dd27c57b5291e93dba97be12479601e00bcab24d26471948cb643653",
)
host_deps = ["pkgconf"]
# Architecture-independent XML + pkg-config data; nothing to link.
deps = []
configure, build, install = meson(
configure_args=["-Dtests=false"],
)
+23
View File
@@ -0,0 +1,23 @@
# Must match the build machine's wayland-scanner (from the Alpine image), which
# wayland requires to be the exact same version when cross-compiling.
version = "1.25.0"
revision = 1
description = "Core Wayland protocol library and scanner"
license = "MIT"
url = "https://wayland.freedesktop.org/"
source = tarball(
url=f"https://gitlab.freedesktop.org/wayland/wayland/-/releases/{version}/downloads/wayland-{version}.tar.xz",
sha256="c065f040afdff3177680600f249727e41a1afc22fccf27222f15f5306faa1f03",
)
host_deps = ["binutils", "gcc", "pkgconf"]
# The build machine's wayland-scanner (from the builder image) generates protocol
# glue; the target libwayland-{client,server} link libffi/expat/libxml2.
deps = [profile["libc"], "libffi", "expat", "libxml2"]
configure, build, install = meson(
configure_args=[
"-Dtests=false",
"-Ddocumentation=false",
"-Ddtd_validation=true",
],
)
+58
View File
@@ -0,0 +1,58 @@
version = "14.0.2"
revision = 1
description = "Reference Wayland compositor (Weston)"
license = "MIT"
url = "https://gitlab.freedesktop.org/wayland/weston"
source = tarball(
url=f"https://gitlab.freedesktop.org/wayland/weston/-/releases/{version}/downloads/weston-{version}.tar.xz",
sha256="b47216b3530da76d02a3a1acbf1846a9cd41d24caa86448f9c46f78f20b6e0ac",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [
profile["libc"],
"wayland",
"wayland-protocols",
"libxkbcommon",
"pixman",
"cairo",
"libinput",
"mesa",
"libdrm",
"libdisplay-info",
"seatd",
"pango",
"glib2",
"libjpeg-turbo",
"libpng",
"freetype2",
"fontconfig",
"ttf-dejavu",
]
configure, build, install = meson(
configure_args=[
# DRM backend with the GL renderer; seatd (libseat) launcher, no logind.
"-Dbackend-drm=true",
"-Dbackend-headless=true",
"-Dbackend-wayland=true",
"-Dbackend-x11=false",
"-Dbackend-rdp=false",
"-Dbackend-vnc=false",
"-Dbackend-pipewire=false",
"-Dbackend-drm-screencast-vaapi=false",
"-Drenderer-gl=true",
"-Dxwayland=false",
"-Dsystemd=false",
# libseat (seatd) is auto-detected in weston 14; no explicit option.
"-Dimage-jpeg=true",
"-Dimage-webp=false",
"-Dremoting=false",
"-Dpipewire=false",
"-Dcolor-management-lcms=false",
"-Ddemo-clients=true",
"-Dsimple-clients=damage,im,egl,shm,touch",
# Test suite needs extra generated protocol headers and isn't needed.
"-Dtests=false",
"-Dtest-junit-xml=false",
],
)
+16
View File
@@ -0,0 +1,16 @@
version = "2.44"
revision = 1
description = "X keyboard configuration database (keymaps for libxkbcommon)"
license = "MIT"
url = "https://www.freedesktop.org/wiki/Software/XKeyboardConfig/"
source = tarball(
url=f"https://www.x.org/archive/individual/data/xkeyboard-config/xkeyboard-config-{version}.tar.xz",
sha256="54d2c33eeebb031d48fa590c543e54c9bcbd0f00386ebc6489b2f47a0da4342a",
)
host_deps = ["pkgconf"]
# Pure keymap data installed under /usr/share/X11/xkb.
deps = []
configure, build, install = meson(
configure_args=["-Dxorg-rules-symlinks=true"],
)
+13
View File
@@ -0,0 +1,13 @@
version = "5.6.3"
revision = 1
description = "LZMA/XZ compression tools and library"
license = "0BSD AND GPL-2.0-or-later AND LGPL-2.1-or-later"
url = "https://tukaani.org/xz/"
source = tarball(
url=f"https://github.com/tukaani-project/xz/releases/download/v{version}/xz-{version}.tar.xz",
sha256="db0590629b6f0fa36e74aea5f9731dc6f8df068ce7b7bafa45301832a5eebc3a",
)
host_deps = ["autoconf", "automake", "binutils", "gcc"]
deps = [profile["libc"]]
configure, build, install = autotools(configure_args=["--disable-doc"])
+36
View File
@@ -0,0 +1,36 @@
version = "1.3.2"
revision = 1
description = "Lossless data-compression library"
license = "Zlib"
url = "https://zlib.net/"
source = tarball(
url=f"https://github.com/madler/zlib/releases/download/v{version}/zlib-{version}.tar.gz",
sha256="bb329a0a2cd0274d05519d61c667c062e06990d72e125ee2dfa8de64f0119d16",
)
host_deps = ["binutils", "gcc"]
deps = [profile["libc"]]
def configure(self):
# zlib ships its own ./configure; doesn't grok autoconf flags.
self.run(
self.source_dir / "configure",
f"--prefix={self.profile['prefix']}",
f"--libdir={self.profile['libdir']}",
f"--sharedlibdir={self.profile['libdir']}",
env={
"CC": f"{self.triple}-gcc",
"AR": f"{self.triple}-ar",
"RANLIB": f"{self.triple}-ranlib",
"CFLAGS": self.profile["cflags"],
"LDFLAGS": self.profile["ldflags"],
},
)
def build(self):
self.run("make", f"-j{self.jobs}")
def install(self):
self.run("make", "install", env={"DESTDIR": str(self.dest_dir)})
+29
View File
@@ -0,0 +1,29 @@
version = "1.5.6"
revision = 1
description = "Zstandard fast lossless compression library"
license = "BSD-3-Clause"
url = "https://facebook.github.io/zstd/"
source = tarball(
url=f"https://github.com/facebook/zstd/releases/download/v{version}/zstd-{version}.tar.gz",
sha256="8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1",
)
host_deps = ["binutils", "gcc", "pkgconf"]
deps = [profile["libc"]]
def configure(self):
# zstd's top-level autotools/Makefile don't cross-compile cleanly; use the
# maintained meson port shipped under build/meson.
meson_configure(
self,
["-Dbin_programs=true", "-Dzlib=disabled", "-Dlzma=disabled", "-Dlz4=disabled"],
source_dir=self.source_dir / "build/meson",
)
def build(self):
meson_build(self)
def install(self):
meson_install(self)
+128
View File
@@ -0,0 +1,128 @@
#!/usr/bin/env bash
#
# Build a bootable initramfs from the installed package set and (optionally)
# launch it in QEMU to test the Weston desktop.
#
# Approach: the entire root filesystem is packed into a single initramfs and
# booted straight from RAM (no disk image, no loop mounts, no root needed).
# dinit runs as PID 1, brings up udev/seatd, autologins, and starts Weston.
#
# Usage:
# scripts/mkimage.sh [-C build-dir] [--run] [--mem MB]
#
# -C, --build-dir orchid build dir (default: $ORCHID_BUILD or build-x86_64)
# --out DIR output dir for artifacts (default: <build-dir>/qemu)
# --mem MB QEMU RAM in MiB (default: 4096)
# --run launch QEMU after building (otherwise just print the command)
#
# Artifacts written to <out>: rootfs/ (installed tree), vmlinuz, initramfs.cpio.gz
set -euo pipefail
here=$(cd "$(dirname "$0")/.." && pwd)
orchid="$here/orchid"
build_dir=${ORCHID_BUILD:-build-x86_64}
out=""
mem=4096
run=0
while [ $# -gt 0 ]; do
case "$1" in
-C|--build-dir) build_dir=$2; shift 2 ;;
--out) out=$2; shift 2 ;;
--mem) mem=$2; shift 2 ;;
--run) run=1; shift ;;
-h|--help) sed -n '2,20p' "$0"; exit 0 ;;
*) echo "unknown argument: $1" >&2; exit 2 ;;
esac
done
[ -d "$build_dir" ] || { echo "build dir not found: $build_dir" >&2; exit 1; }
out=${out:-$build_dir/qemu}
rootfs="$out/rootfs"
mkdir -p "$out"
echo ">> installing packages into $rootfs"
rm -rf "$rootfs"
"$orchid" install -C "$build_dir" "$rootfs"
echo ">> wiring up init"
# The kernel execs /init from an initramfs but does NOT auto-mount devtmpfs, so
# dinit would have no /dev/null to set up service stdio. This tiny bootstrap
# mounts the kernel vfs, then hands off to dinit (PID 1) which runs the rest.
mkdir -p "$rootfs"/{proc,sys,dev,run,tmp}
cat > "$rootfs/init" <<'EOF'
#!/bin/bash
export PATH=/usr/bin:/usr/sbin:/bin:/sbin
mount -t devtmpfs dev /dev 2>/dev/null || true
mount -t proc proc /proc 2>/dev/null || true
mount -t sysfs sys /sys 2>/dev/null || true
exec /sbin/init
EOF
chmod +x "$rootfs/init"
echo ">> regenerating ld.so.cache"
# Target libs are split across /lib, /usr/lib and /usr/lib64; without a cache
# the loader can't find e.g. libstdc++ for dinit (PID 1, before any service
# runs). base-files ships /etc/ld.so.conf + the /lib64 and /bin compat links;
# build the cache now from the assembled rootfs.
# Prefer the *target* ldconfig (run via the target loader) so the cache is in a
# format the target glibc loader accepts; fall back to the host ldconfig.
loader="$rootfs/lib/ld-linux-x86-64.so.2"
tgt_ldconfig="$rootfs/sbin/ldconfig"
if [ -x "$loader" ] && [ -e "$tgt_ldconfig" ]; then
"$loader" --library-path "$rootfs/lib:$rootfs/usr/lib:$rootfs/usr/lib64" \
"$tgt_ldconfig" -r "$rootfs"
elif command -v ldconfig >/dev/null; then
ldconfig -r "$rootfs"
else
echo " warning: no ldconfig available; libraries may not resolve" >&2
fi
echo ">> extracting kernel"
kernel=$(ls -1 "$rootfs"/boot/vmlinuz-* 2>/dev/null | head -n1 || true)
if [ -z "$kernel" ]; then
echo "no kernel in $rootfs/boot (build the 'linux' recipe first)" >&2
exit 1
fi
cp "$kernel" "$out/vmlinuz"
if [ ! -d "$rootfs"/lib/modules ] && [ ! -d "$rootfs"/usr/lib/modules ]; then
echo "warning: no /lib/modules in rootfs — DRM/input drivers built as" >&2
echo " modules won't load (rebuild 'linux' with modules_install)." >&2
fi
echo ">> packing initramfs"
# Pack as a newc cpio + gzip. Run from within rootfs so paths are relative.
( cd "$rootfs" && find . -print0 | cpio --null --create --format=newc --quiet ) \
| gzip -9 > "$out/initramfs.cpio.gz"
echo " initramfs: $(du -h "$out/initramfs.cpio.gz" | cut -f1)"
# Assemble the QEMU command. virtio-gpu gives Weston a DRM/KMS device; virtio
# keyboard/tablet feed libinput; serial is the console for boot logs.
kvm=()
[ -w /dev/kvm ] && kvm=(-enable-kvm -cpu host)
cmd=(
qemu-system-x86_64
"${kvm[@]}"
-m "$mem" -smp 4
-kernel "$out/vmlinuz"
-initrd "$out/initramfs.cpio.gz"
-append "console=ttyS0,115200 loglevel=6"
-device virtio-gpu-pci
-device virtio-keyboard-pci
-device virtio-tablet-pci
-display gtk,gl=on
-serial mon:stdio
)
echo ""
echo ">> QEMU command:"
printf ' %q' "${cmd[@]}"; echo
if [ "$run" -eq 1 ]; then
echo ">> launching QEMU (Ctrl-A X to quit the serial console)"
exec "${cmd[@]}"
fi
+3
View File
@@ -0,0 +1,3 @@
"""Orchid build system"""
__version__ = "0.1.0"
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/python3
import os
import sys
_HERE = os.path.dirname(os.path.realpath(__file__))
_ROOT = os.path.dirname(_HERE)
if _ROOT not in sys.path:
sys.path.insert(0, _ROOT)
from src.cli import main
raise SystemExit(main())
+134
View File
@@ -0,0 +1,134 @@
from src.container import Container
from src.recipe import Recipe
from src.source import Subpackage
def _info_args(
name: str,
version: str,
revision: int,
arch: str,
origin: str,
description: str,
license: str,
url: str,
maintainer: str,
depends: list[str],
) -> list[str]:
args = [
"--info",
f"name:{name}",
"--info",
f"version:{version}-r{revision}",
"--info",
f"arch:{arch}",
"--info",
f"origin:{origin}",
]
if description:
args += ["--info", f"description:{description}"]
if license:
args += ["--info", f"license:{license}"]
if url:
args += ["--info", f"url:{url}"]
if maintainer:
args += ["--info", f"packager:{maintainer}"]
for d in depends:
args += ["--info", f"depends:{d}"]
return args
def mkpkg_base(container: Container, recipe: Recipe, arch: str) -> None:
name = recipe.name
args = [
"apk",
"mkpkg",
"--files",
f"/dest/{name}",
"--output",
f"/pkgs/{name}-{recipe.version}-r{recipe.revision}.apk",
*_info_args(
name,
recipe.version,
recipe.revision,
arch,
recipe.name,
recipe.description,
recipe.license,
recipe.url,
recipe.maintainer,
list(recipe.deps),
),
]
container.exec(args)
def mkpkg_subpackage(
container: Container, recipe: Recipe, sub: Subpackage, arch: str
) -> None:
args = [
"apk",
"mkpkg",
"--files",
f"/dest/{sub.name}",
"--output",
f"/pkgs/{sub.name}-{recipe.version}-r{recipe.revision}.apk",
*_info_args(
sub.name,
recipe.version,
recipe.revision,
arch,
recipe.name,
sub.description,
sub.license,
sub.url,
sub.maintainer,
[recipe.name],
),
]
container.exec(args)
def index(container: Container) -> None:
container.exec_shell(
"apk mkndx --allow-untrusted -o /pkgs/Packages.adb /pkgs/*.apk"
)
def sysroot_install(container: Container, pkgs: list[str], *, initdb: bool) -> None:
if not pkgs:
return
args = [
"apk",
"add",
"--root",
"/sysroot",
"--allow-untrusted",
"--no-network",
"--repository",
"/pkgs/Packages.adb",
]
if initdb:
args.append("--initdb")
args += pkgs
container.exec(args)
def sysroot_initialized(container: Container) -> bool:
rc = container.exec(["test", "-f", "/sysroot/lib/apk/db/installed"], check=False)
return rc == 0
def split_subpackage_script(base: str, dest: str, pattern: str) -> str:
# Move matching files from /dest/<base> to /dest/<dest>, preserving dirs.
# TODO: Make this cleaner.
return (
f"set -e; "
f"cd /dest/{base}; "
f"find . -depth -path './{pattern}' -print 2>/dev/null | while IFS= read -r f; do "
f' rel="${{f#./}}"; '
f' target=/dest/{dest}/"$rel"; '
f' mkdir -p "$(dirname "$target")"; '
f' mv "$f" "$target"; '
f"done"
)
+328
View File
@@ -0,0 +1,328 @@
import os
import re
import shutil
from pathlib import Path
from src import apk, fetch, log
from src.container import Container, Mount
from src.context import RecipeContext
from src.layout import Layout
from src.profile import Profile
from src.plan import (
PHASE_STAMPS,
Plan,
stamp_dir,
stamp_token,
stamp_valid,
transitive_host_deps,
)
from src.recipe import Recipe, RecipeSet
def _container_name(*parts: str) -> str:
name = "-".join(parts)
name = re.sub(
r"[^a-zA-Z0-9_.-]",
lambda m: f"_{ord(m.group(0)):02x}",
name,
)
if not name or not name[0].isalnum():
name = f"orchid-{name}"
return name
def _source_tree(layout: Layout, r: Recipe, key: str | None) -> Path:
base = layout.source_tree(r.name, r.version)
if len(r.sources) == 1:
return base
if key is None:
raise ValueError(f"{r.name}: multi-source entries must be named")
return base / key
def _prepare_all_sources(layout: Layout, r: Recipe, *, strict: bool = False) -> None:
for key, src in r.sources.items():
tree = _source_tree(layout, r, key)
tree.parent.mkdir(parents=True, exist_ok=True)
fetch.prepare_source(layout, r.dir, src, tree, strict=strict)
def _build_path_env(host_deps_order: list[str], layout: Layout) -> str:
parts: list[str] = []
for h in reversed(host_deps_order):
parts += [
f"/tools/{h}/sbin",
f"/tools/{h}/bin",
]
parts += [
"/usr/local/sbin",
"/usr/local/bin",
"/usr/sbin",
"/usr/bin",
"/sbin",
"/bin",
]
return ":".join(parts)
def _container_for(
rs: RecipeSet, layout: Layout, profile: Profile, r: Recipe
) -> tuple[Container, list[str]]:
host_order = transitive_host_deps(rs, r)
name = _container_name("orchid", layout.build.name, r.kind, r.name)
mounts: list[Mount] = []
tmpfs: list[str] = ["/sysroot"]
# sources
if len(r.sources) == 1:
key = next(iter(r.sources.keys()))
mounts.append(Mount(_source_tree(layout, r, key), "/sources", readonly=True))
else:
for k in r.sources.keys():
mounts.append(
Mount(_source_tree(layout, r, k), f"/sources/{k}", readonly=True)
)
# build dir
wd = layout.build_workdir(r.name if r.kind == "target" else f"host-{r.name}")
wd.mkdir(parents=True, exist_ok=True)
mounts.append(Mount(wd, "/build", readonly=False))
# files dir
if r.files_dir is not None:
mounts.append(Mount(r.files_dir, "/files", readonly=True))
# tools
for h in host_order:
mounts.append(Mount(layout.host_pkg_dir(h), f"/tools/{h}", readonly=True))
# pkgs (produced packages persist on disk); sysroot lives in tmpfs
mounts.append(Mount(layout.pkgs_dir, "/pkgs", readonly=False))
env = {
"PATH": _build_path_env(host_order, layout),
"ORCHID_ARCH": profile.arch,
"ORCHID_TRIPLE": profile.triple,
"ORCHID_JOBS": str(os.cpu_count() or 1),
}
c = Container(
name=name,
image=profile.container_image,
mounts=mounts,
tmpfs=tmpfs,
network=False,
extra_env=env,
)
return c, host_order
def _recipe_ref(r: Recipe) -> str:
return f"{r.key} ({r.version}-r{r.revision})"
def _mark_stamp(layout: Layout, r: Recipe, phase: str) -> None:
name = PHASE_STAMPS.get(phase)
if name is None:
return
d = stamp_dir(layout, r)
d.mkdir(parents=True, exist_ok=True)
(d / name).write_text(stamp_token(r))
def _clear_stamps(layout: Layout, r: Recipe) -> None:
d = stamp_dir(layout, r)
if d.is_dir():
shutil.rmtree(d)
def _wipe_workdir(layout: Layout, r: Recipe) -> None:
wd = layout.build_workdir(r.name if r.kind == "target" else f"host-{r.name}")
if wd.is_dir():
shutil.rmtree(wd)
def _run_phases(ctx: RecipeContext, r: Recipe, layout: Layout) -> None:
for phase in ("prepare", "configure", "build"):
fn = r.phases.get(phase)
if fn is None:
continue
if stamp_valid(layout, r, phase):
log.info_field(phase, f"{_recipe_ref(r)} (cached)")
continue
log.info_field(phase, _recipe_ref(r))
fn(ctx)
_mark_stamp(layout, r, phase)
def _do_install(ctx: RecipeContext, r: Recipe) -> None:
fn = r.phases.get("install")
if fn is None:
return
log.info_field("install", _recipe_ref(r))
ctx._dest_output = r.name
try:
fn(ctx)
finally:
ctx._dest_output = None
def _split_subpackages(c: Container, r: Recipe) -> None:
for sub in r.subpackages:
c.exec(["mkdir", "-p", f"/dest/{sub.name}"])
for pat in sub.files:
c.exec_shell(apk.split_subpackage_script(r.name, sub.name, pat))
def _package_target(c: Container, r: Recipe, arch: str) -> None:
apk.mkpkg_base(c, r, arch)
for sub in r.subpackages:
apk.mkpkg_subpackage(c, r, sub, arch)
apk.index(c)
def _finalize_host(c: Container, layout: Layout, r: Recipe) -> None:
import subprocess
out = layout.host_pkg_dir(r.name)
if out.exists():
shutil.rmtree(out)
out.mkdir(parents=True)
p1 = subprocess.Popen(
[
"podman",
"exec",
c.name,
"sh",
"-c",
f"cd /dest/{r.name}/tools/{r.name} && tar -cf - .",
],
stdout=subprocess.PIPE,
)
p2 = subprocess.Popen(["tar", "-xf", "-", "-C", str(out)], stdin=p1.stdout)
if p1.stdout is not None:
p1.stdout.close()
rc = p2.wait()
p1.wait()
if rc != 0 or p1.returncode != 0:
raise RuntimeError(f"host {r.name}: copy-out failed")
layout.host_pkg_marker(r.name, r.version, r.revision).write_text("ok\n")
def _target_output_index(rs: RecipeSet) -> dict[str, Recipe]:
"""Map every installable target package name (incl. subpackages) to its recipe."""
idx: dict[str, Recipe] = {}
for rec in rs.target.values():
for out in rec.outputs:
idx[out] = rec
return idx
def _transitive_runtime_deps(rs: RecipeSet, r: Recipe) -> list[str]:
"""Full closure of `r`'s deps, so the sysroot carries everything its
dependencies need (e.g. pkg-config Requires.private / linked SONAMEs).
Starts from `r`'s direct deps + build_deps and follows each package's own
`deps`. Unknown names (external packages, subpackages we can't resolve) are
still installed but not recursed into.
"""
idx = _target_output_index(rs)
order: list[str] = []
visited: set[str] = set()
def visit(name: str) -> None:
if name in visited:
return
visited.add(name)
order.append(name)
dep_recipe = idx.get(name)
if dep_recipe is not None and dep_recipe.name != r.name:
for d in dep_recipe.deps:
visit(d)
for name in (*r.deps, *r.build_deps):
visit(name)
return order
def _sysroot_sync(c: Container, rs: RecipeSet, r: Recipe) -> None:
pkgs = _transitive_runtime_deps(rs, r)
if not pkgs:
return
initdb = not apk.sysroot_initialized(c)
apk.sysroot_install(c, pkgs, initdb=initdb)
def build_one(
rs: RecipeSet,
layout: Layout,
profile: Profile,
r: Recipe,
*,
forced: bool = False,
strict: bool = False,
) -> None:
log.info_field("recipe", _recipe_ref(r))
if forced:
_clear_stamps(layout, r)
_wipe_workdir(layout, r)
_prepare_all_sources(layout, r, strict=strict)
c, _host_order = _container_for(rs, layout, profile, r)
c.start()
try:
# Ensure base output dest dir exists.
c.exec(["mkdir", "-p", f"/dest/{r.name}"])
_sysroot_sync(c, rs, r)
ctx = RecipeContext(
recipe=r, profile=profile, container=c, jobs=os.cpu_count() or 1
)
_run_phases(ctx, r, layout)
_do_install(ctx, r)
if r.kind == "target":
log.info_field("package", _recipe_ref(r))
_split_subpackages(c, r)
_package_target(c, r, profile.arch)
else:
log.info_field("finalize", _recipe_ref(r))
_finalize_host(c, layout, r)
finally:
c.stop()
log.ok_field("done", _recipe_ref(r))
def execute(
plan: Plan, rs: RecipeSet, layout: Layout, profile: Profile, *, strict: bool = False
) -> None:
if not plan.order:
log.info_field("plan", "nothing to do")
return
for k in plan.order:
r = plan.recipes[k]
build_one(rs, layout, profile, r, forced=k in plan.forced, strict=strict)
def install_to(
layout: Layout,
profile: Profile,
dest: Path,
pkgs: list[str],
*,
initdb: bool = True,
) -> None:
if not pkgs:
log.info_field("install", "nothing to install")
return
c = Container(
name=_container_name("orchid", layout.build.name, "install"),
image=profile.container_image,
mounts=[
Mount(layout.pkgs_dir, "/pkgs", readonly=True),
Mount(dest, "/sysroot", readonly=False),
],
network=False,
)
c.start()
try:
log.info_field("install", f"{dest}: {', '.join(pkgs)}")
apk.sysroot_install(c, pkgs, initdb=initdb)
finally:
c.stop()

Some files were not shown because too many files have changed in this diff Show More