Compare commits
5 Commits
b6e18c474e
..
python
| Author | SHA1 | Date | |
|---|---|---|---|
| f51dab51db | |||
| d3c949b8a2 | |||
| afb13bb8ad | |||
| fc97bc4bb2 | |||
| 3253dfe87b |
@@ -26,6 +26,7 @@ RUN apk add --no-cache \
|
|||||||
zlib-dev \
|
zlib-dev \
|
||||||
git \
|
git \
|
||||||
pkgconf \
|
pkgconf \
|
||||||
|
kmod \
|
||||||
patchelf \
|
patchelf \
|
||||||
gperf \
|
gperf \
|
||||||
python3 \
|
python3 \
|
||||||
@@ -50,6 +51,10 @@ RUN apk add --no-cache \
|
|||||||
ninja \
|
ninja \
|
||||||
meson \
|
meson \
|
||||||
glslang \
|
glslang \
|
||||||
|
py3-jinja2 \
|
||||||
|
wayland-dev \
|
||||||
|
wayland-protocols \
|
||||||
|
glib-dev \
|
||||||
elfutils-dev \
|
elfutils-dev \
|
||||||
libffi-dev \
|
libffi-dev \
|
||||||
expat-dev \
|
expat-dev \
|
||||||
|
|||||||
+12
-21
@@ -1,4 +1,4 @@
|
|||||||
version = "20.1.0"
|
version = "22.1.6"
|
||||||
revision = 1
|
revision = 1
|
||||||
description = "LLVM compiler infrastructure with clang and lld"
|
description = "LLVM compiler infrastructure with clang and lld"
|
||||||
license = "Apache-2.0 WITH LLVM-exception"
|
license = "Apache-2.0 WITH LLVM-exception"
|
||||||
@@ -17,29 +17,20 @@ def configure(self):
|
|||||||
self.source_dir / "llvm",
|
self.source_dir / "llvm",
|
||||||
"-B",
|
"-B",
|
||||||
self.build_dir,
|
self.build_dir,
|
||||||
"-G",
|
"-GNinja",
|
||||||
"Ninja",
|
f"-DDEFAULT_SYSROOT={self.sysroot}",
|
||||||
"-DCMAKE_BUILD_TYPE=Release",
|
|
||||||
f"-DCMAKE_INSTALL_PREFIX={self.prefix}",
|
f"-DCMAKE_INSTALL_PREFIX={self.prefix}",
|
||||||
"-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra;lld",
|
"-UBUILD_SHARED_LIBS",
|
||||||
"-DLLVM_ENABLE_RUNTIMES=compiler-rt",
|
"-UENABLE_STATIC",
|
||||||
"-DLLVM_TARGETS_TO_BUILD=X86;AArch64;RISCV",
|
"-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_DEFAULT_TARGET_TRIPLE={self.triple}",
|
||||||
f"-DLLVM_HOST_TRIPLE={self.triple}",
|
f"-DLLVM_HOST_TRIPLE={self.triple}",
|
||||||
"-DLLVM_ENABLE_LIBXML2=OFF",
|
"-Wno-dev",
|
||||||
"-DLLVM_ENABLE_LIBEDIT=OFF",
|
|
||||||
"-DLLVM_ENABLE_TERMINFO=OFF",
|
|
||||||
"-DLLVM_ENABLE_ASSERTIONS=OFF",
|
|
||||||
"-DLLVM_ENABLE_PIC=ON",
|
|
||||||
"-DLLVM_BUILD_LLVM_DYLIB=ON",
|
|
||||||
"-DLLVM_LINK_LLVM_DYLIB=ON",
|
|
||||||
"-DLLVM_INSTALL_UTILS=ON",
|
|
||||||
"-DLLVM_INCLUDE_TESTS=OFF",
|
|
||||||
"-DLLVM_INCLUDE_EXAMPLES=OFF",
|
|
||||||
"-DLLVM_INCLUDE_BENCHMARKS=OFF",
|
|
||||||
"-DCLANG_DEFAULT_LINKER=lld",
|
|
||||||
"-DCLANG_DEFAULT_RTLIB=compiler-rt",
|
|
||||||
"-DCLANG_DEFAULT_CXX_STDLIB=libstdc++",
|
|
||||||
env={
|
env={
|
||||||
"CFLAGS": self.profile["host_cflags"],
|
"CFLAGS": self.profile["host_cflags"],
|
||||||
"CXXFLAGS": self.profile["host_cxxflags"],
|
"CXXFLAGS": self.profile["host_cxxflags"],
|
||||||
|
|||||||
@@ -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",
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
},
|
||||||
|
)
|
||||||
+16
-33
@@ -1,34 +1,17 @@
|
|||||||
def profile():
|
def profile(base):
|
||||||
arch = "x86_64"
|
arch = "x86_64"
|
||||||
libc = "glibc"
|
target_flags = (
|
||||||
triple = f"{arch}-orchid-linux-gnu"
|
"-march=x86-64-v3 -mtune=generic -fstack-clash-protection "
|
||||||
|
"-fstack-protector-strong -fcf-protection"
|
||||||
host_cflags = "-O2 -pipe"
|
)
|
||||||
host_cxxflags = host_cflags
|
return Profile(
|
||||||
host_ldflags = "-Wl,-O1 -Wl,--sort-common -Wl,--as-needed"
|
arch=arch,
|
||||||
|
triple=f"{arch}-orchid-linux-gnu",
|
||||||
target_flags = " -march=x86-64-v3 -mtune=generic -fstack-clash-protection -fstack-protector-strong -fcf-protection"
|
options={
|
||||||
cflags = host_cflags + target_flags
|
"libc": "glibc",
|
||||||
cxxflags = cflags
|
# Target flags build on the base host flags.
|
||||||
ldflags = host_ldflags + " -Wl,-z,now -Wl,-z,pack-relative-relocs"
|
"cflags": f"{base['host_cflags']} {target_flags}",
|
||||||
|
"cxxflags": f"{base['host_cflags']} {target_flags}",
|
||||||
return {
|
"ldflags": f"{base['host_ldflags']} -Wl,-z,now -Wl,-z,pack-relative-relocs",
|
||||||
"arch": arch,
|
},
|
||||||
"libc": libc,
|
)
|
||||||
"triple": triple,
|
|
||||||
"container_image": "localhost/orchid-builder:latest",
|
|
||||||
"host_cflags": host_cflags,
|
|
||||||
"host_cxxflags": host_cxxflags,
|
|
||||||
"host_ldflags": host_ldflags,
|
|
||||||
"cflags": cflags,
|
|
||||||
"cxxflags": cxxflags,
|
|
||||||
"ldflags": ldflags,
|
|
||||||
"prefix": "/usr",
|
|
||||||
"bindir": "/usr/bin",
|
|
||||||
"sbindir": "/usr/bin",
|
|
||||||
"libdir": "/usr/lib",
|
|
||||||
"libexecdir": "/usr/libexec",
|
|
||||||
"includedir": "/usr/include",
|
|
||||||
"sysconfdir": "/etc",
|
|
||||||
"localstatedir": "/var",
|
|
||||||
}
|
|
||||||
|
|||||||
+15
-31
@@ -1,34 +1,18 @@
|
|||||||
def profile():
|
def profile(base):
|
||||||
arch = "x86_64"
|
arch = "x86_64"
|
||||||
libc = "musl"
|
libc = "musl"
|
||||||
triple = f"{arch}-orchid-linux-{libc}"
|
target_flags = (
|
||||||
|
"-march=x86-64-v3 -mtune=generic -fstack-clash-protection "
|
||||||
host_cflags = "-O2 -pipe"
|
"-fstack-protector-strong -fcf-protection"
|
||||||
host_cxxflags = host_cflags
|
)
|
||||||
host_ldflags = "-Wl,-O1 -Wl,--sort-common -Wl,--as-needed"
|
return Profile(
|
||||||
|
arch=arch,
|
||||||
target_flags = " -march=x86-64-v3 -mtune=generic -fstack-clash-protection -fstack-protector-strong -fcf-protection"
|
triple=f"{arch}-orchid-linux-{libc}",
|
||||||
cflags = host_cflags + target_flags
|
options={
|
||||||
cxxflags = cflags
|
|
||||||
ldflags = host_ldflags + " -Wl,-z,now -Wl,-z,pack-relative-relocs"
|
|
||||||
|
|
||||||
return {
|
|
||||||
"arch": arch,
|
|
||||||
"libc": libc,
|
"libc": libc,
|
||||||
"triple": triple,
|
# Target flags build on the base host flags.
|
||||||
"container_image": "localhost/orchid-builder:latest",
|
"cflags": f"{base['host_cflags']} {target_flags}",
|
||||||
"host_cflags": host_cflags,
|
"cxxflags": f"{base['host_cflags']} {target_flags}",
|
||||||
"host_cxxflags": host_cxxflags,
|
"ldflags": f"{base['host_ldflags']} -Wl,-z,now -Wl,-z,pack-relative-relocs",
|
||||||
"host_ldflags": host_ldflags,
|
},
|
||||||
"cflags": cflags,
|
)
|
||||||
"cxxflags": cxxflags,
|
|
||||||
"ldflags": ldflags,
|
|
||||||
"prefix": "/usr",
|
|
||||||
"bindir": "/usr/bin",
|
|
||||||
"sbindir": "/usr/bin",
|
|
||||||
"libdir": "/usr/lib",
|
|
||||||
"libexecdir": "/usr/libexec",
|
|
||||||
"includedir": "/usr/include",
|
|
||||||
"sysconfdir": "/etc",
|
|
||||||
"localstatedir": "/var",
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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:
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
orchid
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
/lib
|
||||||
|
/usr/lib
|
||||||
|
/usr/lib64
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
NAME="Orchid"
|
||||||
|
PRETTY_NAME="Orchid Linux"
|
||||||
|
ID=orchid
|
||||||
|
ANSI_COLOR="0;35"
|
||||||
|
HOME_URL="https://example.invalid/"
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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'",
|
||||||
|
)
|
||||||
+10
-7
@@ -1,28 +1,31 @@
|
|||||||
version = "5.2.32"
|
version = "5.3"
|
||||||
revision = 1
|
revision = 1
|
||||||
description = "GNU Bourne-Again SHell"
|
description = "GNU Bourne-Again SHell"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
url = "https://www.gnu.org/software/bash/"
|
url = "https://www.gnu.org/software/bash/"
|
||||||
source = tarball(
|
source = tarball(
|
||||||
url=f"https://ftp.gnu.org/gnu/bash/bash-{version}.tar.gz",
|
url=f"https://ftp.gnu.org/gnu/bash/bash-{version}.tar.gz",
|
||||||
sha256="d3ef80d2b67d8cbbe4d3265c63a72c46f9b278ead6e0e06d61801b58f23f50b5",
|
sha256="0d5cd86965f869a26cf64f4b71be7b96f90a3ba8b3d74e27e8e9d9d5550f31ba",
|
||||||
)
|
)
|
||||||
host_deps = ["autoconf", "automake", "binutils", "gcc"]
|
host_deps = ["autoconf", "automake", "binutils", "gcc"]
|
||||||
deps = [profile["libc"], "ncurses", "readline"]
|
deps = [profile["libc"], "ncurses", "readline"]
|
||||||
|
|
||||||
build_if = False # TODO: Doesn't build yet
|
|
||||||
|
|
||||||
configure, build, install = autotools(
|
configure, build, install = autotools(
|
||||||
configure_args=[
|
configure_args=[
|
||||||
"--without-bash-malloc",
|
"--without-bash-malloc",
|
||||||
"--disable-nls",
|
"--disable-nls",
|
||||||
"--with-installed-readline",
|
|
||||||
"--with-curses",
|
"--with-curses",
|
||||||
"--enable-readline",
|
"--enable-readline",
|
||||||
"--with-installed-readline=/sysroot/usr", # TODO: get /sysroot from context
|
"--with-installed-readline",
|
||||||
],
|
],
|
||||||
configure_env={
|
configure_env={
|
||||||
|
"bash_cv_termcap_lib": "libtinfo",
|
||||||
"CFLAGS": profile["cflags"] + " -std=gnu17",
|
"CFLAGS": profile["cflags"] + " -std=gnu17",
|
||||||
"CFLAGS_FOR_BUILD": 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",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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"],
|
||||||
|
)
|
||||||
@@ -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
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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",
|
||||||
|
)
|
||||||
@@ -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)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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}")
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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),
|
||||||
|
)
|
||||||
@@ -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)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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"],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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()
|
||||||
@@ -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()
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
+5
-5
@@ -10,9 +10,9 @@ source = tarball(
|
|||||||
host_deps = ["autoconf", "automake", "binutils", "gcc"]
|
host_deps = ["autoconf", "automake", "binutils", "gcc"]
|
||||||
deps = [profile["libc"]]
|
deps = [profile["libc"]]
|
||||||
|
|
||||||
build_if = profile["arch"] in ("x86_64", "aarch64", "riscv64", "loongarch64")
|
build_if = profile.arch in ("x86_64", "aarch64", "riscv64", "loongarch64")
|
||||||
|
|
||||||
_arch_args = {
|
arch_args = {
|
||||||
"x86_64": [
|
"x86_64": [
|
||||||
"--enable-uefi-x86-64",
|
"--enable-uefi-x86-64",
|
||||||
"--enable-uefi-ia32",
|
"--enable-uefi-ia32",
|
||||||
@@ -25,8 +25,8 @@ _arch_args = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
configure, build, install = autotools(
|
configure, build, install = autotools(
|
||||||
configure_args=["--enable-uefi-cd", *_arch_args.get(profile["arch"], [])],
|
configure_args=["--enable-uefi-cd", *arch_args[profile.arch]],
|
||||||
configure_env={"TOOLCHAIN_FOR_TARGET": profile["triple"] + "-"},
|
configure_env={"TOOLCHAIN_FOR_TARGET": profile.triple + "-"},
|
||||||
)
|
)
|
||||||
|
|
||||||
subpackages = [
|
subpackages = [
|
||||||
@@ -40,7 +40,7 @@ subpackages = [
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
if profile["arch"] == "x86_64":
|
if profile.arch == "x86_64":
|
||||||
subpackages.append(
|
subpackages.append(
|
||||||
subpackage(
|
subpackage(
|
||||||
"limine-bios",
|
"limine-bios",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ def build(self):
|
|||||||
# Stage the source into the (writable) build dir before invoking the kernel
|
# Stage the source into the (writable) build dir before invoking the kernel
|
||||||
# build system, which is not happy with a read-only source tree.
|
# build system, which is not happy with a read-only source tree.
|
||||||
self.run("cp", "-rp", f"{self.source_dir}/.", self.build_dir)
|
self.run("cp", "-rp", f"{self.source_dir}/.", self.build_dir)
|
||||||
arch = linux_archs.get(self.profile["arch"], self.profile["arch"])
|
arch = linux_archs.get(self.arch, self.arch)
|
||||||
self.run("make", "headers_install", f"ARCH={arch}")
|
self.run("make", "headers_install", f"ARCH={arch}")
|
||||||
self.run(
|
self.run(
|
||||||
"find",
|
"find",
|
||||||
|
|||||||
+33
-3
@@ -14,8 +14,8 @@ linux_subarchs = {"x86_64": "x86"}
|
|||||||
|
|
||||||
|
|
||||||
def _make(self, *extra):
|
def _make(self, *extra):
|
||||||
arch = linux_archs.get(self.profile["arch"], self.profile["arch"])
|
arch = linux_archs.get(self.arch, self.arch)
|
||||||
subarch = linux_subarchs.get(self.profile["arch"])
|
subarch = linux_subarchs.get(self.arch)
|
||||||
subarch_arg = (f"SUBARCH={subarch}",) if subarch else ()
|
subarch_arg = (f"SUBARCH={subarch}",) if subarch else ()
|
||||||
return (
|
return (
|
||||||
"make",
|
"make",
|
||||||
@@ -30,7 +30,7 @@ def _make(self, *extra):
|
|||||||
def configure(self):
|
def configure(self):
|
||||||
self.run("cp", "-rp", f"{self.source_dir}/.", self.build_dir)
|
self.run("cp", "-rp", f"{self.source_dir}/.", self.build_dir)
|
||||||
self.run(
|
self.run(
|
||||||
"cp", self.files / f"config.{self.profile['arch']}", self.build_dir / ".config"
|
"cp", self.files / f"config.{self.arch}", self.build_dir / ".config"
|
||||||
)
|
)
|
||||||
self.run(*_make(self, "olddefconfig"))
|
self.run(*_make(self, "olddefconfig"))
|
||||||
|
|
||||||
@@ -46,3 +46,33 @@ def install(self):
|
|||||||
self.build_dir / "arch/x86/boot/bzImage",
|
self.build_dir / "arch/x86/boot/bzImage",
|
||||||
self.dest_dir / f"boot/vmlinuz-{self.version}",
|
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",
|
||||||
|
)
|
||||||
|
|||||||
@@ -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")
|
||||||
@@ -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)
|
||||||
@@ -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()
|
||||||
+10
-1
@@ -1,5 +1,5 @@
|
|||||||
version = "6.5"
|
version = "6.5"
|
||||||
revision = 1
|
revision = 2
|
||||||
description = "Terminal control library with wide-character support"
|
description = "Terminal control library with wide-character support"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
url = "https://invisible-island.net/ncurses/"
|
url = "https://invisible-island.net/ncurses/"
|
||||||
@@ -37,3 +37,12 @@ configure, build, _ = autotools(
|
|||||||
|
|
||||||
def install(self):
|
def install(self):
|
||||||
autotools_install(self, [f"DESTDIR={self.dest_dir}"])
|
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")
|
||||||
|
|||||||
+11
-4
@@ -5,7 +5,7 @@ license = "Apache-2.0"
|
|||||||
url = "https://www.openssl.org/"
|
url = "https://www.openssl.org/"
|
||||||
source = tarball(
|
source = tarball(
|
||||||
url=f"https://github.com/openssl/openssl/releases/download/openssl-{version}/openssl-{version}.tar.gz",
|
url=f"https://github.com/openssl/openssl/releases/download/openssl-{version}/openssl-{version}.tar.gz",
|
||||||
sha256="?",
|
sha256="002a2d6b30b58bf4bea46c43bdd96365aaf8daa6c428782aa4feee06da197df3",
|
||||||
)
|
)
|
||||||
host_deps = ["binutils", "gcc"]
|
host_deps = ["binutils", "gcc"]
|
||||||
deps = ["zlib"]
|
deps = ["zlib"]
|
||||||
@@ -18,9 +18,9 @@ ossl_targets = {
|
|||||||
|
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
target = ossl_targets.get(self.profile["arch"])
|
target = ossl_targets.get(self.arch)
|
||||||
if target is None:
|
if target is None:
|
||||||
raise ValueError(f"openssl: unsupported arch {self.profile['arch']}")
|
raise ValueError(f"openssl: unsupported arch {self.arch}")
|
||||||
|
|
||||||
self.run(
|
self.run(
|
||||||
self.source_dir / "Configure",
|
self.source_dir / "Configure",
|
||||||
@@ -48,6 +48,13 @@ def build(self):
|
|||||||
|
|
||||||
|
|
||||||
def install(self):
|
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(
|
self.run(
|
||||||
"make", "install_sw", "install_ssldirs", env={"DESTDIR": str(self.dest_dir)}
|
"make",
|
||||||
|
"install_sw",
|
||||||
|
"install_ssldirs",
|
||||||
|
f"DESTDIR={self.dest_dir}",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
version = "3.3.3"
|
version = "2.5.1"
|
||||||
revision = 1
|
revision = 1
|
||||||
description = "Lightweight pkg-config implementation"
|
description = "Lightweight pkg-config implementation"
|
||||||
license = "ISC"
|
license = "ISC"
|
||||||
url = "http://pkgconf.org/"
|
url = "http://pkgconf.org/"
|
||||||
source = tarball(
|
source = tarball(
|
||||||
url=f"https://distfiles.ariadne.space/pkgconf/pkgconf-{version}.tar.xz",
|
url=f"https://distfiles.ariadne.space/pkgconf/pkgconf-{version}.tar.xz",
|
||||||
sha256="?",
|
sha256="cd05c9589b9f86ecf044c10a2269822bc9eb001eced2582cfffd658b0a50c243",
|
||||||
)
|
)
|
||||||
host_deps = ["autoconf", "automake", "binutils", "gcc"]
|
host_deps = ["autoconf", "automake", "binutils", "gcc"]
|
||||||
deps = [profile["libc"]]
|
deps = [profile["libc"]]
|
||||||
|
|||||||
+5
-5
@@ -1,19 +1,19 @@
|
|||||||
version = "8.2"
|
version = "8.3"
|
||||||
revision = 1
|
revision = 1
|
||||||
description = "Library for command-line editing"
|
description = "Library for command-line editing"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
url = "https://tiswww.case.edu/php/chet/readline/rltop.html"
|
url = "https://tiswww.case.edu/php/chet/readline/rltop.html"
|
||||||
source = tarball(
|
source = tarball(
|
||||||
url=f"https://ftp.gnu.org/gnu/readline/readline-{version}.tar.gz",
|
url=f"https://ftp.gnu.org/gnu/readline/readline-{version}.tar.gz",
|
||||||
sha256="3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35",
|
sha256="fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc",
|
||||||
)
|
)
|
||||||
host_deps = ["autoconf", "automake", "binutils", "gcc"]
|
host_deps = ["autoconf", "automake", "binutils", "gcc"]
|
||||||
deps = [profile["libc"], "ncurses"]
|
deps = [profile["libc"], "ncurses"]
|
||||||
|
|
||||||
configure, build, _ = autotools(
|
configure, build, _ = autotools(
|
||||||
configure_args=["--with-curses"],
|
configure_args=["--with-curses", "--with-shared-termcap-library"],
|
||||||
# Force linking against system ncurses, not readline's internal termcap stub.
|
# Force linking against system terminfo, not readline's internal termcap stub.
|
||||||
configure_env={"bash_cv_termcap_lib": "ncursesw"},
|
configure_env={"bash_cv_termcap_lib": "libtinfo"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
)
|
||||||
@@ -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}/")
|
||||||
@@ -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",
|
||||||
|
)
|
||||||
|
|
||||||
@@ -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"],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -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"],
|
||||||
|
)
|
||||||
+1
-1
@@ -5,7 +5,7 @@ license = "Zlib"
|
|||||||
url = "https://zlib.net/"
|
url = "https://zlib.net/"
|
||||||
source = tarball(
|
source = tarball(
|
||||||
url=f"https://github.com/madler/zlib/releases/download/v{version}/zlib-{version}.tar.gz",
|
url=f"https://github.com/madler/zlib/releases/download/v{version}/zlib-{version}.tar.gz",
|
||||||
sha256="?",
|
sha256="bb329a0a2cd0274d05519d61c667c062e06990d72e125ee2dfa8de64f0119d16",
|
||||||
)
|
)
|
||||||
host_deps = ["binutils", "gcc"]
|
host_deps = ["binutils", "gcc"]
|
||||||
deps = [profile["libc"]]
|
deps = [profile["libc"]]
|
||||||
|
|||||||
@@ -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)
|
||||||
Executable
+128
@@ -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
|
||||||
+1
-2
@@ -40,7 +40,6 @@ def _info_args(
|
|||||||
|
|
||||||
def mkpkg_base(container: Container, recipe: Recipe, arch: str) -> None:
|
def mkpkg_base(container: Container, recipe: Recipe, arch: str) -> None:
|
||||||
name = recipe.name
|
name = recipe.name
|
||||||
deps = list(recipe.deps) + list(recipe.run_deps)
|
|
||||||
args = [
|
args = [
|
||||||
"apk",
|
"apk",
|
||||||
"mkpkg",
|
"mkpkg",
|
||||||
@@ -58,7 +57,7 @@ def mkpkg_base(container: Container, recipe: Recipe, arch: str) -> None:
|
|||||||
recipe.license,
|
recipe.license,
|
||||||
recipe.url,
|
recipe.url,
|
||||||
recipe.maintainer,
|
recipe.maintainer,
|
||||||
deps,
|
list(recipe.deps),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
container.exec(args)
|
container.exec(args)
|
||||||
|
|||||||
+63
-18
@@ -7,6 +7,7 @@ from src import apk, fetch, log
|
|||||||
from src.container import Container, Mount
|
from src.container import Container, Mount
|
||||||
from src.context import RecipeContext
|
from src.context import RecipeContext
|
||||||
from src.layout import Layout
|
from src.layout import Layout
|
||||||
|
from src.profile import Profile
|
||||||
from src.plan import (
|
from src.plan import (
|
||||||
PHASE_STAMPS,
|
PHASE_STAMPS,
|
||||||
Plan,
|
Plan,
|
||||||
@@ -39,11 +40,11 @@ def _source_tree(layout: Layout, r: Recipe, key: str | None) -> Path:
|
|||||||
return base / key
|
return base / key
|
||||||
|
|
||||||
|
|
||||||
def _prepare_all_sources(layout: Layout, r: Recipe) -> None:
|
def _prepare_all_sources(layout: Layout, r: Recipe, *, strict: bool = False) -> None:
|
||||||
for key, src in r.sources.items():
|
for key, src in r.sources.items():
|
||||||
tree = _source_tree(layout, r, key)
|
tree = _source_tree(layout, r, key)
|
||||||
tree.parent.mkdir(parents=True, exist_ok=True)
|
tree.parent.mkdir(parents=True, exist_ok=True)
|
||||||
fetch.prepare_source(layout, r.dir, src, tree)
|
fetch.prepare_source(layout, r.dir, src, tree, strict=strict)
|
||||||
|
|
||||||
|
|
||||||
def _build_path_env(host_deps_order: list[str], layout: Layout) -> str:
|
def _build_path_env(host_deps_order: list[str], layout: Layout) -> str:
|
||||||
@@ -65,7 +66,7 @@ def _build_path_env(host_deps_order: list[str], layout: Layout) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def _container_for(
|
def _container_for(
|
||||||
rs: RecipeSet, layout: Layout, profile: dict, r: Recipe
|
rs: RecipeSet, layout: Layout, profile: Profile, r: Recipe
|
||||||
) -> tuple[Container, list[str]]:
|
) -> tuple[Container, list[str]]:
|
||||||
host_order = transitive_host_deps(rs, r)
|
host_order = transitive_host_deps(rs, r)
|
||||||
name = _container_name("orchid", layout.build.name, r.kind, r.name)
|
name = _container_name("orchid", layout.build.name, r.kind, r.name)
|
||||||
@@ -96,13 +97,13 @@ def _container_for(
|
|||||||
|
|
||||||
env = {
|
env = {
|
||||||
"PATH": _build_path_env(host_order, layout),
|
"PATH": _build_path_env(host_order, layout),
|
||||||
"ORCHID_ARCH": profile["arch"],
|
"ORCHID_ARCH": profile.arch,
|
||||||
"ORCHID_TRIPLE": profile["triple"],
|
"ORCHID_TRIPLE": profile.triple,
|
||||||
"ORCHID_JOBS": str(os.cpu_count() or 1),
|
"ORCHID_JOBS": str(os.cpu_count() or 1),
|
||||||
}
|
}
|
||||||
c = Container(
|
c = Container(
|
||||||
name=name,
|
name=name,
|
||||||
image=profile["container_image"],
|
image=profile.container_image,
|
||||||
mounts=mounts,
|
mounts=mounts,
|
||||||
tmpfs=tmpfs,
|
tmpfs=tmpfs,
|
||||||
network=False,
|
network=False,
|
||||||
@@ -203,22 +204,64 @@ def _finalize_host(c: Container, layout: Layout, r: Recipe) -> None:
|
|||||||
layout.host_pkg_marker(r.name, r.version, r.revision).write_text("ok\n")
|
layout.host_pkg_marker(r.name, r.version, r.revision).write_text("ok\n")
|
||||||
|
|
||||||
|
|
||||||
def _sysroot_sync(c: Container, r: Recipe) -> None:
|
def _target_output_index(rs: RecipeSet) -> dict[str, Recipe]:
|
||||||
direct_deps = list(r.deps)
|
"""Map every installable target package name (incl. subpackages) to its recipe."""
|
||||||
if not direct_deps:
|
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
|
return
|
||||||
initdb = not apk.sysroot_initialized(c)
|
initdb = not apk.sysroot_initialized(c)
|
||||||
apk.sysroot_install(c, direct_deps, initdb=initdb)
|
apk.sysroot_install(c, pkgs, initdb=initdb)
|
||||||
|
|
||||||
|
|
||||||
def build_one(
|
def build_one(
|
||||||
rs: RecipeSet, layout: Layout, profile: dict, r: Recipe, *, forced: bool = False
|
rs: RecipeSet,
|
||||||
|
layout: Layout,
|
||||||
|
profile: Profile,
|
||||||
|
r: Recipe,
|
||||||
|
*,
|
||||||
|
forced: bool = False,
|
||||||
|
strict: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
log.info_field("recipe", _recipe_ref(r))
|
log.info_field("recipe", _recipe_ref(r))
|
||||||
if forced:
|
if forced:
|
||||||
_clear_stamps(layout, r)
|
_clear_stamps(layout, r)
|
||||||
_wipe_workdir(layout, r)
|
_wipe_workdir(layout, r)
|
||||||
_prepare_all_sources(layout, r)
|
_prepare_all_sources(layout, r, strict=strict)
|
||||||
|
|
||||||
c, _host_order = _container_for(rs, layout, profile, r)
|
c, _host_order = _container_for(rs, layout, profile, r)
|
||||||
c.start()
|
c.start()
|
||||||
@@ -226,7 +269,7 @@ def build_one(
|
|||||||
# Ensure base output dest dir exists.
|
# Ensure base output dest dir exists.
|
||||||
c.exec(["mkdir", "-p", f"/dest/{r.name}"])
|
c.exec(["mkdir", "-p", f"/dest/{r.name}"])
|
||||||
|
|
||||||
_sysroot_sync(c, r)
|
_sysroot_sync(c, rs, r)
|
||||||
|
|
||||||
ctx = RecipeContext(
|
ctx = RecipeContext(
|
||||||
recipe=r, profile=profile, container=c, jobs=os.cpu_count() or 1
|
recipe=r, profile=profile, container=c, jobs=os.cpu_count() or 1
|
||||||
@@ -237,7 +280,7 @@ def build_one(
|
|||||||
if r.kind == "target":
|
if r.kind == "target":
|
||||||
log.info_field("package", _recipe_ref(r))
|
log.info_field("package", _recipe_ref(r))
|
||||||
_split_subpackages(c, r)
|
_split_subpackages(c, r)
|
||||||
_package_target(c, r, profile["arch"])
|
_package_target(c, r, profile.arch)
|
||||||
else:
|
else:
|
||||||
log.info_field("finalize", _recipe_ref(r))
|
log.info_field("finalize", _recipe_ref(r))
|
||||||
_finalize_host(c, layout, r)
|
_finalize_host(c, layout, r)
|
||||||
@@ -246,18 +289,20 @@ def build_one(
|
|||||||
log.ok_field("done", _recipe_ref(r))
|
log.ok_field("done", _recipe_ref(r))
|
||||||
|
|
||||||
|
|
||||||
def execute(plan: Plan, rs: RecipeSet, layout: Layout, profile: dict) -> None:
|
def execute(
|
||||||
|
plan: Plan, rs: RecipeSet, layout: Layout, profile: Profile, *, strict: bool = False
|
||||||
|
) -> None:
|
||||||
if not plan.order:
|
if not plan.order:
|
||||||
log.info_field("plan", "nothing to do")
|
log.info_field("plan", "nothing to do")
|
||||||
return
|
return
|
||||||
for k in plan.order:
|
for k in plan.order:
|
||||||
r = plan.recipes[k]
|
r = plan.recipes[k]
|
||||||
build_one(rs, layout, profile, r, forced=k in plan.forced)
|
build_one(rs, layout, profile, r, forced=k in plan.forced, strict=strict)
|
||||||
|
|
||||||
|
|
||||||
def install_to(
|
def install_to(
|
||||||
layout: Layout,
|
layout: Layout,
|
||||||
profile: dict,
|
profile: Profile,
|
||||||
dest: Path,
|
dest: Path,
|
||||||
pkgs: list[str],
|
pkgs: list[str],
|
||||||
*,
|
*,
|
||||||
@@ -268,7 +313,7 @@ def install_to(
|
|||||||
return
|
return
|
||||||
c = Container(
|
c = Container(
|
||||||
name=_container_name("orchid", layout.build.name, "install"),
|
name=_container_name("orchid", layout.build.name, "install"),
|
||||||
image=profile["container_image"],
|
image=profile.container_image,
|
||||||
mounts=[
|
mounts=[
|
||||||
Mount(layout.pkgs_dir, "/pkgs", readonly=True),
|
Mount(layout.pkgs_dir, "/pkgs", readonly=True),
|
||||||
Mount(dest, "/sysroot", readonly=False),
|
Mount(dest, "/sysroot", readonly=False),
|
||||||
|
|||||||
+15
-5
@@ -50,7 +50,7 @@ def cmd_image(args) -> int:
|
|||||||
layout.ensure()
|
layout.ensure()
|
||||||
prof = profile_mod.load_profile(layout)
|
prof = profile_mod.load_profile(layout)
|
||||||
container.ensure_image(
|
container.ensure_image(
|
||||||
layout.dockerfile, prof["container_image"], layout.image_hash_file
|
layout.dockerfile, prof.container_image, layout.image_hash_file
|
||||||
)
|
)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -115,12 +115,12 @@ def cmd_build(args) -> int:
|
|||||||
layout.ensure()
|
layout.ensure()
|
||||||
prof, rs = _load(layout)
|
prof, rs = _load(layout)
|
||||||
container.ensure_image(
|
container.ensure_image(
|
||||||
layout.dockerfile, prof["container_image"], layout.image_hash_file
|
layout.dockerfile, prof.container_image, layout.image_hash_file
|
||||||
)
|
)
|
||||||
p = plan.build_plan(rs, layout, args.recipes or None, rebuild=args.rebuild)
|
p = plan.build_plan(rs, layout, args.recipes or None, rebuild=args.rebuild)
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
return cmd_plan(args)
|
return cmd_plan(args)
|
||||||
builder.execute(p, rs, layout, prof)
|
builder.execute(p, rs, layout, prof, strict=args.strict)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ def cmd_install(args) -> int:
|
|||||||
layout.ensure()
|
layout.ensure()
|
||||||
prof, rs = _load(layout)
|
prof, rs = _load(layout)
|
||||||
container.ensure_image(
|
container.ensure_image(
|
||||||
layout.dockerfile, prof["container_image"], layout.image_hash_file
|
layout.dockerfile, prof.container_image, layout.image_hash_file
|
||||||
)
|
)
|
||||||
dest = Path(args.dest).resolve()
|
dest = Path(args.dest).resolve()
|
||||||
dest.mkdir(parents=True, exist_ok=True)
|
dest.mkdir(parents=True, exist_ok=True)
|
||||||
@@ -159,7 +159,7 @@ def cmd_fetch(args) -> int:
|
|||||||
for k in targets:
|
for k in targets:
|
||||||
r = rs.get(k)
|
r = rs.get(k)
|
||||||
for key, src in r.sources.items():
|
for key, src in r.sources.items():
|
||||||
fetch_mod.fetch(layout, src)
|
fetch_mod.fetch(layout, src, strict=args.strict)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@@ -197,6 +197,11 @@ def make_parser() -> argparse.ArgumentParser:
|
|||||||
_common(p_build)
|
_common(p_build)
|
||||||
p_build.add_argument("--rebuild", action="store_true")
|
p_build.add_argument("--rebuild", action="store_true")
|
||||||
p_build.add_argument("-n", "--dry-run", action="store_true")
|
p_build.add_argument("-n", "--dry-run", action="store_true")
|
||||||
|
p_build.add_argument(
|
||||||
|
"--strict",
|
||||||
|
action="store_true",
|
||||||
|
help='fail on recipes with a placeholder checksum (sha256="?")',
|
||||||
|
)
|
||||||
p_build.set_defaults(func=cmd_build)
|
p_build.set_defaults(func=cmd_build)
|
||||||
|
|
||||||
p_inst = sub.add_parser(
|
p_inst = sub.add_parser(
|
||||||
@@ -221,6 +226,11 @@ def make_parser() -> argparse.ArgumentParser:
|
|||||||
|
|
||||||
p_fetch = sub.add_parser("fetch", help="fetch sources only")
|
p_fetch = sub.add_parser("fetch", help="fetch sources only")
|
||||||
_common(p_fetch)
|
_common(p_fetch)
|
||||||
|
p_fetch.add_argument(
|
||||||
|
"--strict",
|
||||||
|
action="store_true",
|
||||||
|
help='fail on recipes with a placeholder checksum (sha256="?")',
|
||||||
|
)
|
||||||
p_fetch.set_defaults(func=cmd_fetch)
|
p_fetch.set_defaults(func=cmd_fetch)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|||||||
+20
-3
@@ -1,9 +1,11 @@
|
|||||||
import os
|
import os
|
||||||
|
from collections.abc import Mapping
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from pathlib import PurePosixPath
|
from pathlib import PurePosixPath
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from src.container import Container
|
from src.container import Container
|
||||||
|
from src.profile import Profile
|
||||||
from src.recipe import Recipe
|
from src.recipe import Recipe
|
||||||
|
|
||||||
|
|
||||||
@@ -12,7 +14,7 @@ class RecipeContext:
|
|||||||
"""The `self` value passed to recipe phase functions."""
|
"""The `self` value passed to recipe phase functions."""
|
||||||
|
|
||||||
recipe: Recipe
|
recipe: Recipe
|
||||||
profile: dict
|
profile: Profile
|
||||||
container: Container
|
container: Container
|
||||||
jobs: int
|
jobs: int
|
||||||
_dest_output: str | None = None
|
_dest_output: str | None = None
|
||||||
@@ -73,13 +75,17 @@ class RecipeContext:
|
|||||||
def prefix(self) -> str:
|
def prefix(self) -> str:
|
||||||
return f"/tools/{self.name}" if self.recipe.kind == "host" else "/usr"
|
return f"/tools/{self.name}" if self.recipe.kind == "host" else "/usr"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def options(self) -> Mapping[str, Any]:
|
||||||
|
return self.profile.options
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def triple(self) -> str:
|
def triple(self) -> str:
|
||||||
return self.profile["triple"]
|
return self.profile.triple
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def arch(self) -> str:
|
def arch(self) -> str:
|
||||||
return self.profile["arch"]
|
return self.profile.arch
|
||||||
|
|
||||||
def run(
|
def run(
|
||||||
self,
|
self,
|
||||||
@@ -102,3 +108,14 @@ class RecipeContext:
|
|||||||
merged.update(env)
|
merged.update(env)
|
||||||
cwd_s = str(cwd) if cwd is not None else "/build"
|
cwd_s = str(cwd) if cwd is not None else "/build"
|
||||||
self.container.exec(flat, env=merged, cwd=cwd_s)
|
self.container.exec(flat, env=merged, cwd=cwd_s)
|
||||||
|
|
||||||
|
def write_text(self, path, content: str) -> None:
|
||||||
|
"""Write *content* to *path* inside the container.
|
||||||
|
|
||||||
|
Round-tripped through base64 so arbitrary text (quotes, newlines,
|
||||||
|
shell metacharacters) survives the shell without escaping.
|
||||||
|
"""
|
||||||
|
import base64
|
||||||
|
|
||||||
|
data = base64.b64encode(content.encode()).decode()
|
||||||
|
self.run("sh", "-c", f"echo '{data}' | base64 -d > '{path}'")
|
||||||
|
|||||||
+12
-5
@@ -26,11 +26,16 @@ def cache_lock(layout: Layout):
|
|||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
def fetch_tarball(layout: Layout, src: Tarball) -> Path:
|
def fetch_tarball(layout: Layout, src: Tarball, *, strict: bool = False) -> Path:
|
||||||
dest = layout.tarball_cache / src.sha256
|
dest = layout.tarball_cache / src.sha256
|
||||||
if dest.is_file():
|
if dest.is_file():
|
||||||
return dest
|
return dest
|
||||||
if src.sha256 == "?":
|
if src.sha256 == "?":
|
||||||
|
if strict:
|
||||||
|
raise RuntimeError(
|
||||||
|
f"{src.url}: missing checksum (sha256=\"?\") is not allowed in "
|
||||||
|
f"strict mode; pin the real sha256 in the recipe"
|
||||||
|
)
|
||||||
log.warn(f"fetching {src.url} (sha256 unknown)")
|
log.warn(f"fetching {src.url} (sha256 unknown)")
|
||||||
else:
|
else:
|
||||||
log.info(f"fetching {src.url}")
|
log.info(f"fetching {src.url}")
|
||||||
@@ -82,10 +87,10 @@ def fetch_git(layout: Layout, src: Git) -> Path:
|
|||||||
return dest
|
return dest
|
||||||
|
|
||||||
|
|
||||||
def fetch(layout: Layout, src) -> Path:
|
def fetch(layout: Layout, src, *, strict: bool = False) -> Path:
|
||||||
with cache_lock(layout):
|
with cache_lock(layout):
|
||||||
if isinstance(src, Tarball):
|
if isinstance(src, Tarball):
|
||||||
return fetch_tarball(layout, src)
|
return fetch_tarball(layout, src, strict=strict)
|
||||||
if isinstance(src, Git):
|
if isinstance(src, Git):
|
||||||
return fetch_git(layout, src)
|
return fetch_git(layout, src)
|
||||||
raise TypeError(f"unknown source type {type(src).__name__}")
|
raise TypeError(f"unknown source type {type(src).__name__}")
|
||||||
@@ -165,9 +170,11 @@ def apply_patches(tree: Path, recipe_dir: Path, patches: tuple[str, ...]) -> Non
|
|||||||
_patched_marker(tree).write_text("\n".join(patches) + "\n")
|
_patched_marker(tree).write_text("\n".join(patches) + "\n")
|
||||||
|
|
||||||
|
|
||||||
def prepare_source(layout: Layout, recipe_dir: Path, src, tree: Path) -> None:
|
def prepare_source(
|
||||||
|
layout: Layout, recipe_dir: Path, src, tree: Path, *, strict: bool = False
|
||||||
|
) -> None:
|
||||||
"""Fetch + extract + patch into `tree`. Idempotent via marker files."""
|
"""Fetch + extract + patch into `tree`. Idempotent via marker files."""
|
||||||
cache_path = fetch(layout, src)
|
cache_path = fetch(layout, src, strict=strict)
|
||||||
expected_patches = "\n".join(src.patches) + "\n" if src.patches else "\n"
|
expected_patches = "\n".join(src.patches) + "\n" if src.patches else "\n"
|
||||||
if (
|
if (
|
||||||
_patched_marker(tree).is_file()
|
_patched_marker(tree).is_file()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
def autotools_configure(self, extra_args=(), extra_env=None):
|
def autotools_configure(self, extra_args=(), extra_env=None):
|
||||||
p = self.profile
|
p = self.options
|
||||||
env = {
|
env = {
|
||||||
"CFLAGS": p.get("cflags", ""),
|
"CFLAGS": p.get("cflags", ""),
|
||||||
"CXXFLAGS": p.get("cxxflags", ""),
|
"CXXFLAGS": p.get("cxxflags", ""),
|
||||||
@@ -9,7 +9,7 @@ def autotools_configure(self, extra_args=(), extra_env=None):
|
|||||||
env.update(extra_env)
|
env.update(extra_env)
|
||||||
args = [
|
args = [
|
||||||
self.source_dir / "configure",
|
self.source_dir / "configure",
|
||||||
f"--host={p['triple']}",
|
f"--host={self.triple}",
|
||||||
f"--with-sysroot={self.sysroot}",
|
f"--with-sysroot={self.sysroot}",
|
||||||
f"--prefix={p.get('prefix', '/usr')}",
|
f"--prefix={p.get('prefix', '/usr')}",
|
||||||
f"--sysconfdir={p.get('sysconfdir', '/etc')}",
|
f"--sysconfdir={p.get('sysconfdir', '/etc')}",
|
||||||
|
|||||||
+4
-4
@@ -1,5 +1,5 @@
|
|||||||
def cmake_configure(self, extra_args=(), extra_env=None, *, host=False):
|
def cmake_configure(self, extra_args=(), extra_env=None, *, host=False):
|
||||||
p = self.profile
|
p = self.options
|
||||||
if host:
|
if host:
|
||||||
env = {
|
env = {
|
||||||
"CFLAGS": p.get("host_cflags", ""),
|
"CFLAGS": p.get("host_cflags", ""),
|
||||||
@@ -15,10 +15,10 @@ def cmake_configure(self, extra_args=(), extra_env=None, *, host=False):
|
|||||||
}
|
}
|
||||||
toolchain = [
|
toolchain = [
|
||||||
"-DCMAKE_SYSTEM_NAME=Linux",
|
"-DCMAKE_SYSTEM_NAME=Linux",
|
||||||
f"-DCMAKE_SYSTEM_PROCESSOR={p['arch']}",
|
f"-DCMAKE_SYSTEM_PROCESSOR={self.arch}",
|
||||||
f"-DCMAKE_SYSROOT={self.sysroot}",
|
f"-DCMAKE_SYSROOT={self.sysroot}",
|
||||||
f"-DCMAKE_C_COMPILER={p['triple']}-gcc",
|
f"-DCMAKE_C_COMPILER={self.triple}-gcc",
|
||||||
f"-DCMAKE_CXX_COMPILER={p['triple']}-g++",
|
f"-DCMAKE_CXX_COMPILER={self.triple}-g++",
|
||||||
"-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER",
|
"-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER",
|
||||||
"-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY",
|
"-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY",
|
||||||
"-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY",
|
"-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY",
|
||||||
|
|||||||
@@ -1,5 +1,98 @@
|
|||||||
|
# A cross `llvm-config`. The target llvm-config is a glibc binary that can't run
|
||||||
|
# on the (musl) build host, so instead of executing it we emulate the queries
|
||||||
|
# meson/mesa make, reporting paths inside the sysroot. Self-configuring: it reads
|
||||||
|
# the LLVM version, library soname, and built targets from the installed sysroot,
|
||||||
|
# so it works for any LLVM consumer (mesa now, rust/etc. later) with no hardcoding.
|
||||||
|
_LLVM_CONFIG_EMULATOR = r'''#!/usr/bin/env python3
|
||||||
|
import glob, re, sys
|
||||||
|
|
||||||
|
SYSROOT = "/sysroot"
|
||||||
|
LIBDIR = SYSROOT + "/usr/lib"
|
||||||
|
INCDIR = SYSROOT + "/usr/include"
|
||||||
|
|
||||||
|
_major = ""
|
||||||
|
for _p in sorted(glob.glob(LIBDIR + "/libLLVM-*.so*")):
|
||||||
|
_m = re.search(r"libLLVM-(\d+)", _p)
|
||||||
|
if _m:
|
||||||
|
_major = _m.group(1)
|
||||||
|
break
|
||||||
|
|
||||||
|
_version = (_major + ".0.0") if _major else "0.0.0"
|
||||||
|
try:
|
||||||
|
with open(INCDIR + "/llvm/Config/llvm-config.h") as _f:
|
||||||
|
_m = re.search(r'LLVM_VERSION_STRING\s+"([^"]+)"', _f.read())
|
||||||
|
if _m:
|
||||||
|
_version = _m.group(1)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
_targets = []
|
||||||
|
try:
|
||||||
|
with open(INCDIR + "/llvm/Config/Targets.def") as _f:
|
||||||
|
_targets = re.findall(r"LLVM_TARGET\((\w+)\)", _f.read())
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
if not _targets:
|
||||||
|
_targets = ["X86", "AMDGPU"]
|
||||||
|
|
||||||
|
_GENERIC = (
|
||||||
|
"aggressiveinstcombine all all-targets analysis asmparser asmprinter "
|
||||||
|
"binaryformat bitreader bitstreamreader bitwriter cfguard codegen "
|
||||||
|
"codegentypes core coroutines coverage debuginfocodeview debuginfodwarf "
|
||||||
|
"debuginfomsf debuginfopdb demangle dlltooldriver engine executionengine "
|
||||||
|
"extensions frontenddriver frontendhlsl frontendoffloading frontendopenmp "
|
||||||
|
"fuzzmutate globalisel instcombine instrumentation interpreter ipo irreader "
|
||||||
|
"irprinter jitlink libdriver lineeditor linker lto mc mca mcdisassembler "
|
||||||
|
"mcjit mcparser native nativecodegen object objectyaml option orcjit "
|
||||||
|
"orcshared orctargetprocess passes profiledata remarks runtimedyld "
|
||||||
|
"scalaropts selectiondag support symbolize target targetparser textapi "
|
||||||
|
"transformutils vectorize windowsdriver windowsmanifest"
|
||||||
|
).split()
|
||||||
|
|
||||||
|
|
||||||
|
def _components():
|
||||||
|
comps = list(_GENERIC)
|
||||||
|
for t in _targets:
|
||||||
|
tl = t.lower()
|
||||||
|
comps += [tl, tl + "asmparser", tl + "codegen", tl + "desc",
|
||||||
|
tl + "disassembler", tl + "info", tl + "targetmca", tl + "utils"]
|
||||||
|
return " ".join(sorted(set(comps)))
|
||||||
|
|
||||||
|
|
||||||
|
_H = {
|
||||||
|
"--version": lambda: _version,
|
||||||
|
"--components": _components,
|
||||||
|
"--targets-built": lambda: " ".join(_targets),
|
||||||
|
"--prefix": lambda: SYSROOT + "/usr",
|
||||||
|
"--bindir": lambda: SYSROOT + "/usr/bin",
|
||||||
|
"--includedir": lambda: INCDIR,
|
||||||
|
"--libdir": lambda: LIBDIR,
|
||||||
|
"--cmakedir": lambda: LIBDIR + "/cmake/llvm",
|
||||||
|
"--has-rtti": lambda: "YES",
|
||||||
|
"--shared-mode": lambda: "shared",
|
||||||
|
"--libs": lambda: "-lLLVM-" + _major,
|
||||||
|
"--system-libs": lambda: "",
|
||||||
|
"--cflags": lambda: "-I" + INCDIR,
|
||||||
|
"--cppflags": lambda: ("-I" + INCDIR
|
||||||
|
+ " -D__STDC_CONSTANT_MACROS"
|
||||||
|
+ " -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"),
|
||||||
|
"--cxxflags": lambda: ("-I" + INCDIR
|
||||||
|
+ " -D__STDC_CONSTANT_MACROS"
|
||||||
|
+ " -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"),
|
||||||
|
"--ldflags": lambda: "-L" + LIBDIR,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _a in sys.argv[1:]:
|
||||||
|
if _a in _H:
|
||||||
|
print(_H[_a]())
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
def meson_cross_file(self):
|
def meson_cross_file(self):
|
||||||
cross = self.build_dir / "meson-cross.ini"
|
cross = self.build_dir / "meson-cross.ini"
|
||||||
|
llvm_config = self.build_dir / "llvm-config"
|
||||||
|
self.write_text(llvm_config, _LLVM_CONFIG_EMULATOR)
|
||||||
|
self.run("chmod", "+x", llvm_config)
|
||||||
self.write_text(
|
self.write_text(
|
||||||
cross,
|
cross,
|
||||||
f"""\
|
f"""\
|
||||||
@@ -12,6 +105,8 @@ objcopy = '{self.triple}-objcopy'
|
|||||||
ranlib = '{self.triple}-ranlib'
|
ranlib = '{self.triple}-ranlib'
|
||||||
strip = '{self.triple}-strip'
|
strip = '{self.triple}-strip'
|
||||||
pkg-config = '{self.triple}-pkg-config'
|
pkg-config = '{self.triple}-pkg-config'
|
||||||
|
cmake = '/usr/bin/cmake'
|
||||||
|
llvm-config = '{llvm_config}'
|
||||||
|
|
||||||
[host_machine]
|
[host_machine]
|
||||||
system = 'linux'
|
system = 'linux'
|
||||||
|
|||||||
+20
-13
@@ -111,6 +111,21 @@ def build_plan(
|
|||||||
seen: dict[str, Recipe] = {}
|
seen: dict[str, Recipe] = {}
|
||||||
ts: graphlib.TopologicalSorter[str] = graphlib.TopologicalSorter()
|
ts: graphlib.TopologicalSorter[str] = graphlib.TopologicalSorter()
|
||||||
forced: set[str] = set()
|
forced: set[str] = set()
|
||||||
|
target_outputs: dict[str, Recipe] = {}
|
||||||
|
|
||||||
|
for tr in rs.target.values():
|
||||||
|
for out in tr.outputs:
|
||||||
|
if out in target_outputs:
|
||||||
|
raise ValueError(f"duplicate target output: {out}")
|
||||||
|
target_outputs[out] = tr
|
||||||
|
|
||||||
|
def target_dep(owner: str, name: str) -> Recipe:
|
||||||
|
tr = target_outputs.get(name)
|
||||||
|
if tr is None:
|
||||||
|
raise KeyError(f"{owner}: unknown target dep {name!r}")
|
||||||
|
if not tr.enabled:
|
||||||
|
raise ValueError(f"{owner}: dep {name!r} disabled by build_if")
|
||||||
|
return tr
|
||||||
|
|
||||||
def add(r: Recipe) -> None:
|
def add(r: Recipe) -> None:
|
||||||
k = _key(r)
|
k = _key(r)
|
||||||
@@ -127,22 +142,14 @@ def build_plan(
|
|||||||
add(hr)
|
add(hr)
|
||||||
deps.append(_key(hr))
|
deps.append(_key(hr))
|
||||||
if r.kind == "target":
|
if r.kind == "target":
|
||||||
for d in (*r.deps, *r.run_deps):
|
for d in (*r.deps, *r.build_deps):
|
||||||
tr = rs.target.get(d)
|
tr = target_dep(r.name, d)
|
||||||
if tr is None:
|
|
||||||
raise KeyError(f"{r.name}: unknown dep {d!r}")
|
|
||||||
if not tr.enabled:
|
|
||||||
raise ValueError(f"{r.name}: dep {d!r} disabled by build_if")
|
|
||||||
add(tr)
|
add(tr)
|
||||||
deps.append(_key(tr))
|
deps.append(_key(tr))
|
||||||
else:
|
else:
|
||||||
# host recipes may declare target `deps` that need to land in /sysroot
|
# host recipes may declare target deps that need to land in /sysroot
|
||||||
for d in r.deps:
|
for d in (*r.deps, *r.build_deps):
|
||||||
tr = rs.target.get(d)
|
tr = target_dep(f"host:{r.name}", d)
|
||||||
if tr is None:
|
|
||||||
raise KeyError(f"host:{r.name}: unknown target dep {d!r}")
|
|
||||||
if not tr.enabled:
|
|
||||||
raise ValueError(f"host:{r.name}: dep {d!r} disabled by build_if")
|
|
||||||
add(tr)
|
add(tr)
|
||||||
deps.append(_key(tr))
|
deps.append(_key(tr))
|
||||||
ts.add(k, *deps)
|
ts.add(k, *deps)
|
||||||
|
|||||||
+95
-14
@@ -1,42 +1,123 @@
|
|||||||
import importlib.util
|
import importlib.util
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from dataclasses import dataclass, field, replace
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from src.layout import Layout
|
from src.layout import Layout
|
||||||
|
|
||||||
REQUIRED_KEYS = ("arch", "triple", "container_image")
|
# Core fields identify the build target. Every resolved profile must define
|
||||||
|
# them, and they are read as attributes (profile.arch) rather than options.
|
||||||
|
CORE_FIELDS = ("arch", "triple", "container_image")
|
||||||
|
|
||||||
|
# Name of the profile that supplies defaults for every other profile.
|
||||||
|
BASE_PROFILE = "base"
|
||||||
|
|
||||||
|
_MISSING = object()
|
||||||
|
|
||||||
|
|
||||||
def _load_module(path: Path, name: str):
|
@dataclass(frozen=True)
|
||||||
|
class Profile:
|
||||||
|
"""A resolved build profile.
|
||||||
|
|
||||||
|
The *core* fields (see ``CORE_FIELDS``) identify the build target and must
|
||||||
|
be present. Everything that tunes how packages are built from source --
|
||||||
|
install layout, compiler flags, and free-form feature switches -- lives in
|
||||||
|
``options`` and is looked up by key.
|
||||||
|
"""
|
||||||
|
|
||||||
|
name: str = ""
|
||||||
|
arch: str = ""
|
||||||
|
triple: str = ""
|
||||||
|
container_image: str = ""
|
||||||
|
options: Mapping[str, Any] = field(default_factory=dict)
|
||||||
|
|
||||||
|
def option(self, key: str, default: Any = _MISSING) -> Any:
|
||||||
|
"""Return option ``key``; fall back to ``default`` or raise KeyError."""
|
||||||
|
if key in self.options:
|
||||||
|
return self.options[key]
|
||||||
|
if default is not _MISSING:
|
||||||
|
return default
|
||||||
|
if key in CORE_FIELDS:
|
||||||
|
raise KeyError(
|
||||||
|
f"profile {self.name!r}: {key!r} is a core field; "
|
||||||
|
f"access it as profile.{key}, not as an option"
|
||||||
|
)
|
||||||
|
raise KeyError(f"profile {self.name!r}: option {key!r} is not defined")
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.option(key)
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return self.option(key, default)
|
||||||
|
|
||||||
|
def overlay(self, child: "Profile") -> "Profile":
|
||||||
|
"""Layer ``child`` over ``self`` (the base) and return the result.
|
||||||
|
|
||||||
|
Core fields fall back to the base wherever the child leaves them empty;
|
||||||
|
options are merged key-by-key, with the child winning.
|
||||||
|
"""
|
||||||
|
return Profile(
|
||||||
|
name=child.name or self.name,
|
||||||
|
arch=child.arch or self.arch,
|
||||||
|
triple=child.triple or self.triple,
|
||||||
|
container_image=child.container_image or self.container_image,
|
||||||
|
options={**self.options, **child.options},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _load_module(path: Path, name: str, ns: dict):
|
||||||
spec = importlib.util.spec_from_file_location(name, path)
|
spec = importlib.util.spec_from_file_location(name, path)
|
||||||
if spec is None or spec.loader is None:
|
if spec is None or spec.loader is None:
|
||||||
raise RuntimeError(f"cannot load profile module {path}")
|
raise RuntimeError(f"cannot load profile module {path}")
|
||||||
mod = importlib.util.module_from_spec(spec)
|
mod = importlib.util.module_from_spec(spec)
|
||||||
|
mod.__dict__.update(ns)
|
||||||
spec.loader.exec_module(mod)
|
spec.loader.exec_module(mod)
|
||||||
return mod
|
return mod
|
||||||
|
|
||||||
|
|
||||||
def load_profile(layout: Layout) -> dict[str, Any]:
|
def _eval_profile(path: Path, name: str, base: "Profile | None") -> Profile:
|
||||||
|
mod = _load_module(path, f"orchid_profile_{name}", {"Profile": Profile})
|
||||||
|
if not hasattr(mod, "profile"):
|
||||||
|
raise AttributeError(f"profile {name!r}: must define profile(base)")
|
||||||
|
spec = mod.profile(base)
|
||||||
|
if not isinstance(spec, Profile):
|
||||||
|
raise TypeError(f"profile {name!r}: profile(base) must return a Profile(...)")
|
||||||
|
if not isinstance(spec.options, Mapping) or any(
|
||||||
|
not isinstance(k, str) for k in spec.options
|
||||||
|
):
|
||||||
|
raise TypeError(f"profile {name!r}: options must be a dict with string keys")
|
||||||
|
return replace(spec, name=name)
|
||||||
|
|
||||||
|
|
||||||
|
def load_profile(layout: Layout) -> Profile:
|
||||||
link = layout.profile_link
|
link = layout.profile_link
|
||||||
if not link.exists():
|
if not link.exists():
|
||||||
raise FileNotFoundError(f"{link} missing a profile")
|
raise FileNotFoundError(f"{link} missing a profile")
|
||||||
target = link.resolve()
|
target = link.resolve()
|
||||||
if not target.is_file():
|
if not target.is_file():
|
||||||
raise FileNotFoundError(f"profile {target.name}: missing config.py")
|
raise FileNotFoundError(f"profile {target.name}: missing config")
|
||||||
mod = _load_module(target, f"orchid_profile_{target.name}")
|
|
||||||
if not hasattr(mod, "profile"):
|
# The base profile is optional, but supplies defaults when present.
|
||||||
raise AttributeError(f"profile {target.name}: config.py must define profile()")
|
base = Profile(name=BASE_PROFILE)
|
||||||
data = mod.profile()
|
base_file = layout.profiles_dir / f"{BASE_PROFILE}.py"
|
||||||
if not isinstance(data, dict):
|
if base_file.is_file():
|
||||||
raise TypeError(f"profile {target.name}: profile() must return a dict")
|
base = _eval_profile(base_file, BASE_PROFILE, None)
|
||||||
missing = [k for k in REQUIRED_KEYS if k not in data]
|
|
||||||
|
child = _eval_profile(target, target.stem, base)
|
||||||
|
resolved = base.overlay(child)
|
||||||
|
|
||||||
|
missing = [f for f in CORE_FIELDS if not getattr(resolved, f)]
|
||||||
if missing:
|
if missing:
|
||||||
raise ValueError(f"profile {target.name}: missing keys {missing}")
|
raise ValueError(f"profile {resolved.name!r}: missing core fields {missing}")
|
||||||
data["__name__"] = target.name
|
return resolved
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def init_build_dir(build: Path, repo: Path, profile_name: str) -> None:
|
def init_build_dir(build: Path, repo: Path, profile_name: str) -> None:
|
||||||
|
if profile_name == BASE_PROFILE:
|
||||||
|
raise ValueError(
|
||||||
|
f"{BASE_PROFILE!r} only supplies defaults and cannot be built directly"
|
||||||
|
)
|
||||||
profile_src = repo / "profiles" / (profile_name + ".py")
|
profile_src = repo / "profiles" / (profile_name + ".py")
|
||||||
if not (profile_src).is_file():
|
if not (profile_src).is_file():
|
||||||
raise FileNotFoundError(f"profile {profile_name!r} not found at {profile_src}")
|
raise FileNotFoundError(f"profile {profile_name!r} not found at {profile_src}")
|
||||||
|
|||||||
+20
-9
@@ -8,6 +8,7 @@ from typing import Any, Callable
|
|||||||
|
|
||||||
from src import source as src_mod
|
from src import source as src_mod
|
||||||
from src.layout import Layout
|
from src.layout import Layout
|
||||||
|
from src.profile import Profile
|
||||||
from src.source import Subpackage, Tarball, subpackage, tarball, git
|
from src.source import Subpackage, Tarball, subpackage, tarball, git
|
||||||
|
|
||||||
PHASE_NAMES = ("prepare", "configure", "build", "install")
|
PHASE_NAMES = ("prepare", "configure", "build", "install")
|
||||||
@@ -28,8 +29,8 @@ class Recipe:
|
|||||||
maintainer: str
|
maintainer: str
|
||||||
sources: dict[str | None, Tarball | src_mod.Git] # key=None for single source
|
sources: dict[str | None, Tarball | src_mod.Git] # key=None for single source
|
||||||
host_deps: tuple[str, ...]
|
host_deps: tuple[str, ...]
|
||||||
|
build_deps: tuple[str, ...]
|
||||||
deps: tuple[str, ...]
|
deps: tuple[str, ...]
|
||||||
run_deps: tuple[str, ...]
|
|
||||||
subpackages: tuple[Subpackage, ...]
|
subpackages: tuple[Subpackage, ...]
|
||||||
phases: dict[str, Callable[[Any], None]]
|
phases: dict[str, Callable[[Any], None]]
|
||||||
enabled: bool
|
enabled: bool
|
||||||
@@ -79,7 +80,7 @@ def _lib_symbols() -> dict:
|
|||||||
|
|
||||||
|
|
||||||
# Symbols which are injected into the recipe
|
# Symbols which are injected into the recipe
|
||||||
def _builtins(profile: dict) -> dict:
|
def _builtins(profile: Profile) -> dict:
|
||||||
return {
|
return {
|
||||||
**_lib_symbols(),
|
**_lib_symbols(),
|
||||||
"tarball": tarball,
|
"tarball": tarball,
|
||||||
@@ -112,7 +113,12 @@ def _plain_field(mod, recipe_name: str, field_name: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def _load_one(
|
def _load_one(
|
||||||
name: str, kind: str, recipe_file: Path, recipe_dir: Path, pure: bool, profile: dict
|
name: str,
|
||||||
|
kind: str,
|
||||||
|
recipe_file: Path,
|
||||||
|
recipe_dir: Path,
|
||||||
|
pure: bool,
|
||||||
|
profile: Profile,
|
||||||
) -> Recipe | None:
|
) -> Recipe | None:
|
||||||
mod = _load_module(recipe_file, _builtins(profile))
|
mod = _load_module(recipe_file, _builtins(profile))
|
||||||
|
|
||||||
@@ -152,8 +158,8 @@ def _load_one(
|
|||||||
else:
|
else:
|
||||||
for k, v in multi_items:
|
for k, v in multi_items:
|
||||||
sources[k] = v
|
sources[k] = v
|
||||||
else:
|
# else: no source. Allowed for config-only recipes (e.g. base-files); the
|
||||||
raise ValueError(f"{name}: 'source' or 'sources' required")
|
# presence of at least one phase is validated below.
|
||||||
|
|
||||||
if pure:
|
if pure:
|
||||||
for s in sources.values():
|
for s in sources.values():
|
||||||
@@ -163,8 +169,8 @@ def _load_one(
|
|||||||
)
|
)
|
||||||
|
|
||||||
host_deps = tuple(getattr(mod, "host_deps", ()) or ())
|
host_deps = tuple(getattr(mod, "host_deps", ()) or ())
|
||||||
|
build_deps = tuple(getattr(mod, "build_deps", ()) or ())
|
||||||
deps = tuple(getattr(mod, "deps", ()) or ())
|
deps = tuple(getattr(mod, "deps", ()) or ())
|
||||||
run_deps = tuple(getattr(mod, "run_deps", ()) or ())
|
|
||||||
subs = tuple(getattr(mod, "subpackages", ()) or ())
|
subs = tuple(getattr(mod, "subpackages", ()) or ())
|
||||||
for s in subs:
|
for s in subs:
|
||||||
if not isinstance(s, Subpackage):
|
if not isinstance(s, Subpackage):
|
||||||
@@ -185,6 +191,11 @@ def _load_one(
|
|||||||
# Purely declarative pkgs are unusual but allowed
|
# Purely declarative pkgs are unusual but allowed
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if not sources and not phases:
|
||||||
|
raise ValueError(
|
||||||
|
f"{name}: define a 'source'/'sources' or at least one build phase"
|
||||||
|
)
|
||||||
|
|
||||||
enabled = bool(getattr(mod, "build_if", True))
|
enabled = bool(getattr(mod, "build_if", True))
|
||||||
|
|
||||||
return Recipe(
|
return Recipe(
|
||||||
@@ -200,15 +211,15 @@ def _load_one(
|
|||||||
maintainer=maintainer,
|
maintainer=maintainer,
|
||||||
sources=sources,
|
sources=sources,
|
||||||
host_deps=host_deps,
|
host_deps=host_deps,
|
||||||
|
build_deps=build_deps,
|
||||||
deps=deps,
|
deps=deps,
|
||||||
run_deps=run_deps,
|
|
||||||
subpackages=subs,
|
subpackages=subs,
|
||||||
phases=phases,
|
phases=phases,
|
||||||
enabled=enabled,
|
enabled=enabled,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _discover(root: Path, kind: str, profile: dict) -> dict[str, Recipe]:
|
def _discover(root: Path, kind: str, profile: Profile) -> dict[str, Recipe]:
|
||||||
out: dict[str, Recipe] = {}
|
out: dict[str, Recipe] = {}
|
||||||
if not root.is_dir():
|
if not root.is_dir():
|
||||||
return out
|
return out
|
||||||
@@ -252,7 +263,7 @@ class RecipeSet:
|
|||||||
return [*self.target.values(), *self.host.values()]
|
return [*self.target.values(), *self.host.values()]
|
||||||
|
|
||||||
|
|
||||||
def load_recipes(layout: Layout, profile: dict) -> RecipeSet:
|
def load_recipes(layout: Layout, profile: Profile) -> RecipeSet:
|
||||||
target = _discover(layout.recipes_dir, "target", profile)
|
target = _discover(layout.recipes_dir, "target", profile)
|
||||||
host = _discover(layout.host_recipes_dir, "host", profile)
|
host = _discover(layout.host_recipes_dir, "host", profile)
|
||||||
return RecipeSet(target=target, host=host)
|
return RecipeSet(target=target, host=host)
|
||||||
|
|||||||
Reference in New Issue
Block a user