<!doctype linuxdoc system>
<linuxdoc><article>
<titlepag>
  <title>Cross compiling VLC for ARM-Linux based platforms</title>
  <author>Marc Ariberti <tt><htmlurl url="mailto:marcari@videolan.org" name="<marcari@videolan.org>"></tt></author>
  <date>v0.0.1, 13 march 2003</date>
  <abstract>
    This document describes all the steps to cross compile vlc for ARM based
    platforms. It describes how to build a cross compilation toolchain, how to
    build the libraries needed by vlc and the compilation of the vlc itself.
  </abstract>
</titlepag>

<toc>

<sect>
  <heading>Introduction</heading>
  <p>
  This document is only a first draft. It does not intend to cover all the 
  subject. You may still have some problems at some steps or find better 
  way to do them. If you have any comment do not hesitate to contact us.
  </p>
  <sect1>
    <heading>Which platforms are targeted ?</heading>
    <p>
      I will describe here how to compile vlc for an ARM based
      PDA running linux. It includes for example :
      <itemize>
      <item>Compaq - iPaq (H36xx, H38xx,...), using
        <itemize>
          <item>Familiar linux
          <item>Opie
        </itemize>
      </item>
      <item>YOPY/Linupy</item>
      <item>Zaurus</item>
      </itemize>
    </p>
  </sect1> 
  <sect1>
    <heading>Requirements for cross-compilation</heading>
  </sect1>
  <sect1>
    <heading>Why cross-compiling ?</heading>
    <p>
      It is of course possible to compile directly on the targeted platform.
      But there are a lot of great advantages to cross-compile :
      <itemize>
      <item>The most important one is probably the speed, because a
        desktop computer is most of the time faster than a PDA for
        compilation.</item>
      <item>Another big problem is that a complete compilation toolchain
        does take a great amount of disk space. And this space is usually
        very limited on embedded systems.</item>
      <item>And there also may not be enough memory to compile big files.</item>
      </itemize>
    </p>
  </sect1>
</sect>

<sect>
  <heading>Building the toolchain</heading>
  <sect1>
    <heading>Prerequisite</heading>
    <sect2>
      <heading>Importants paths</heading>
      <p>
        During this section, we will use the following paths :
      </p>
      <p>I would personally advise to compile everything as a normal user and
      then install everything as root.</p>
      <sect3>
        <heading>${SRCDIR}</heading>
        <p>
        This is where the sources will be located and where the compilation
        will be done.
        (eg: <tt>/usr/src</tt> or <tt>/home/foobar/arm-src</tt>).
        </p>
      </sect3>
      <sect3>
        <heading>${PREFIX}</heading>
        <p>This is where you want to install your cross compilation toolchain.
        It can be either installed system-wide (in <tt>/usr/local/arm/2.95.3</tt> for example). Installation steps (i.e. <tt>make install</tt>) will have
        to be done as <tt>root</tt>.
        Or it can be installed in user-land, for the user's own use (<tt>/home/foobar/arm/2.95.3</tt> for example).
        In this paper, the chosen prefix is <tt>/usr/local/arm/2.95.3</tt>,
        you will have to adapt the commands to what you choose..
        </p>
      </sect3>
    </sect2>
    <sect2>
      <heading>Files needed</heading>
      <p>Download the following files and put them in the <bf>${SRCDIR}</bf>.
      Most of them are available on the <htmlurl url="http://www.videolan.org/vlc/download-sources.html" name="VideoLAN website">.
        <itemize>
          <item><tt>binutils-2.11.2.tar.gz</tt></item>
          <item><tt>linux-2.4.19.tar.bz2</tt></item>
          <item><tt>patch-2.4.19-rmk4.bz2</tt></item>
          <item><tt>gcc-2.95.3.tar.gz</tt></item>
          <item><tt>gcc-2.95.3.diff.bz2</tt></item>
          <item><tt>gcc-2.95.3.diffbis.bz2</tt></item>
          <item><tt>gcc-2.95.3.diff2</tt></item>
          <item><tt>glibc-2.2.5.tar.gz</tt></item>
          <item><tt>glibc-linuxthreads-2.2.5.tar.gz</tt></item>
          <item><tt>SDL-1.2.5.tar.gz</tt></item>
          <item><tt>glib-1.2.10.tar.gz</tt></item>
          <item><tt>ffmpeg.tar.gz</tt></item>
          <item><tt>mad-0.14.2b.tar.gz</tt></item>
          <item><tt>flac-1.1.0.tar.gz</tt></item>
          <item><tt>libdvbpsi-0.1.2.tar.gz</tt></item>
          <item><tt>a52dec-0.7.4.tar.gz</tt></item>
        </itemize>
      </p>
    </sect2>
  </sect1>
  <sect1>
    <heading>Binutils</heading>
    <p>Compiling binutils is pretty simple :
    <tscreen><verb>
tar xzf binutils-2.11.2.tar.gz
cd binutils-2.11.2
./configure --target=arm-linux --prefix=/usr/local/arm/2.95.3
make
make install
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>Preparing linux kernel</heading>
    <p>
    <tscreen><verb>
tar xzf linux-2.4.19.tar.bz2
bunzip2 patch-2.4.19-rmk4.bz2
cd linux-2.4.19
patch -p1 &lt; ../patch-2.4.19-rmk4.bz2
make clean ARCH=arm CROSS_COMPILE=arm-linux-
make ARCH=arm h3600_config
  </verb></tscreen>
  <bf>Do not forget</bf> to save the configuration even if no changes 
  are made !
  <tscreen><verb>
make ARCH=arm menuconfig
make symlinks ARCH=arm CROSS_COMPILE=arm-linux-
mkdir -p /usr/local/arm/2.95.3/arm-linux/include
cp -Rf include/asm include/asm-arm include/linux \
                      /usr/local/arm/2.95.3/arm-linux/include
cd /usr/local/arm/2.95.3/arm-linux
ln -s include sys-linux
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>Basic cross compiler (gcc)</heading>
    <p>
    <tscreen><verb>
tar xvzf gcc-2.95.3.tar.gz
bunzip2 gcc-2.95.3.diff.bz2
bunzip2 gcc-2.95.3.diffbis.bz2
patch -p1 -d gcc-2.95.3 &lt; gcc-2.95.3.diff
patch -p1 -d gcc-2.95.3 &lt; gcc-2.95.3.diffbis
cd gcc-2.95.3
./configure --target=arm-linux --disable-threads --enable-languages=c \
        --prefix=/usr/local/arm/2.95.3 --with-headers=linux-2.4.19/include
make
make install
    </verb></tscreen>
    </p>

  </sect1>
  <sect1>
    <heading>Compiling glibc</heading>
    <p>
    Depending on your target, you may choose another glibc version (eg: 2.1.3 for linupy 1.4)
    <tscreen><verb>
tar xvzf glibc-2.2.5.tar.gz
cd glibc-2.2.5
tar xvzf ../glibc-linuxthreads-2.2.5.tar.gz
CC=arm-linux-gcc ./configure arm-linux --target=arm-linux \
          --prefix=/usr/local/arm/2.95.3/arm-linux --enable-add-ons
    </verb></tscreen>

The following step is quite long !

    <tscreen><verb>
CC=arm-linux-gcc make
    </verb></tscreen>

If you have problems compiling glibc due to pread/pwrite, edit <tt>sysdeps/unix/sysv/linux/kernel-features.h</tt>
and turn <tt>__ASSUME_PREAD_SYSCALL</tt> and 
<tt>__ASSUME_PWRITE_SYSCALL</tt> from 1 to 0.

    <tscreen><verb>
CC=arm-linux-gcc make install
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>Full cross compiler (gcc)</heading>
    <p>
    <tscreen><verb>
rm -Rf gcc-2.95.3
tar xvzf gcc-2.95.3.tar.gz
patch -p1 -d gcc-2.95.3 &lt; gcc-2.95.3.diff
patch -p1 -d gcc-2.95.3 &lt; gcc-2.95.3.diff2
cd gcc-2.95.3
./configure --target=arm-linux --prefix=/usr/local/arm/2.95.3
make
make install
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>Compiling linux kernel</heading>
  </sect1>
  <sect1>
    <heading>Misc</heading>
    <p>
    Add <tt>/usr/local/arm/2.95.3/bin</tt> to your PATH. Add the following line (depends on your shell)
    to your shell's configuration file :
    <tscreen><verb>
export PATH=/usr/local/arm/2.95.3/bin:$PATH
    </verb></tscreen>
    I would advise you to completely log out and then log in again, so that
    the change would be taken into account. You can now check that when you
    type <tt>arm-linux-gcc</tt>, it launches the cross-compiler.
    </p>

    <p>
    Next are some packages that you may compile by yourself, but I found
    it was easier to use the precompiled packages. You can take them
    at <htmlurl url="http://ipkgfind.handhelds.org/" name="ipkgfind">.
    You may find packages with other version numbers which should not be
    a problem.
    <descrip>
    <tag><tt>libgcc1_3.1.1-1_arm.ipk</tt></tag>
        This provides libgcc.so.1 which is needed to compile some libraries.
    <tag><tt>xlibs_4.1-5_arm.ipk</tt>, <tt>xlibs-dev_4.1.0-16_arm.ipk</tt></tag>
        Those are the libraries ans the development files for X windows.
    <tag><tt>zlib1g_1.1.4-3_arm.ipk</tt>, <tt>zlib1g-dev_1.1.3-fam1_arm.ipk</tt></tag>
        These libraries are needed by some libraries to compile.
    </descrip>
    
    Install these packages on your compiler box in <tt>/usr/local/arm/2.95.3/arm-linux</tt> :
     You can use the script <tt>install.sh</tt> :
    <tscreen><verb>
#!/bin/sh
# script to install .ipk into the arm-toolchain
# usage : ./install.sh foobar.ipk

if ! tar xvzf $1 2> /dev/null
then
    ar xv $1 2> /dev/null
fi
cp data.tar.gz /usr/local/arm/2.95.3/arm-linux
cd /usr/local/arm/2.95.3/arm-linux
tar xvzf data.tar.gz
    </verb></tscreen>
    </p>
  </sect1>
</sect>



<sect>
  <heading>Cross compiling libraries needed by vlc</heading>
  <p>
  Download <tt>ipaq-config.site</tt> to ${SOURCES}.
  When downloading source tarballs copy them to your ${SOURCES} directory.
  Each section is supposed to begin with <tt>cd ${SOURCES}</tt>.
  </p>
  <sect1>
    <heading>SDL</heading>
    <p>
    It is not clean at all but did not found a better working method.
    Using config.site
    it compiles well, but when linking with vlc there are problems !
    </p>
    <p>
    <tt>/usr/local/arm/2.95.3/arm-linux/bin</tt> should contain the cross 
    compiler without the prefix <tt>arm-linux-</tt>.
    
    <tscreen><verb>
tar xvzf SDL-1.2.5.tar.gz
cd SDL-1.2.5
./configure --enable-release --target=arm-linux --host=arm-linux \
      --disable-esd \
      --prefix=/usr/local/arm/2.95.3/arm-linux/usr \
      --x-includes=/usr/local/arm/2.95.3/arm-linux/usr/X11R6/include \
      --x-libraries=/usr/local/arm/2.95.3/arm-linux/usr/X11R6/lib \
      --disable-video-opengl

export PATH=/usr/local/arm/2.95.3/arm-linux/bin:$PATH

make && make install
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>Glib/GTK+</heading>
    <p>
    <tscreen><verb>
tar xvzf glib-1.2.10.tar.gz
cd glib-1.2.10
CONFIG_SITE=../ipaq-config.site ./configure \
      --prefix=/usr/local/arm/2.95.3/arm-linux/usr
make
make install
cd ..
tar xvzf gtk+-1.2.10.tar.gz
cd gtk+-1.2.10
CONFIG_SITE=../ipaq-config.site ./configure \
      --prefix=/usr/local/arm/2.95.3/arm-linux/usr --with-glib=../glib-1.2.10
make 
make install
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>ffmpeg</heading>
    <p>
    <tscreen><verb>
tar xvzf ffmpeg.tar.gz
cd ffmpeg
./configure --cpu=armv4l --cc=arm-linux-gcc --disable-mmx \
        --prefix=/usr/local/arm/2.95.3/arm-linux/usr --enable-shared
cd libavcodec
make
    </verb></tscreen>

    Vlc does not require that you install ffmpeg.
    </p>
  </sect1>
  <sect1>
    <heading>mad</heading>
    <p>
    <tscreen><verb>
tar xvzf mad-0.14.2b.tar.gz
cd mad-0.14.2b
./configure --enable-release --target=arm-linux --host=arm-linux \
      --disable-esd \
      --prefix=/usr/local/arm/2.95.3/arm-linux/usr \
      --x-includes=/usr/local/arm/2.95.3/arm-linux/usr/X11R6/include \
      --x-libraries=/usr/local/arm/2.95.3/arm-linux/usr/X11R6/lib \
      --disable-video-opengl
export PATH=/usr/local/arm/2.95.3/arm-linux/bin:$PATH
make
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>gpe</heading>
  </sect1>
  <sect1>
    <heading>tremor</heading>
    <p>
    Tremor is an integer decoder for the vorbis audio codec. Download the
    source through CVS at the <htmlurl url="http://www.xiph.org" name="xiph.org"> website.
    </p>
    <p>
    Log into CVS using the password : <tt>anoncvs</tt>.
    <tscreen><verb>
cvs -d :pserver:anoncvs@xiph.org:/usr/local/cvsroot login
cvs -d :pserver:anoncvs@xiph.org:/usr/local/cvsroot co Tremor
cd Tremor
CONFIG_SITE=../ipaq-config.site ./configure \
              --prefix=/usr/local/arm/2.95.3/arm-linux/usr
make
</verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>ogg</heading>
    <p>
    For ogg, it is the same as Tremor.
    <tscreen><verb>
cvs -d :pserver:anoncvs@xiph.org:/usr/local/cvsroot login
cvs -d :pserver:anoncvs@xiph.org:/usr/local/cvsroot co ogg
cd ogg
CONFIG_SITE=../ipaq-config.site ./configure \
             --prefix=/usr/local/arm/2.95.3/arm-linux/usr
make
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>flac</heading>
    <p>
    <tscreen><verb>
tar xvzf flac-1.1.0.tar.gz
cd flac-1.1.0
./configure --enable-release --host=arm-linux --target=arm-linux \
            --prefix=/usr/local/arm/2.95.3/arm-linux/usr
    </verb></tscreen>
    It will probably fail (due to the xmms plugin), but it is not a problem, 
    we will continue installation by hand.
    <tscreen><verb>
cp -Rf include/FLAC /usr/local/arm/2.95.3/arm-linux/include
cd src/libFLAC
make install
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>libdvbpsi</heading>
    <p>
    <tscreen><verb>
tar xvzf libdvbpsi-0.1.2.tar.gz
cd libdvbpsi-0.1.2
./bootstrap
./configure --target=arm-linux --host=arm-linux
make
    </verb></tscreen>
    </p>
  </sect1>
  <sect1>
    <heading>a52</heading>
    <p>
    <tscreen><verb>
tar xvzf a52dec-0.7.4.tar.gz
cd a52dec-0.7.4
./configure --enable-release --host=arm-linux --target=arm-linux \
            --prefix=/usr/local/arm/2.95.3/arm-linux/usr
make && make install
    </verb></tscreen>
    </p>
  </sect1>
</sect>

<sect>
  <heading>Cross compiling vlc itself</heading>
  <p>
  First of all, run the <tt>./bootstrap</tt> script.
  Then run one of the <tt>ipkg/rules.*</tt>, according to what you want to compile.
  Finally you just have to type make and you'll get a stand alone vlc.
  </p>
  <p>
  Run <tt>arm-linux-strip</tt> to remove symbols and so the size of the file,
  and now you can test it easily on your PDA.
  </p>
  <p>
    Enjoy !
  </p>
</sect>

</article></linuxdoc>
