[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