[Scratchbox-users] Notes on building crosstool compilers and crocodile packages for powerpc (PPC) using scratchbox

Jim Heck jsurf at heckheck.com
Thu Dec 21 18:41:30 EET 2006


Since I've been recently coming up the learning curve, I thought to copy 
some of my notes here in the hope that they might help some people.  
This covers building your own foreign toolchain and then install that in 
scratchbox to build crocodile packages for powerpc.

Here are some notes.  I was working on two different toolchains (ppc603 
and ppc860), so I refer to both interchangably.  There may be some 
omissions or errors, it's a work in progress.  There are two patches 
that were needed to build the crocodile packages for powerpc, one for 
procps and one for zlib.

-Jim Heck

**0. Starting with a vanilla Ubuntu 6.10 installation.  I tried this 
because I had problems installing scratchbox 1.0.6 on Debian (turns out 
Debian was fine, as I was able to install on my laptop running Debian).  
The installation hung in the stage where it was running the preinstall 
scripts for the packages.  This may have had something to do with 
autofs, since the installation creates an sbox user.  I confirmed that 
scratchbox installs on Debian if autofs is not used.

**1. Installed scratchbox-core (1.0.7).  This pulled in scratchbox-libs 
(1.0.7).  Ultimately I ended up installing the following scratchbox 
packages.

--------------------------------------
jheck at ubuntu-cross:/scratchbox/users/jheck/home/jheck/crocodile/patches$ 
dpkg -l |grep scratchbox
ii  scratchbox-core                            
1.0.7                         Scratchbox base system
ii  scratchbox-devkit-cputransp                
1.0.1                         CPU transparency methods
ii  scratchbox-devkit-debian                   
1.0.6                         Debian tools for Scratchbox
ii  scratchbox-devkit-doctools                 
1.0.5                         Doctools for Scratchbox
ii  scratchbox-devkit-perl                     
1.0.4                         Perl modules for Scratchbox
ii  scratchbox-libs                            
1.0.7                         Scratchbox libraries
ii  scratchbox-toolchain-arm-linux-ct401-2.3   
1.0.4                         arm-linux-ct401-2.3 compiler for Scratchbox
ii  scratchbox-toolchain-host-gcc              
1.0.7                         Scratchbox host-gcc toolchain
ii  scratchbox-toolchain-i686-gcc3.3-glibc2.3  
1.0.3                         i686-linux-gcc3.3-glibc2.3 compiler for Scra


**2. Decided to start by trying to install a foreign toolchain (see 
@1).  To prepare for this, I built a few toolchains using crosstool 0.42 
from Dan Kegel (see @2).

See the following web pages:

@1 http://www.scratchbox.org/wiki/ForeignToolchains
- overview of foreign toolchains for scratchbox

@2 http://kegel.com/crosstool/
- overview of crosstool

@3 http://kegel.com/crosstool/crosstool-0.42/buildlogs/
- summary of working crosstool combinations

@4 http://kegel.com/crosstool/crosstool-0.42/doc/crosstool-howto.html
- crosstool step by step howto


**2.1 Used a supported combination of glibc and gcc under crosstool 0.42 
to make a compiler.  I built this as user jheck under /home/jheck and 
targeted /opt/crosstool/ for the built compiler

- gcc-3.4.5
- glibc-2.3.6

**2.2 Here is a cat of the configuration file used 
/home/jheck/crosstool-0.42/demo-ppc603.sh

--------------------------------------
#!/bin/sh
set -ex
TARBALLS_DIR=$HOME/downloads
RESULT_TOP=/opt/crosstool
export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES="c,c++"
export GCC_LANGUAGES


# Really, you should do the mkdir before running this,
# and chown /opt/crosstool to yourself so you don't need to run as root.
mkdir -p $RESULT_TOP

# Build the toolchain.  Takes a couple hours and a couple gigabytes.
#eval `cat powerpc-603.dat gcc-3.4.0-glibc-2.3.2.dat` sh all.sh 
--builduserland --notest
# eval `cat powerpc-603.dat gcc-3.4.1-glibc-2.3.3.dat`  sh all.sh --notest
#eval `cat powerpc-603.dat gcc-3.4.1-glibc-20040827.dat` sh all.sh --notest
eval `cat powerpc-603.dat gcc-3.4.5-glibc-2.3.6.dat`  sh all.sh --notest
#eval `cat powerpc-603.dat gcc-3.4.5-glibc-2.3.6.dat`  sh all.sh 
--nounpack --notest

echo Done.
--------------------------------------

**2.3 Had the following problems compliling the toolchain

- libc6-dev was not installed by Ubuntu by default and had to be added
- /bin/sh was linked to the /bin/dash shell and that caused problems.  
Solved by changing it to link to /bin/bash.

**2.4 Resulting toolchain was functional, but had a dependence on the 
host glibc, which was version 2.4 based.  This toolchain would not work 
in scratchbox, since scratchbox only includes a 2.3 based version of 
glibc for the host crosscompiler to use.  The fix for this was to 
compile the crosstool toolchain under scratchbox (see 3.)

**3. Rebuilt the crosstool 0.42 toolchain under scratchbox.  The steps 
are outlined below.  Basically I built in my home directory targeting 
/opt/crosstool. 

NOTE: This must NOT be done using the scratchbox HOST sandbox, since 
doing so will result in a compiler with a ld that does not look for 
library dependencies in /usr/lib.  Instead you must use a scratchbox x86 
toolchain.  I was not able to find or build one using the latest Apophis 
r4 version, so I went back and grabbed a toolchain from Apophis r3 
(scratchbox-toolchain-i686-gcc3.3-glibc2.3_1.0.3_i386.deb).  I made a 
sandbox using this toolchain and the debian devkit, and compiled the 
crosstool toolchain.

See the following web pages:
http://scratchbox.org/download/files/sbox-releases/branches/apophis/r3/deb/

--------------------------------------
as user jheck

$ /scratchbox/login
[sbox-ct-compile: ~] >export http_proxy=xxx.xxx.xxx.xxx:xxxx
[sbox-ct-compile: ~] >export ftp_proxy=xxx.xxx.xxx.xxx:xxxx
- to get past the firewall, setup proxies so other tools can work

[sbox-ct-compile: ~] >wget http://kegel.com/crosstool/crosstool-0.42.tar.gz
[sbox-ct-compile: ~] >tar xvzf crosstool-0.42.tar.gz
[sbox-ct-compile: ~] >cd crosstool-0.42
- get the croostool tarball

[sbox-ct-compile: ~] >cp demo-ppc604.sh demo-ppc603.sh
[sbox-ct-compile: ~] >vi demo-ppc603.sh
- setup the master 'demo' script to build glibc-2.3.6/gcc-3.4.5 toolchain
- see 2.2 above for contents of demo-ppc603.sh

[sbox-ct-compile: ~] >unset LD_LIBRARY_PATH
- LD_LIBRARY_PATH cannot be set during compile, and scratchbox has it 
set, so unset it

[sbox-ct-compile: ~] >ln -sf /scratchbox/tools/bin/bash /bin/sh
- fixinc.sh in 
/home/jheck/crosstool-0.42/build/powerpc-603-linux-gnu/gcc-3.4.5-glibc-2.3.6/build-gcc-core/gcc 
needs a link to sh in /bin, so create one

[sbox-ct-compile: ~] >sh demo-ppc603.sh 2>&1 |tee ../ppc603.log
- invoke the crosstool build script, and wait

**4. Built the scratchbox sb-toolchain-extras set of tools, to allow the 
toolchain to be integrated into the scratchbox environment.

NOTE: One thing to remember here is that the toolchain has compiled into 
it, absolute paths to find its libraries and includes 
(/opt/crosstool/gcc-3.4.5-glibc-2.3.6/powerpc-860-linux-gnu/powerpc-860-linux-gnu/lib 
and .../include).  The scratchbox environment installs the toolchain in 
such a way that the necessary files for the compiler are copied to well 
known locations under /usr/lib and /usr/include.  This is how the 
compiler will find them.  A caveat to note is that this process will 
work only only for toolchains that don't mess with the structure of the 
lib and include directories.  Notably, I had a problem with the 
powerpc-860 compiler, which doesn't have a floating point unit.  In this 
case, a few static libraries (e.g. the libstdc++.a) were located in a 
subdirectory under the /lib directory (/lib/nof).  This caused crosstool 
confusion when building the sb-toolchain-extras.  I had to manually copy 
the static libraries up into the /lib directory of the built compiler 
tree so that the crosstool build/scripts could find them.  Thus the use 
of the "standard" path metod crosstool employes is a bit scary, since it 
cannot know exactly how the compiler is setup, and thus we must be 
certain the compiler is working properly in the scratchbox environment.

--------------------------------------
as user jheck logged into scratchbox

[sbox-HOST: ~] >cd /opt/crosstool/gcc-3.4.5-glibc-2.3.6
[sbox-HOST: ~] >tar cvpzf powerpc-603-linux-gnu.gz powerpc-603-linux-gnu
[sbox-HOST: ~] >cp powerpc-603-linux-gnu.gz /scratchbox/compilers/.
[sbox-HOST: ~] >cd /scratchbox/compilers/
[sbox-HOST: /scratchbox/compilers] >tar xvzf powerpc-603-linux-gnu.gz
[sbox-HOST: /scratchbox/compilers] >cd
- tar up the toolchain and untar it in the /scratchbox/compilers directory

[sbox-HOST: ~] >cd /scratchbox/compilers/powerpc-860-linux-gnu
[sbox-HOST: /scratchbox/compilers/powerpc-860-linux-gnu] >rm -rf distributed
- get rid of the distributed gcc compiler because it confuses the python 
script for the toolchain-extras

[sbox-HOST: /scratchbox/compilers/powerpc-860-linux-gnu] >cd 
powerpc-860-linux-gnu/lib/nof
[sbox-HOST: 
/scratchbox/compilers/powerpc-860-linux-gnu/powerpc-860-linux-gnu/lib/nof] 
 >cp *.a ../.
[sbox-HOST: 
/scratchbox/compilers/powerpc-860-linux-gnu/powerpc-860-linux-gnu/lib/nof] 
 >cd
- copy the static .a libraries up to the lib directory so they can be 
found when building toolchain-extras

[sbox-HOST: ~] >darcs get --set-scripts-executable 
http://scratchbox.org/repos/1.0/sb-toolchain-extras
- get the darcs repository with the scratchbox toolchain extras

[sbox-HOST: ~] >cd /scratchbox/compilers/powerpc-860-linux-gnu
[sbox-HOST: /scratchbox/compilers/powerpc-860-linux-gnu] 
 >~/sb-toolchain-extras/confhelper/create_toolchain_conf.py > 
~/sb-toolchain-extras/meta/alien-tc/powerpc-860-linux-gnu.conf
- create the conf file to build the alien toolchain

[sbox-HOST: /scratchbox/compilers/powerpc-860-linux-gnu] >cd 
~/sb-toolchain-extras/
[sbox-HOST: ~/sb-toolchain-extras] >make 
CONFIG=meta/alien-tc/powerpc-860-linux-gnu.conf -C meta/alien-tc all-sums
[sbox-HOST: ~/sb-toolchain-extras] >make 
CONFIG=meta/alien-tc/powerpc-860-linux-gnu.conf -C meta/alien-tc
- make the alien toolchain (first the checksums and then the toolchain 
itself)

[sbox-HOST: ~/sb-toolchain-extras] >cd
[sbox-HOST: ~] >sb-menu
- make a sandbox using the new foreign toolchain

**5. Build the crocodile set of packages.  These are debian sarge 
packages necessary to bootstrap a system.

NOTE: Crocodile is based off the sarge debian distribution.  For the 
most part, it builds all the libraries that the build-essential set of 
packages depends on.  It does leverage a bunch of tools from the 
scratchbox environment, such as those associated with the compiler, and 
some such as autoconf, debmake, flex, etc.  It proceeds in a brute force 
fashion making multiple passes trying to compile all source packages in 
a repository until no progress has been made over two passes.

See the following web pages:
@ http://www.scratchbox.org/wiki/Crocodile
@ http://www.scratchbox.org/wiki/Apophis-r4
@ http://www.scratchbox.org/wiki/EnvironmentVariables

--------------------------------------
as user jheck

**5.1. From Scratchbox 1.0.7 on, flex is not regarded as a provided 
package when checking debian build deps.  This is fixed with the 
following, performed inside scratchbox.

# mkdir /scratchbox/users/${USER}/targets/`sb-conf cu`_deb_list
# cat > /scratchbox/users/${USER}/targets/`sb-conf cu`_deb_list/flex << EOF
Source: flex
Version: 2.5.31
Binary: flex
EOF

**5.2. For powerpc, the value scratchbox returns for 'uname -m' is 
'powerpc'.  This causes problems when building packages, since the 
scripts/makefiles generally expect 'ppc'.  This is fixed by setting the 
'SBOX_UNAME_MACHINE' environment variable to 'ppc'

[sbox-ppc603-croc: ~] > export SBOX_UNAME_MACHINE=ppc


**5.3. Two packages required patches over and above the ones scratchbox 
had already provided.  These were procps and zlib.  The patches go in 
crocodile/patches

- procps required a patch to remove dependence on a header file 
/include/asm/page.h.  The use of a macro for PAGE_SIZE resolved to a 
function and was being improperly used in a variable declaration.  I 
took code from the latest version of the package to patch it in the 
sarge version.

cat of procps.patch
--------------------------------------
diff -Naur procps-3.2.1/proc/devname.c procps-3.2.1-patched/proc/devname.c
--- procps-3.2.1/proc/devname.c 2004-03-17 13:43:50.000000000 -0500
+++ procps-3.2.1-patched/proc/devname.c 2006-12-13 11:38:10.366938000 -0500
@@ -19,10 +19,10 @@
 #include "version.h"
 #include "devname.h"

-#include <asm/page.h>
-#ifndef PAGE_SIZE
-#define PAGE_SIZE (sizeof(long)*1024)
-#endif
+// This is the buffer size for a tty name. Any path is legal,
+// which makes PAGE_SIZE appropriate (see kernel source), but
+// that is only 99% portable and utmp only holds 32 anyway.
+#define TTY_NAME_SIZE 128

 /* Who uses what:
  *
@@ -216,7 +216,7 @@
   char path[32];
   int count;
   sprintf(path, "/proc/%d/%s", pid, name);  /* often permission denied */
-  count = readlink(path,buf,PAGE_SIZE-1);
+  count = readlink(path,buf,TTY_NAME_SIZE-1);
   if(count == -1) return 0;
   buf[count] = '\0';
   if(stat(buf, &sbuf) < 0) return 0;
@@ -227,7 +227,7 @@

 /* number --> name */
 unsigned dev_to_tty(char *restrict ret, unsigned chop, dev_t dev_t_dev, 
int pid, unsigned int flags) {
-  static char buf[PAGE_SIZE];
+  static char buf[TTY_NAME_SIZE];
   char *restrict tmp = buf;
   unsigned dev = dev_t_dev;
   unsigned i = 0;
--------------------------------------

- zlib attempted to create the compiler name for the CC environment 
variable using 'dpkg-architecture -qDEB_HOST_GNU_TYPE'.  This resolved 
the gcc tool name to 'powerpc-linux-gnu-gcc', but scratchbox for some 
reason has the gcc compiler linked to 'powerpc-linux-gcc'.  The fix was 
to patch the rules file for the sarge package using code from the latest 
version, which invokes the compiler using the environment variable CC, 
which make maps to cc, instead of trying to build up the tool name directly.

cat of zlib.patch
--------------------------------------
diff -Naur zlib-1.2.2/debian/rules zlib-1.2.2-patched/debian/rules
--- zlib-1.2.2/debian/rules     2006-12-13 17:13:17.807465000 -0500
+++ zlib-1.2.2-patched/debian/rules     2006-12-13 17:27:35.457286000 -0500
@@ -12,13 +12,20 @@
 DEB_BUILD_GNU_SYSTEM := $(shell dpkg-architecture -qDEB_BUILD_GNU_SYSTEM)
 DEB_BUILD_GNU_TYPE=$(DEB_BUILD_GNU_CPU)-$(DEB_BUILD_GNU_SYSTEM)
 DEB_HOST_ARCH=$(shell dpkg-architecture -qDEB_HOST_ARCH)
-DEB_HOST_GNU_CPU=$(shell dpkg-architecture -qDEB_BUILD_GNU_CPU)
-DEB_HOST_GNU_SYSTEM=$(shell dpkg-architecture -qDEB_BUILD_GNU_SYSTEM)
-DEB_HOST_GNU_TYPE=$(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+DEB_HOST_GNU_CPU=$(shell dpkg-architecture -qDEB_HOST_GNU_CPU)
+DEB_HOST_GNU_SYSTEM=$(shell dpkg-architecture -qDEB_HOST_GNU_SYSTEM)
+DEB_HOST_GNU_TYPE=$(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
 DH_OPTIONS=

 ifeq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
 TESTS=test
+CC=gcc
+CC32=gcc -m32
+CC64=gcc -m64
+else
+CC=$(DEB_HOST_GNU_TYPE)-gcc
+CC32=$(DEB_HOST_GNU_TYPE)-gcc -m32
+CC64=$(DEB_HOST_GNU_TYPE)-gcc -m64
 endif

 COMPAT-ARCHS=
@@ -58,14 +65,14 @@
 build: $(STAMP_DIR)/build
 $(STAMP_DIR)/build: $(STAMP_DIR)/source.make $(DOBUILDCOMPAT)
        dh_testdir
-       cd $(BUILD_TREE) && CC=$(DEB_HOST_GNU_TYPE)-gcc CFLAGS="-O3 -g 
-D_REENTRANT -fPIC" ./configure --shared
+       cd $(BUILD_TREE) && CC=$(CC) CFLAGS="-O3 -g -D_REENTRANT -fPIC" 
./configure --shared
        $(MAKE) -C $(BUILD_TREE) all libz.a $(TESTS)
-       $(MAKE) CC=$(DEB_HOST_GNU_TYPE)-gcc -C $(BUILD_TREE)/contrib/minizip
+       $(MAKE) CC=$(CC) -C $(BUILD_TREE)/contrib/minizip
        touch $@

 $(STAMP_DIR)/build-64: $(STAMP_DIR)/source.make
        dh_testdir
-       cd $(BUILD_TREE) && CC="$(DEB_HOST_GNU_TYPE)-gcc -m64" 
CFLAGS="-O3 -g -D_REENTRANT -fPIC" ./configure --shared
+       cd $(BUILD_TREE) && CC="$(CC64)" CFLAGS="-O3 -g -D_REENTRANT 
-fPIC" ./configure --shared
        $(MAKE) -C $(BUILD_TREE) clean
        $(MAKE) -C $(BUILD_TREE) all libz.a $(TESTS)
        touch $@
@@ -73,7 +80,7 @@
 $(STAMP_DIR)/build-nopic: $(STAMP_DIR)/source.make
        dh_testdir
        mkdir -p debian/nopic-tmp
-       cd $(BUILD_TREE) && CC=$(DEB_HOST_GNU_TYPE)-gcc CFLAGS="-O3 
-D_REENTRANT" ./configure
+       cd $(BUILD_TREE) && CC=$(CC) CFLAGS="-O3 -D_REENTRANT" ./configure
        $(MAKE) -C $(BUILD_TREE) clean
        $(MAKE) -C $(BUILD_TREE) all libz.a $(TESTS)
        $(MAKE) -C $(BUILD_TREE) install prefix=$(CURDIR)/debian/nopic-tmp
@@ -84,7 +91,7 @@
 $(STAMP_DIR)/build-64-nopic: $(STAMP_DIR)/source.make
        dh_testdir
        mkdir -p debian/nopic-tmp
-       cd $(BUILD_TREE) && CC="$(DEB_HOST_GNU_TYPE)-gcc -m64" 
CFLAGS="-O3 -D_REENTRANT" ./configure --libdir=\$${prefix}/lib64
+       cd $(BUILD_TREE) && CC="$(CC64)" CFLAGS="-O3 -D_REENTRANT" 
./configure --libdir=\$${prefix}/lib64
        $(MAKE) -C $(BUILD_TREE) clean
        $(MAKE) -C $(BUILD_TREE) all libz.a $(TESTS)
        $(MAKE) -C $(BUILD_TREE) install prefix=$(CURDIR)/debian/nopic-tmp
--------------------------------------

**5.5. Create a cross compile scratchbox using sb-menu.  C

- choose the powerpc-xxx-linux-gnu compiler.
- add the 'cputransp', 'doctools', 'debian' and 'perl' devkits
- select 'qemu-ppc-0.8.1-sb2' CPU-transparancy emulation
- no rootstrap
- add 'C-library', '/etc', 'Devkits' and 'fakeroot' files to the target
- then patch as described above in 5.1-5.3
- don't forget to set proxies if necessary for http 'export 
http_proxy=http://xxx.xxx.xxx.xxx:xxxx'
- create a sources.list file containing an appropriate sarge mirror for 
sources.  I used 'deb-src http://mirrors.ircam.fr/pub/debian/ sarge main'
- follow the instructions described at 
http://www.scratchbox.org/wiki/Crocodile
Once the new sandbox has been created

[sbox-ppc860-croc: ~] >export ftp_proxy=http://xxx.xxx.xxx.xxx:xxxx
[sbox-ppc860-croc: ~] >export ftp_proxy=http://xxx.xxx.xxx.xxx:xxxx
[sbox-ppc860-croc: ~] >darcs get --set-scripts-executable 
http://scratchbox.org/repos/crocodile
- get the crocodile files

[sbox-ppc860-croc: ~] >echo 'deb-src http://mirrors.ircam.fr/pub/debian/ 
sarge main' > /etc/apt/sources.list
[sbox-ppc860-croc: ~] >apt-get update
[sbox-ppc860-croc: ~] >mkdir crocodile-packages
[sbox-ppc860-croc: ~] >cd crocodile-packages
[sbox-ppc860-croc: ~/crocodile-packages] >apt-get source -d acl attr 
base-files base-passwd bash bc bzip2 chrpath coreutils cpio cracklib2 
db1-compat db3 db4.2 debianutils diffutils dpkg e2fsprogs findutils 
fribidi gdbm grep gzip hostname libcap libselinux libsepol makedev mawk 
modutils ncurses netbase pam perl procps readline4 sed shadow slang 
sysvinit tar tcl8.3 tcl8.4 util-linux zlib
[sbox-ppc860-croc: ~/crocodile-packages] >dpkg-scansources . 
/dev/null|gzip>Sources.gz
- get source packages to build

[sbox-ppc860-croc: ~/crocodile] >cd ../crocodile
[sbox-ppc860-croc: ~/crocodile] >echo "deb-src 
file:/home/${USER}/crocodile-packages ./" > etc/sources.list
- setup sources.list so only the downloaded packages get built

[sbox-ppc860-croc: ~/crocodile] >export SBOX_UNAME_MACHINE=ppc
[sbox-ppc860-croc: ~/crocodile] >mkdir 
/scratchbox/users/${USER}/targets/`sb-conf cu`_deb_list
[sbox-ppc860-croc: ~/crocodile] >cat > 
/scratchbox/users/${USER}/targets/`sb-conf cu`_deb_list/flex << EOF
Source: flex
Version: 2.5.31
Binary: flex
EOF
- Setup as described in 5.1-5.2 to do the build

[sbox-ppc860-croc: ~/crocodile] >./unplanned-build.sh --clean
- Build the crocodile packages




More information about the Scratchbox-users mailing list