[Toybox] [PATCH] Add makefile rule to build kconfig; fixes clean-tree parallel builds

Rob Landley rob at landley.net
Tue Mar 3 12:11:11 PST 2026


On 2/27/26 16:07, enh wrote:
> On Sun, Feb 22, 2026 at 6:49 PM Rob Landley <rob at landley.net> wrote:
>>
>> On 2/13/26 13:36, enh wrote:
>>>> Anyway, in theory, android could now just do something like:
>>>>
>>>> KCONFIG_ALLCONFIG=scripts/android_miniconfig scripts/genconfig.sh -n &&
>>>> scripts/make.sh
>>>>
>>>> And... it might work? (Don't have the test environment.)
>>>
>>> ...you had me worried here that i was going to have to change
>>> something, but it seems like the update "just worked"? is that
>>> expected, or have i missed something and just haven't noticed the
>>> other shoe fall yet?
>>
>> Commit 32decfacef12 is probably the other shoe, you'll have to at least
>> resnapshot the headers because the probed symbol names changed.
> 
> yeah, that's fucked it :-)

Alas.

> here's what we're doing on each update (at the root of our toybox clone):
> 
> ```
> rm -rf .config generated/ android/
> 
> function generate() {
>    which=$1
>    echo -e "\n-------- $1\n"
> 
>    # These are the only generated files we actually need.
>    files="config.h flags.h globals.h help.h newtoys.h tags.h"

Hmmm... You're missing generated/Config.in which seems kind of important.

$ make clean
cleaned
$ scripts/genconfig.sh
$ ls generated/
Config.in  help.h  unstripped
$ scripts/make.sh
Compile toybox
...
$ ls generated/
build.sh  Config.in  globals.h  newtoys.h  unstripped
config.h  flags.h    help.h     tags.h     zhelp.h

Running scripts/make.sh won't run scripts/genconfig.sh (anymore), so it 
won't recreate generated/Config.in.

(If you don't enable gunzip you won't get zhelp, "unstripped" is a 
directory that gets mkdir -p by make.sh, and build.sh is more or less 
documentation that gets harvested for the prereq build. The rest you need.)

>    cp config-$which .config

ok.

>    NOBUILD=1 scripts/make.sh
 >    out=android/$which/generated/
>    mkdir -p $out
>    for f in $files; do cp generated/$f $out/$f ; done
>    rm -rf .config generated/

My first guess is to add Config.in to the list at the top.

That said, the build no longer compiles and runs test binaries, and all 
the inputs to sed/grep etc that generate those headers are checked into 
the repo, with the single exception of the "cc -dM -E -" output, which 
is checked for the presence or absence of two #defines. Historically 
"config" had a lot more dependencies than "make", but I'm trying hard to 
fix that.

The other stuff that used to be probed got moved to #ifdefs and 
__has_include() and so on, but configuration dependencies are resolved 
before then so anything that "depends on SYMBOL" needs a symbol.

There are actually only six probed "depends on" left: three for 
IS_ANDROID (log/sendenvent/mkpasswd) and three for IS_FORK (all in 
pending, and they can just break the build in certain configs until they 
get fixed up, that's part of what needing to be fixed up MEANS.)

All the OTHER uses of those symbols could just as easily use an if 
(IS_ANDROID) or if (HAS_FORK) which could geet set in portability.h via 
appropriate #ifdeffery and not involve the config system at all (except 
as a strict consumer of its output).

I already intend to clean up mkpasswd. It would just be REALLY nice if 
ONE WEEK would go by without a fresh 
https://mstdn.jp/@landley/116134666430118741 and me looking at jobs as a 
nurse's assistant or something. (Unionized! Excellent health insurance! 
Not having to care about being fucked over by Gavin Newsom _too_!)

I just built "sendevent" on glibc, my linux headers have the ioctl 
define and nothing else really looks android specific? (I mean nothing's 
probably LISTENING to the ioctl, but the tool doesn't care.) So there 
doesn't seem to be a reason not to remove that "depends on" now? (It's 
no more out of place in defconfig than deallocvt or i2cdump.)

"log" really looks like a reinvention of posix's logger. I could 
probably work up a small shim so a non-bionic build of it would 
basically else fall back to syslog(). (I'm not translating buffers to 
facilities, but the syscall can do what it likes with the input.)

If all the inputs of scripts/genconfig.sh were confirmed to be 
checked-in files, and we didn't parse compiler output anymore, would 
THAT be good enough to run scripts/genconfig.sh as part of the android 
build?

Sigh. I'm aware that mac (and cygwin?) builds suck. Would a "forkbomb" 
parallel build of the prereq stuff help? I believe this is posix-2008:

for i in lib/*.c $FILES
do
   X=${FILES##*/} X=${X%.c}
   $BUILD -c $i -o $X.o &
done
wait
$BUILD $LINK *.o -o toybox-prereq && rm *.o || exit 1

(The hard part of parallel builds is the rate limiting. If you just want 
to launch EVERYTHING in parallel then wait and link... well that. Sigh, 
I need a way to comment out the last line of build.sh so use.sh could do 
the parallel one instead. "Simple" a moving target when you add 
features...)

>    make allnoconfig KCONFIG_ALLCONFIG=config-$which
> }
> 
> generate "device"
> generate "linux"
> generate "mac"
> 
> rm -rf .config
> ```

I'd take a look at those input configs, but if android's toybox is still 
public and up to date anywhere outside google's firewall I haven't found 
it. :(

> (and, yes, i can confirm that it's
> 32decfacef12644c8c939466db58f1370ccba4d0 that broke things, not the
> more recent change.)

There used to be a less strict separation between config and make, so 
make.sh would recreate generated/Config.in.

> it seems like my "config" file is being used (because i get an error
> until i rename CONFIG_TOYBOX_ON_ANDROID to CONFIG_IS_ANDROID) but then
> when i look at the resulting generated/config.h file it's wrong. for
> example:
> 
> generated/config.h:#define CFG_TOYBOX_SELINUX 0
> 
> despite
> 
> CONFIG_TOYBOX_SELINUX=y
> 
> in my config...

That's... odd.

I still don't have the input .config you're using to reproduce it here, 
but one thing that might be screwing you up is that scripts/make.sh now 
has this near the start:

# Run oldconfig if necessary
[ -e "$GENDIR"/Config.in ] ||
   KCONFIG_ALLCONFIG="${KCONFIG_ALLCONFIG:-$KCONFIG_CONFIG}" \
   scripts/genconfig.sh -d || exit 1

So the .config you copied in place before running make.sh may get 
stomped by the oldconfig before you've got your ducks in a row? (The 
theory is you run scripts/genconfig.sh _then_ run scripts/make.sh, but 
you're doing it in reverse order. That "make allnoconfig" is a call to 
scripts/genconfig.sh.)

Try doing this:

$ make distclean
$ KCONFIG_ALLCONFIG=your_config_file scripts/genconfig.sh -n
$ NOBUILD=1 scripts/make.sh

Does that create the generated/ files you want? (It does here...)

$ KCONFIG_ALLCONFIG=scripts/android_miniconfig scripts/genconfig.sh -n
$ NOBUILD=1 scripts/make.sh
warning: using unfinished code from toys/pending
$ grep SELINUX .config generated/config.h
.config:CONFIG_TOYBOX_SELINUX=y
generated/config.h:#define CFG_TOYBOX_SELINUX 1
generated/config.h:#define USE_TOYBOX_SELINUX(...) __VA_ARGS__
generated/config.h:#define SKIP_TOYBOX_SELINUX(...)

Rob


More information about the Toybox mailing list