[busybox] some size savings

Rob Landley rob at landley.net
Tue Oct 11 00:33:31 UTC 2005


On Monday 10 October 2005 13:51, Bernhard Fischer wrote:
> [changing the subject to something more appropriate]
>
> Recap: Size savings "for free" i.e. without touching individual applets
> but improving the way busybox is built. For free in quotes as someone
> still has to do the grunt "work". Work in quotes as it's Just For Fun
> and cleanliness, at least for my part.
>
> On Sun, Oct 09, 2005 at 08:16:12PM +0200, Bernhard Fischer wrote:
> >On Sat, Oct 08, 2005 at 04:14:34PM -0500, Rob Landley wrote:
> >>On Saturday 08 October 2005 08:38, Bernhard Fischer wrote:
> >>> >I'll look into building libbb in one go now..
> >>>
> >>> Looks promising. There is most likely still opportunity for the
> >>> compiler to optimize, but for a start (without any fancy tricks) it
> >>> looks ok:
> >>
> >>That is a _nice_ size savings.
> >
> >Here are numbers after having converted all internal libs to this.
> >
> >It's expected that switching only the libs doesn't make much of a
> >difference. The majority of the code-size is added by the applets
> >which aren't (yet, should we?) converted.
>
> ping. Should we (i.e. /me) do that?
>
> It would take some time to convert these, so i won't start to look into
> it if somebody is strictly opposed to it.

It should work with old compilers, and I noticed that it even gives some size 
savings with 3.3.

The potential downside is that it uses more memory (gcc reads in all the files 
at once and creates the mother of all parse trees, which is where the greater 
optimization possibilites come from).  But this is memory in the build 
environment, not the destination system.  And it's still unlikely to top that 
one horror in the gcc build itself that takes something like 10 seconds to 
compile (entirely cpu bound!) on a 2 ghz  system.

I.E. I'm all for it, and consider it 1.1 material.

> >Results for allyesconfig, non-static without using libbusybox.so.
> >Binaries were built with the same toolchain, oorig is current trunk,
> >the other one is with the patch mentioned below.
> >
> >$ ls -sn ../busybox.oorig/busybox busybox
> > 896 -rwxr-xr-x  1 0 0  913224 2005-10-09 19:47 busybox
> >1076 -rwxr-xr-x  1 0 0 1097653 2005-10-09 18:54 ../busybox.oorig/busybox
> >
> >$ size ../busybox.oorig/busybox busybox
> >   text    data     bss     dec     hex filename
> > 897847   15760 1072772 1986379  1e4f4b ../busybox.oorig/busybox
> > 895878   15832 1070068 1981778  1e3d52 busybox
>
> intriguing, isn't it? :)

I remember at LWE east in 2000 (or whatever year it was I bought all the audio 
casettes), Jon Maddog Hall was on a panel that was just one long series of 
old fart wisdom anecdotes.

He talked about an old minicomputer project that would take hours to write out 
its data and filled up over a dozen old reel-to-reel tapes doing so.  And he 
made a tiny change to the program so that it wrote out its data in minutes 
and fit it all one one tape.

The solution?  Blocking the data intelligently.  They were writing out a few 
bytes at a time as if tape was a streaming media, so the tape would start up 
the motor, write a new record idicator once the tape got up to speed, write 
the data, write end of record, and stop the motor again.  For every record 
written.  He changed it to buffer the data and write out something like 4k at 
a time, so that the tape had much fewer starts and stoppes, and much less 
tape passed useless under the heads waiting for the motor to get up to 
speed/grind to a halt, plus of course the zillions of useless headers and 
footers that could be discarded.

I suspect something like that is going on here.  In one case, lots of small 
objects are being generated and linked together, and they don't pack together 
all that efficiently.  In the other a smaller number of large objects are 
being generated.

Possibly a much more intelligent linker could give us some of this benefit.  I 
don't know.

> >[]
> >
> >>I think this can still go into 1.1, as can the libbb.so patch.  Just
> >> because I'm pushing for a -pre1 doesn't mean we'll be shipping 1.1.0
> >> before january.
> >
> >Ok. I'd be glad if somebody can verify that the patch is ok for other
> >setups than gcc-4.x and glibc 2.3.5-6 on an i386.. I *think* the
> >majority is ok, except the ldflags for the .so (should be weeded out and
> >improved).
>
> ping.

Check it in and see who yells.  We're allowed to break stuff like build 
environments in 1.1 as long as we can document it and tell people what it is 
they need.  We're already contemplating gcc 3.4 or newer as the recommended 
compiler because it plays nice with ENABLE much better...

> >Please note that there is some cruft left, so it has to be cleaned up a
> >bit before it can go in.
>
> All XXX has to be revisited.
> Also, i need to know if folks want to be able to build the individual .o
> or not.

For make standalone, perhaps.  But we can handle that later.  Sounds like 
standalone would also benefit from this kind of thing...

> E.g. for size-optimisations, should
> rm -f libbb/bb_echo.o;make $(pwd)/libbb/bb_echo.o
> still produce bb_echo.o or not? I could ditch the rules to build
> individual objects if only the overall size is interresting. Note that
> imho the overall size needed does count in the end, still i see that it
> is useful to allow for optimizing single obj. Opinions?

Vodz just got dependencies working.  How does this interact with that?

> The patch is around 30k uncompressed, so i'm hesitating to send it to
> the list. I can of course change my mind if people think that muxing
> stuff like that is more welcome....
>
> >Anyway. Updated patch is here:
> >http://members.aon.at/berny_f/busybox/busybox.libs.03b.diff

I'm not too much help with makefiles, but...

Ah, the libbb.so patch.  I think that we should probably check it in before 
too much more goes into it (and before we get too much closer to 1.1.0-pre1).

> -if [ "$prefix" = "" ]; then
> +# Some versions of [ can't deal with empty strings for the '=' operation
> +if [ "x$prefix" = "x" ]; then

Remember -z...

> rm -f $prefix/bin/busybox || exit 1
> mkdir -p $prefix/bin || exit 1
>+mkdir -p $prefix/$libdir || exit 1
> install -m 755 busybox $prefix/bin/busybox || exit 1

Hmmm...  Possibly that should be conditional?  (Creating the directory when 
libbb.so isn't selected is a user-visible change.  Admittedly the lib 
directory will generally already be there...)

>
> +for i in libbusybox.so*
> +do
> + [ -f $i ] && install -m 644 $i $prefix/$libdir/
> +done

And when libbusybox.so* doesn't exist, this does what?
 
Now, this bit:

-# Copyright (C) 1999-2004 by Erik Andersen <andersen at codepoet.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
+# Copyright (C) 1999-2005 by Erik Andersen <andersen at codepoet.org>
 #
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Licensed under the GPL v2, see the file LICENSE in this tarball.
 #

Subtle legal point: the "or (at your option) any later version" just got 
dropped, and as far as I can tell the _only_ thing allowing code to be used 
under GPL v3 is the "at your option" clause in the license grant boilerplate.  
(If you think I'm wrong, point to the license text please.)

Abbreviating the boilerplate, yea.  Changing the license terms while doing so, 
boo.

Now if we just want to put the "at your option" clause into LICENSE, fine.  
Some of our files currently say gpl v2 and some say gpl v2 or later, although 
technically since it's in the permission grant test this has to count as dual 
licensing rather than incompatible licenses...

Yeah, I pay attention to this sort of thing. :)

Okay, into libunarchive's makefile:

I'm not following this enough to see whether or not the conditionals are being 
honored.  When we want to build busybox statically linked against libbb.a, is 
everything working ok?  I don't mind building libbusybox.so unconditionally 
as long as A) the busybox executable produced is linked the way we want it to 
be, B) we only install what's actually requested.

The makefile.in snippets:

Query: *.c is wrong why?  (What is makedep working based off of?)

+#above line left blank intentionally
 
Yank the trailing \ already.  Any cleverness that needs a comment to 
understand also needs some real benefit to justify its existence.

+# XXX: No idea how i can extract a valid soversion out of e.g.
+# VERSION:=1.1.0-pre1

Either use the whole thing or sed 's/-.*//', or possibly:
sed -r 's/[-a-zA-Z]{1,}/\./'

+libbusybox.so: $(libbusybox-obj)
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) -shared \
+ $(CFLAGS_PIC) -msingle-pic-base \
+ -Wl,-soname=$(libbusybox-soname) \
+ -Wl,--enable-new-dtags -Wl,--reduce-memory-overheads \
+ -Wl,-z,combreloc -Wl,-shared -Wl,--as-needed \
+ -Wl,--warn-shared-textrel -Wl,--no-undefined-version \
+ -o $(@) \
+ -Wl,--whole-archive -Wl,--start-group $(^) \
+ -Wl,--end-group -Wl,--no-whole-archive
+ @rm -f $(libbusybox-soname)
+ ln -s $(@) $(libbusybox-soname)
+ strip --remove-section=.note --remove-section=.comment 
--remove-section=.version --strip-debug --strip-unneeded $@

Possibly this belongs in rules.mak or some such?  Getting into fairly deep 
linker magic here...

Most I feel "check it in and we'll clean it up once it's in" rather than 
keeping a 30k patch out of the tree, but I have very weak make-fu and would 
feel much better if somebody who know what they were doing gave it this sniff 
test...

Rob



More information about the busybox mailing list