[Toybox] FYI: kernel builds rely on GNU expr extensions

Rob Landley rob at landley.net
Thu May 2 09:15:34 PDT 2019


On 5/1/19 3:23 PM, enh via Toybox wrote:
> so you know how i said i wasn't going to use anything in pending for
> the build? turns out i wasn't paying enough attention and accidentally
> used expr...

Eh, if you're deploying pending on the device using it in the build isn't that
much more of a lift...

ALso, $(( )) is expr the same way [ ] is test, so I've gotta finish and promote
it soon to make toysh work...

> i'm reverting that now (but keeping it for the device), but folks
> building their kernels from within an Android tree hit this. (we
> recommend that you _don't_ build your kernel that way, and we don't do
> that ourselves, but realistically we're never going to stop everyone
> from doing it. and i know "build the kernel with toybox" is
> interesting to you anyway.)

It's explicitly one of my goals, to make that supportable, yes. :)

> so, yeah, the kernel build uses some GNU extensions. `index` looks
> like it's there (though perhaps only for tests?), and the specific bug
> report i got was about GNU unary + which the info page describes thus:



>    Strings are not quoted for ‘expr’ itself, though you may need to
>   quote them to protect characters with special meaning to the shell,
>   e.g., spaces.  However, regardless of whether it is quoted, a string
>   operand should not be a parenthesis or any of ‘expr’’s operators like
>   ‘+’, so you cannot safely pass an arbitrary string ‘$str’ to expr merely
>   by quoting it to the shell.  One way to work around this is to use the
>   GNU extension ‘+’, (e.g., ‘+ "$str" = foo’); a more portable way is to
>   use ‘" $str"’ and to adjust the rest of the expression to take the
>   leading space into account (e.g., ‘" $str" = " foo"’).

That was confusing so I looked at the man page:

       + TOKEN
              interpret TOKEN as a string, even if it is a
              keyword like 'match' or an operator like '/'

  $ expr + match
  match
  $ expr 1+2
  1+2
  $ expr 1 +2
  expr: syntax error
  $ expr 1 + 2
  3

Seems straightforward enough. And now I remember why implementing $(( )) with
common plumbing with expr is still on my todo list. :)

> though i'm honestly not convinced this is their real problem. the
> specific example they give is this from scripts/Makefile.lib in the
> kernel:
> 
> size_append = printf $(shell \
> dec_size=0; \
> for F in $1; do \
>     fsize=$$($(CONFIG_SHELL) $(srctree)/scripts/file-size.sh $$F); \
>     dec_size=$$(expr $$dec_size + $$fsize); \
> done; \
> ...
> 
> but given the `dec_size=0` line, i think they're confused and whatever
> failure they're seeing is coming from somewhere else...

Fun. I'll throw it on the todo pile and shuffle "expr" near the top of the
promotion heap...

Thanks,

Rob



More information about the Toybox mailing list