Using ELLCC to (Cross) Compile Toybox

Toybox combines many common Linux command line utilities together into a single BSD-licensed executable. I wanted to to see how hard it would be to compile and cross compile it using ELLCC. It turned out to be pretty easy after I added a few Linux specific header files. These are the files I added:

[~/ellcc] dev% ls ~/ellcc/libecc/include/linux
fs.h  if_vlan.h  loop.h  nbd.h  rfkill.h  rtc.h  sched.h  sockios.h  soundcard.h

The needed include files are in the ELLCC source tree now and are available in the 0.1.22 binary release. Here’s all you need to do to build Toybox:

[rich@dev ~]$ mkdir toybox 
[rich@dev ~]$ cd toybox
[rich@dev toybox]$ wget http://landley.net/toybox/downloads/toybox-0.6.1.tar.gz
--2015-12-23 17:02:37--  http://landley.net/toybox/downloads/toybox-0.6.1.tar.gz
Resolving landley.net (landley.net)... 208.113.171.142
Connecting to landley.net (landley.net)|208.113.171.142|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 736371 (719K) [application/x-tar]
Saving to: ‘toybox-0.6.1.tar.gz’

toybox-0.6.1.tar.gz  100%[=====================>] 719.11K   845KB/s   in 0.9s   

2015-12-23 17:02:38 (845 KB/s) - ‘toybox-0.6.1.tar.gz’ saved [736371/736371]

[rich@dev toybox]$ tar xfp toybox-0.6.1.tar.gz 
[rich@dev toybox]$ cd toybox-0.6.1/
[rich@dev toybox-0.6.1]$ CC="/home/rich/ellcc/bin/ecc -target armv6-linux-engeabihf" CFLAGS="-Wno-format-extra-args -Wno-uninitialized" make defconfig toybox
cc -o kconfig/conf kconfig/conf.c kconfig/zconf.tab.c -DKBUILD_NO_NLS=1 \
        -DPROJECT_NAME=\"ToyBox\"
scripts/genconfig.sh
kconfig/conf -D /dev/null Config.in > /dev/null
scripts/make.sh
Generate headers from toys/*/*.c...
generated/newtoys.h Library probe.......
Make generated/config.h from .config.
generated/flags.h generated/globals.h generated/help.h
Compile toybox................................................................................................................................................................strip: Unable to recognise the format of the input file `toybox_unstripped'
strip failed, using unstripped
.

Oops. The strip failed because the standard x86_64 Linux strip doesn’t understand ARM object file formats. We can use ecc-strip:

[rich@dev toybox-0.6.1]$ ~/ellcc/bin/ecc-strip -o toybox toybox_unstripped
[rich@dev toybox-0.6.1]$ file toybox
toybox: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[sha1]=11e423037c6fb0e4ee10ef5f53a421fca86a81e3, stripped               
[rich@dev toybox-0.6.1]$ size toybox                                             
   text    data     bss     dec     hex filename                                 
 401916    3208   21020  426144   680a0 toybox  

Lest’s send it over to my trusty Raspberry Pi:

                                 
[rich@dev toybox-0.6.1]$ scp toybox rich@192.124.43.98:                                                   
rich@192.124.43.98's password:                                                   
scp: ./toybox: Permission denied                                                 
[rich@dev toybox-0.6.1]$ ssh rich@192.124.43.98
rich@192.124.43.98's password:                                                   
                                                                                 
The programs included with the Debian GNU/Linux system are free software;        
the exact distribution terms for each program are described in the               
individual files in /usr/share/doc/*/copyright.                                  
                                                                                 
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent                
permitted by applicable law.                                                     
Last login: Sun Dec 20 19:20:36 2015 from 192.124.43.2   

What commands does Toybox have?

                        
rich@raspberrypi:~$ ./toybox                                                     
acpi base64 basename blkid blockdev bunzip2 bzcat cal cat catv chattr            
chgrp chmod chown chroot chvt cksum clear cmp comm count cp cpio cut             
date df dirname dmesg dos2unix du echo egrep eject env expand factor             
fallocate false fgrep find flock free freeramdisk fstype fsync grep              
groups halt head help hexedit hostid hostname hwclock id ifconfig                
inotifyd insmod install ionice iorenice kill killall killall5 link               
ln login logname losetup ls lsattr lsmod lspci lsusb makedevs md5sum             
mix mkdir mkfifo mknod mkpasswd mkswap mktemp modinfo mount mountpoint           
mv nbd-client nc netcat nice nl nohup nproc nsenter od oneit partprobe           
passwd paste patch pidof pivot_root pmap poweroff printenv printf                
ps pwd pwdx readahead readlink realpath reboot renice reset rev rfkill           
rm rmdir rmmod sed seq setsid sh sha1sum shred sleep sort split stat             
strings su swapoff swapon switch_root sync sysctl tac tail taskset               
tee time timeout touch toysh true truncate tty umount uname uniq unix2dos        
unlink uptime usleep uudecode uuencode vconfig vmstat w wc which who             
whoami xargs xxd yes                                                             
rich@raspberrypi:~$ ./toybox ls -l
total 3112                                                                       
-rwxr-x--x 1 rich rich  141580 2015-12-20 19:22 hello                            
-r-xr-xr-x 1 rich rich 1446476 2015-12-23 21:21 toybox   

Now let’s build for the x86_64:

                        
rich@raspberrypi:~$ logout                                                                           
Connection to 192.124.43.98 closed.                                              
[rich@dev toybox-0.6.1]$ make clean                                              
rm -f kconfig/zconf.hash.c kconfig/zconf.tab.c kconfig/lex.zconf.c kconfig/conf kconfig/mconf                                                                     
rm -rf toybox toybox_unstripped generated change .singleconfig*                  
[rich@dev toybox-0.6.1]$ CC="/home/rich/ellcc/bin/ecc -target x86_64-linux-eng" CFLAGS="-Wno-format-extra-args -Wno-uninitialized" make defconfig toybox     
cc -o kconfig/conf kconfig/conf.c kconfig/zconf.tab.c -DKBUILD_NO_NLS=1 \        
        -DPROJECT_NAME=\"ToyBox\"                                                
scripts/genconfig.sh                                                             
kconfig/conf -D /dev/null Config.in > /dev/null                                  
scripts/make.sh                                                                  
Generate headers from toys/*/*.c...                                              
generated/newtoys.h Library probe.......                                         
Make generated/config.h from .config.                                            
generated/flags.h generated/globals.h generated/help.h                           
Compile toybox.................................................................................................................................................................                                                                    
[rich@dev toybox-0.6.1]$ file toybox
toybox: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=6d60409b768431310a5ce6085e595b6a98a66d45, stripped                  
[rich@dev toybox-0.6.1]$ size toybox
   text    data     bss     dec     hex filename
 376786    6192   22152  405130   62e8a toybox                                   
[rich@dev toybox-0.6.1]$ 

Cool stuff.

Leave a Reply

Your email address will not be published.