internal/rosa: busybox from source
All checks were successful
Test / Create distribution (push) Successful in 50s
Test / Sandbox (push) Successful in 2m57s
Test / ShareFS (push) Successful in 4m48s
Test / Sandbox (race detector) (push) Successful in 5m25s
Test / Hpkg (push) Successful in 5m33s
Test / Hakurei (push) Successful in 5m48s
Test / Hakurei (race detector) (push) Successful in 7m48s
Test / Flake checks (push) Successful in 1m43s

This will be part of the standard toolchain.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-01-19 01:12:47 +09:00
parent 2df913999b
commit 823f9c76a7

View File

@@ -5,6 +5,8 @@ import (
"io" "io"
"net/http" "net/http"
"os" "os"
"slices"
"strings"
"time" "time"
"hakurei.app/container/fhs" "hakurei.app/container/fhs"
@@ -97,3 +99,260 @@ func newBusyboxBin() pkg.Artifact {
)}), )}),
) )
} }
// NewBusybox returns a [pkg.Artifact] containing a dynamically linked busybox
// installation usable within the [Toolchain] it is compiled against.
func (t Toolchain) NewBusybox() pkg.Artifact {
const (
version = "1.37.0"
checksum = "Ial94Tnt7esJ_YEeb0AxunVL6MGYFyOw7Rtu2o87CXCi1TLrc6rlznVsN1rZk7it"
)
extra := []pkg.Artifact{
t.NewMake(),
t.NewKernelHeaders(),
}
var env []string
if t == toolchainStage3 {
extra = nil
env = append(env, "EXTRA_LDFLAGS=-static")
}
return t.New("busybox-"+version, extra, nil, slices.Concat([]string{
"ROSA_BUSYBOX_ENABLE=" + strings.Join([]string{
"STATIC",
"PIE",
}, " "),
"ROSA_BUSYBOX_DISABLE=" + strings.Join([]string{
"FEATURE_IPV6",
"FEATURE_PREFER_IPV4_ADDRESS",
"FEATURE_HWIB",
"ARP",
"ARPING",
"BRCTL",
"FEATURE_BRCTL_FANCY",
"FEATURE_BRCTL_SHOW",
"DNSD",
"ETHER_WAKE",
"FTPD",
"FEATURE_FTPD_WRITE",
"FEATURE_FTPD_ACCEPT_BROKEN_LIST",
"FEATURE_FTPD_AUTHENTICATION",
"FTPGET",
"FTPPUT",
"FEATURE_FTPGETPUT_LONG_OPTIONS",
"HOSTNAME",
"DNSDOMAINNAME",
"HTTPD",
"FEATURE_HTTPD_PORT_DEFAULT",
"FEATURE_HTTPD_RANGES",
"FEATURE_HTTPD_SETUID",
"FEATURE_HTTPD_BASIC_AUTH",
"FEATURE_HTTPD_AUTH_MD5",
"FEATURE_HTTPD_CGI",
"FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR",
"FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV",
"FEATURE_HTTPD_ENCODE_URL_STR",
"FEATURE_HTTPD_ERROR_PAGES",
"FEATURE_HTTPD_PROXY",
"FEATURE_HTTPD_GZIP",
"FEATURE_HTTPD_ETAG",
"FEATURE_HTTPD_LAST_MODIFIED",
"FEATURE_HTTPD_DATE",
"FEATURE_HTTPD_ACL_IP",
"IFCONFIG",
"FEATURE_IFCONFIG_STATUS",
"FEATURE_IFCONFIG_SLIP",
"FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ",
"FEATURE_IFCONFIG_HW",
"FEATURE_IFCONFIG_BROADCAST_PLUS",
"IFENSLAVE",
"IFPLUGD",
"IFUP",
"IFDOWN",
"IFUPDOWN_IFSTATE_PATH",
"FEATURE_IFUPDOWN_IP",
"FEATURE_IFUPDOWN_IPV4",
"FEATURE_IFUPDOWN_IPV6",
"FEATURE_IFUPDOWN_MAPPING",
"INETD",
"FEATURE_INETD_SUPPORT_BUILTIN_ECHO",
"FEATURE_INETD_SUPPORT_BUILTIN_DISCARD",
"FEATURE_INETD_SUPPORT_BUILTIN_TIME",
"FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME",
"FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN",
"IP",
"IPADDR",
"IPLINK",
"IPROUTE",
"IPTUNNEL",
"IPRULE",
"IPNEIGH",
"FEATURE_IP_ADDRESS",
"FEATURE_IP_LINK",
"FEATURE_IP_LINK_CAN",
"FEATURE_IP_ROUTE",
"FEATURE_IP_ROUTE_DIR",
"FEATURE_IP_TUNNEL",
"FEATURE_IP_RULE",
"FEATURE_IP_NEIGH",
"IPCALC",
"FEATURE_IPCALC_LONG_OPTIONS",
"FEATURE_IPCALC_FANCY",
"FAKEIDENTD",
"NAMEIF",
"FEATURE_NAMEIF_EXTENDED",
"NBDCLIENT",
"NC",
"NC_SERVER",
"NC_EXTRA",
"NC_110_COMPAT",
"NETSTAT",
"FEATURE_NETSTAT_WIDE",
"FEATURE_NETSTAT_PRG",
"NSLOOKUP",
"FEATURE_NSLOOKUP_BIG",
"FEATURE_NSLOOKUP_LONG_OPTIONS",
"NTPD",
"FEATURE_NTPD_SERVER",
"FEATURE_NTPD_CONF",
"FEATURE_NTP_AUTH",
"PING",
"PING6",
"FEATURE_FANCY_PING",
"PSCAN",
"ROUTE",
"SLATTACH",
"SSL_CLIENT",
"TC",
"FEATURE_TC_INGRESS",
"TCPSVD",
"UDPSVD",
"TELNET",
"FEATURE_TELNET_TTYPE",
"FEATURE_TELNET_AUTOLOGIN",
"FEATURE_TELNET_WIDTH",
"TELNETD",
"FEATURE_TELNETD_STANDALONE",
"FEATURE_TELNETD_PORT_DEFAULT",
"FEATURE_TELNETD_INETD_WAIT",
"TFTP",
"FEATURE_TFTP_PROGRESS_BAR",
"FEATURE_TFTP_HPA_COMPAT",
"TFTPD",
"FEATURE_TFTP_GET",
"FEATURE_TFTP_PUT",
"FEATURE_TFTP_BLOCKSIZE",
"TLS",
"TRACEROUTE",
"TRACEROUTE6",
"FEATURE_TRACEROUTE_VERBOSE",
"FEATURE_TRACEROUTE_USE_ICMP",
"TUNCTL",
"FEATURE_TUNCTL_UG",
"VCONFIG",
"WGET",
"FEATURE_WGET_LONG_OPTIONS",
"FEATURE_WGET_STATUSBAR",
"FEATURE_WGET_FTP",
"FEATURE_WGET_AUTHENTICATION",
"FEATURE_WGET_TIMEOUT",
"FEATURE_WGET_HTTPS",
"FEATURE_WGET_OPENSSL",
"WHOIS",
"ZCIP",
"UDHCPD",
"FEATURE_UDHCPD_BOOTP",
"FEATURE_UDHCPD_WRITE_LEASES_EARLY",
"DHCPD_LEASES_FILE",
"DUMPLEASES",
"DHCPRELAY",
"UDHCPC",
"FEATURE_UDHCPC_ARPING",
"FEATURE_UDHCPC_SANITIZEOPT",
"UDHCPC_DEFAULT_SCRIPT",
"UDHCPC6_DEFAULT_SCRIPT",
"UDHCPC6",
"FEATURE_UDHCPC6_RFC3646",
"FEATURE_UDHCPC6_RFC4704",
"FEATURE_UDHCPC6_RFC4833",
"FEATURE_UDHCPC6_RFC5970",
}, " "),
}, env), `
config_enable() {
for ent in "$@"; do
sed "s/^# CONFIG_${ent}.*/CONFIG_${ent}=y/" -i .config
shift
done
}
config_disable() {
for ent in "$@"; do
sed "s/^CONFIG_${ent}=y/# CONFIG_${ent} is not set/" -i .config
shift
done
}
cat > /bin/gcc << EOF
exec clang \
-Wno-ignored-optimization-argument \
${ROSA_CFLAGS} \
${LDFLAGS} \
\$@
EOF
chmod +x /bin/gcc
cd /usr/src/busybox
chmod +w editors editors/awk.c
patch -p 1 < /usr/src/patches/awk-fix-literal-backslash.patch
cd "$(mktemp -d)"
make \
KBUILD_SRC=/usr/src/busybox \
-f /usr/src/busybox/Makefile \
defconfig
config_enable $ROSA_BUSYBOX_ENABLE
config_disable $ROSA_BUSYBOX_DISABLE
ln -s ../system/bin/pwd /bin/pwd || true
make CFLAGS_busybox="${LDFLAGS} ${EXTRA_LDFLAGS}" "-j$(nproc)"
mkdir -p /system/bin/ /work/bin/
cp busybox /system/bin/
mkdir -pv /work/system/bin/
busybox --install -s /work/system/bin/
cp -v busybox /work/system/bin/
ln -vs ../system/bin/hush /work/bin/sh
`, pkg.Path(AbsUsrSrc.Append("busybox"), true, pkg.NewHTTPGetTar(
&http.Client{Transport: &http.Transport{
// busybox website is really slow to respond
TLSHandshakeTimeout: 2 * time.Minute,
}},
"https://busybox.net/downloads/busybox-"+version+".tar.bz2",
mustDecode(checksum),
pkg.TarBzip2,
)), pkg.Path(
AbsUsrSrc.Append("patches", "awk-fix-literal-backslash.patch"), false,
pkg.NewFile("awk-fix-literal-backslash.patch", []byte(`diff --git a/editors/awk.c b/editors/awk.c
index 64e752f4b..40f5ba7f7 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -2636,8 +2636,13 @@ static int awk_sub(node *rn, const char *repl, int nm, var *src, var *dest /*,in
resbuf = qrealloc(resbuf, residx + replen + n, &resbufsize);
memcpy(resbuf + residx, sp + pmatch[j].rm_so - start_ofs, n);
residx += n;
- } else
+ } else {
+/* '\\' and '&' following a backslash keep its original meaning, any other
+ * occurrence of a '\\' should be treated as literal */
+ if (bslash && c != '\\' && c != '&')
+ resbuf[residx++] = '\\';
resbuf[residx++] = c;
+ }
bslash = 0;
}
}`)),
))
}