Re: Toybox make root no longer works as expected

Rob Landley <[email protected]>
Newsgroups gmane.linux.ports.sh.devel
Message-ID <[email protected]>
On 4/29/26 02:46, John Paul Adrian Glaubitz wrote:
> Hi Rob,
> 
> I'm trying to build a new root image after updating Toybox but that no longer works:
> 
> glaubitz@node54:/data/home/glaubitz/toybox> make root CROSS=sh2eb-linux-muslfdpic- LINUX=/data/home/glaubitz/sh-linux
> mkroot/mkroot.sh  -- LINUX=/data/home/glaubitz/sh-linux CROSS=sh2eb-linux-muslfdpic-
> No ccc symlink to compiler directory.

You're using CROSS= with the CROSS_COMPILE= syntax. They mean different 
things.

CROSS= is the syntax that just specifies the target architecture and 
picks a cross compiler from a common directory (pointed to by ccc). The 
special names CROSS=all and CROSS=allnonstop build all the targets (the 
first stopping upon failure, the second continuing past failures. See 
root/build/log for log files afterwards, the extension .y is builds that 
succeeded, .n is builds that didn't succeed, and .txt is every command 
line run out of the $PATH when building.)

CROSS_COMPILE= specifies a compiler prefix to use out of the $PATH, or 
you can CROSS_COMPILE=/path/to/prefix- to supply path and prefix in one. 
In which case the plumbing will use the start of the prefix up to the 
first dash as the target architecture name for finding the kernel config 
and so on out of the big if/else staircase. (I should provide a way to 
independently override that, but it hasn't come up much.)

If you don't specify either it builds using the host compiler, which is 
usually linking against glibc and thus absolutely incompetent at 
producing static binaries.

The supported targets and corresponding config data derived from them 
(kernel config and KARCH, qemu command line invocation including 
specifying the right serial output type, which file is actually the 
runnable kernel produced by the build, etc) are under 
https://codeberg.org/landley/toybox/src/branch/master/mkroot/mkroot.sh#L183 
which sets default values first and then overrides them for targets that 
don't use the most common option in a big if/else staircase.

For example, everything mkroot knows about the m68k target is:

>   elif [ "$CROSS" == m68k ]; then
>     QEMU_M=q800 KARCH=m68k
>     KCONF="$(be2csv MMU M68040 M68KFPU_EMU MAC BLK_DEV_SD MACINTOSH_DRIVERS \
>       NET_VENDOR_NATSEMI MACSONIC SCSI{,_LOWLEVEL,_MAC_ESP} \
>       SERIAL_PMACZILOG{,_TTYS,_CONSOLE})"

Which says qemu-system-m68k needs "-m q800" but otherwise uses the 
default qemu-system-$ARCH invocation (line 333, or see run-qemu.sh in 
any existing image), and that kernel needs ARCH=m68k.

Then KCONFIG= specifies kernel .config symbols in a very terse format, 
which is expanded three times:

1) be2csv = brace expansion to comma separated values, so bash's 
SCSI{,_LOWLEVEL,_MAC_ESP} becomes SCSI SCSI_LOWLEVEL SCSI_MAC_ESP and 
then all the spaces are turned into commas

2) csv2cfg produces miniconfig output, the above three becoming:

CONFIG_SCSI=y
CONFIG_SCSI_LOWLEVEL=y
CONFIG_SCSI_MAC_ESP=y

(Note that if one of the CSV is of the form BLAH=something then the 
=something will be used instead of adding =y, and yes it understands 
that commas inside "double quotes" are part of that value, not symbol 
separators. That's why the regex in csv2cfg is so horrible. If you need 
blah="thing with spaces" you can KCONF+=,symbol without running it 
through be2csv, as at least one architecture used to do? Or did I switch 
that to KCONFIG="$(be2csv blah),MORE=\"thing with spaces\"" for 
that/those target(s)? I forget...)

3) it's fed into the kernel's miniconfig plumbing which I documented 
twenty one years ago (yes in 2005, https://lwn.net/Articles/161086/). 
The plumbing glues on the GENERIC_KCONF list of default symbols (so I 
don't have to tell EVERY target to support ELF or ext2) and then calls

make allnoconfig KCONFIG_ALLCONFIG=mini.config

Those are the three files memorialized in root/sh4/docs and similar, by 
the way. The microconfig (csv after brace expansion), the miniconfig, 
and the full (sadly very version-specific) .config.

> make: *** [Makefile:108: root] Error 1
> glaubitz@node54:/data/home/glaubitz/toybox>
> 
> It asks me to create a "ccc" symlink but I have no clue where that link is supposed
> to point to.

It's at the end of https://landley.net/toybox/faq.html#cross although 
that links to another section which is a bit verbose...

> The FAQ says the link is supposed to »pointing at a directory full of
> cross compilers« but I don't have that and that's not my personal setup.

The ones I built are at https://landley.net/bin/toolchains/latest

You can extract the -cross ones from there into a directory for ccc to 
point at. (The -native.sqf ones are squashfs filesystems you can add to 
qemu with -hda or network block devices or similar.)

> I have the
> cross compilers installed in my home directory and their bin directories added to
> the PATH variable which has always worked in the past without any problems.

Try CROSS_COMPILE instead of CROSS, they mean different things.

> Can you explain how that "ccc" symlink works?

It contains directories called $ARCH-*cross and expects to find a 
compiler called $ARCH-*cross/bin/$CROSS*-cc in each. (It doesn't HAVE to 
be a symlink, it can be a directory, but installing piles of stuff under 
your get repo is not ideal.)

If the ccc/ directory exists and try to CROSS=help or something (any 
target it can't find), it lists the available targets.

> Thanks,
> Adrian

Rob
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.