0

It seems like the answer is no, I just want to make sure I'm not doing anything wrong. I can't find a way to tell Busybox .config that I want to build for musl and not glibc, but it seems the Busybox code base requires glibc extensions these days like:

gnu_dev_minor gnu_dev_major mallopt

$ export CC=/usr/local/musl/bin/musl-gcc
$ export LDFLAGS=-L/usr/local/musl/lib
$ make
  LINK    busybox_unstripped
Static linking against glibc, can't use --gc-sections
Trying libraries: crypt m resolv rt
Failed: -Wl,--start-group -lcrypt -lm -lresolv -lrt   -Wl,--end-group
Output of:
gcc -Wall -Wshadow -Wwrite-strings -Wundef -Wstrict-prototypes -Wunused -Wunused-parameter -Wunused-function -Wunused-value -Wmissing-prototypes -Wmissing-declarations -Wno-format-security -Wdeclaration-after-statement -Wold-style-definition -finline-limit=0 -fno-builtin-strlen -fomit-frame-pointer -ffunction-sections -fdata-sections -fno-guess-branch-probability -funsigned-char -static-libgcc -falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1 -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-builtin-printf -Os -static -L/usr/local/musl/lib -o busybox_unstripped -Wl,--sort-common -Wl,--sort-section,alignment -Wl,--start-group applets/built-in.o archival/lib.a archival/libarchive/lib.a console-tools/lib.a coreutils/lib.a coreutils/libcoreutils/lib.a debianutils/lib.a klibc-utils/lib.a e2fsprogs/lib.a editors/lib.a findutils/lib.a init/lib.a libbb/lib.a libpwdgrp/lib.a loginutils/lib.a mailutils/lib.a miscutils/lib.a modutils/lib.a networking/lib.a networking/libiproute/lib.a networking/udhcp/lib.a printutils/lib.a procps/lib.a runit/lib.a selinux/lib.a shell/lib.a sysklogd/lib.a util-linux/lib.a util-linux/volume_id/lib.a archival/built-in.o archival/libarchive/built-in.o console-tools/built-in.o coreutils/built-in.o coreutils/libcoreutils/built-in.o debianutils/built-in.o klibc-utils/built-in.o e2fsprogs/built-in.o editors/built-in.o findutils/built-in.o init/built-in.o libbb/built-in.o libpwdgrp/built-in.o loginutils/built-in.o mailutils/built-in.o miscutils/built-in.o modutils/built-in.o networking/built-in.o networking/libiproute/built-in.o networking/udhcp/built-in.o printutils/built-in.o procps/built-in.o runit/built-in.o selinux/built-in.o shell/built-in.o sysklogd/built-in.o util-linux/built-in.o util-linux/volume_id/built-in.o -Wl,--end-group -Wl,--start-group -lcrypt -lm -lresolv -lrt -Wl,--end-group
==========
/usr/bin/ld: libbb/lib.a(appletlib.o): in function `main':
appletlib.c:(.text.main+0x18): undefined reference to `mallopt'
/usr/bin/ld: appletlib.c:(.text.main+0x24): undefined reference to `mallopt'
/usr/bin/ld: networking/lib.a(ping.o): in function `common_ping_main.isra.0':
ping.c:(.text.common_ping_main.isra.0+0x4dc): undefined reference to `__cmsg_nxthdr'
/usr/bin/ld: networking/udhcp/lib.a(dhcpc.o): in function `d4_recv_raw_packet':
dhcpc.c:(.text.d4_recv_raw_packet+0x1c4): undefined reference to `__cmsg_nxthdr'
/usr/bin/ld: util-linux/lib.a(mdev.o): in function `initial_scan':
mdev.c:(.text.initial_scan+0x2c): undefined reference to `gnu_dev_major'
/usr/bin/ld: mdev.c:(.text.initial_scan+0x38): undefined reference to `gnu_dev_minor'
/usr/bin/ld: util-linux/lib.a(mountpoint.o): in function `mountpoint_main':
mountpoint.c:(.text.mountpoint_main+0x64): undefined reference to `gnu_dev_major'
/usr/bin/ld: mountpoint.c:(.text.mountpoint_main+0x70): undefined reference to `gnu_dev_minor'
/usr/bin/ld: mountpoint.c:(.text.mountpoint_main+0x110): undefined reference to `gnu_dev_major'
/usr/bin/ld: mountpoint.c:(.text.mountpoint_main+0x11c): undefined reference to `gnu_dev_minor'
/usr/bin/ld: util-linux/volume_id/lib.a(get_devname.o): in function `uuidcache_check_device':
get_devname.c:(.text.uuidcache_check_device+0x24): undefined reference to `gnu_dev_major'
/usr/bin/ld: archival/lib.a(cpio.o): in function `cpio_o':
cpio.c:(.text.cpio_o+0x25c): undefined reference to `gnu_dev_major'
/usr/bin/ld: cpio.c:(.text.cpio_o+0x268): undefined reference to `gnu_dev_minor'
/usr/bin/ld: cpio.c:(.text.cpio_o+0x27c): undefined reference to `gnu_dev_major'
/usr/bin/ld: cpio.c:(.text.cpio_o+0x290): undefined reference to `gnu_dev_minor'
/usr/bin/ld: archival/lib.a(tar.o): in function `writeTarHeader':
tar.c:(.text.writeTarHeader+0x24c): undefined reference to `gnu_dev_major'
/usr/bin/ld: tar.c:(.text.writeTarHeader+0x264): undefined reference to `gnu_dev_minor'
/usr/bin/ld: coreutils/lib.a(ls.o): in function `my_stat':
ls.c:(.text.my_stat+0xe8): undefined reference to `gnu_dev_major'
/usr/bin/ld: ls.c:(.text.my_stat+0xf4): undefined reference to `gnu_dev_minor'
/usr/bin/ld: coreutils/lib.a(mknod.o): in function `mknod_main':
mknod.c:(.text.mknod_main+0x88): undefined reference to `gnu_dev_major'
/usr/bin/ld: mknod.c:(.text.mknod_main+0xa4): undefined reference to `gnu_dev_minor'
/usr/bin/ld: coreutils/lib.a(stat.o): in function `print_stat':
stat.c:(.text.print_stat+0x294): undefined reference to `gnu_dev_major'
/usr/bin/ld: stat.c:(.text.print_stat+0x2b4): undefined reference to `gnu_dev_minor'
/usr/bin/ld: klibc-utils/lib.a(resume.o): in function `resume_main':
resume.c:(.text.resume_main+0xf8): undefined reference to `gnu_dev_major'
/usr/bin/ld: resume.c:(.text.resume_main+0x1d4): undefined reference to `gnu_dev_minor'
/usr/bin/ld: libbb/lib.a(makedev.o): in function `bb_makedev':
makedev.c:(.text.bb_makedev+0x0): undefined reference to `gnu_dev_makedev'
/usr/bin/ld: libbb/lib.a(udp_io.o): in function `recv_from_to':
udp_io.c:(.text.recv_from_to+0xc8): undefined reference to `__cmsg_nxthdr'
collect2: error: ld returned 1 exit status
Note: if build needs additional libraries, put them in CONFIG_EXTRA_LDLIBS.
Example: CONFIG_EXTRA_LDLIBS="pthread dl tirpc audit pam"
make: *** [Makefile:719: busybox_unstripped] Error 1

Also, unless I turn off large file system support, I get even more errors about musl not providing these either:

update_passwd.c:(.text.update_passwd+0xa8): undefined reference to `fopen64'
/usr/bin/ld: update_passwd.c:(.text.update_passwd+0xdc): undefined reference to `open64'
/usr/bin/ld: update_passwd.c:(.text.update_passwd+0xf8): undefined reference to `fstat64'
/usr/bin/ld: update_passwd.c:(.text.update_passwd+0x170): undefined reference to `fcntl64'
/usr/bin/ld: update_passwd.c:(.text.update_passwd+0x5a8): undefined reference to `fcntl64'

This is against the latest musl libc 1.2.4 from 2023-05-01

larsks
  • 34,737
  • https://wiki.musl-libc.org/building-busybox.html this seems to be out of date (it mentions Busybox 1.22.1 but Busybox is currently at 1.36.1) – Brandon Ros Jan 06 '24 at 19:49
  • FWIW, make CC=musl-gcc works fine for me on Ubuntu 22.04 with the canonical musl packages (1.2.2) and the current git HEAD of busybox after symlinking linux, asm, asm-generic and mtd from /usr/include into the musl headers directory. – Stéphane Chazelas Jan 06 '24 at 21:59

1 Answers1

0

I just built busybox (from commit 5dc9ece3b9e87af0dcb01449821ac827391ac116 of Sep. 19 2023) statically under Alpine linux (which is a MUSL-libc based system and does not have glibc installed).

The build finished without errors.

The final binary is:

/src/busybox # file busybox
busybox: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped

If you use this Dockerfile:

FROM docker.io/alpine:latest

RUN apk add git alpine-sdk ncurses-dev linux-headers RUN mkdir /build COPY busybox-config /build/ COPY build-busybox.sh /build/ CMD ["sh", "/build/build-busybox.sh"]

Where build-busybox.sh looks like this:

#!/bin/sh

set -e

cd /build git clone --depth=1 git://busybox.net/busybox.git cd busybox cp /build/busybox-config .config make oldconfig make mkdir -p /output cp busybox /output

And busybox-config is the .config created by running make menuconfig, then you can get a statically linked busybox by running:

docker build -t busybuilder .
mkdir output
docker run --rm -v $PWD/output:/output busybuilder

This will create the statically linked binary as output/busybox.

I've packaged all of the above into a repository here; you can just clone the repository and run the top-level build-image-and-busybox.sh script.

larsks
  • 34,737
  • statically under Alpine linux

    You are 100% right that if you do it from a musl host system, it seems to work without issue. I am trying to figure out why I am having such a hard time doing it from a glibc system. You would think glibc wouldn't matter since you are compiling against/linking against (statically) musl but... there seems to be an issue/I'm doing something wrong?

    – Brandon Ros Jan 07 '24 at 17:19
  • To be clear, I didn't build this on a musl host system. I built this on a glibc host system, using containers to create an isolated build environment. It seems much simpler, and demonstrably works. – larsks Jan 07 '24 at 17:24