Stephan's Yocto XBMC

Someone much smarter than I has put in an epic amount of work to create an XBMC image based on the Yocto build system for iMX6 based boards such as the Wandboard and Udoo. I was an original Udoo kickstarter backer looking for something a little more powerful than the RaspberryPi. I haven't yet started looking at the Arduino features of the Udoo yet, mainly due to all the other half finished projects I have going. There's no point letting it sit idle though. Let's get rid of the old, struggling Mac Mini XBMC and use the Udoo instead.

Just to be clear, this documents my experience with the Udoo and Stephan's awesome work. I take credit for none of his efforts.

Stephan's Blog: http://stephan-rafin.net/blog/
His (Stephan is a guy's name right?) initial instructions for building the image: http://stephan-rafin.net/blog/2013/11/08/new-xbmc-yocto-image/
His first release for the Udoo: http://stephan-rafin.net/blog/2013/12/06/xbmc-for-udoo/

I re-used the VM I use for building deb packages for this task since it has most of the prerequisites already installed. The rest is basically cut and paste from Stephan's site (I've just changed some paths):

mkdir /var/lib/building/udooyocto-xbmc/
cd /var/lib/building/udooyocto-xbmc/
 
#Install repo
mkdir bin
curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > bin/repo
chmod a+x bin/repo
 
#Create BSP folder
PATH=${PATH}:/var/lib/building/udooyocto-xbmc/bin
mkdir xbmc-bsp
cd xbmc-bsp
 
#Download layers
repo init -u https://github.com/wolfgar/fsl-community-bsp-platform -b dora
repo sync
 
#Initialize build environement
#Valid MACHINE values are wandboard-quad, wandboard-dual, udoo-quad and utilite
TEMPLATECONF=`pwd`/sources/meta-stef/conf MACHINE=udoo-quad source setup-environment build-$(date +%s)

You should now be in a directory called build-<a timestamp>. Open the file conf/local.conf and change this line:

MACHINE = 'wandboard-quad'

to this:

MACHINE = 'udoo-quad'

Note: At the time of writing a small tweak to Stephan's source is needed. Apply this tweak before proceeding.
Note: The build process needs plenty of space. Make sure you have at least 25Gb of free space before proceeding.

Now we're ready to build:

#Let's build the whole thing
bitbake xbmc-image

Now it's time to find something else to do. The build is going to take hours.

The build failed

The build system isn't bullet proof. Sometimes things go wrong. Look at the output in red it will help you work out what's wrong.

Don't worry, you're not starting all over again. Bitbake will pick up from where it left off.

Just give it another shot

I have seen mentioned a few times that because bitbake runs multiple threads it mightn't always get dependencies ready before the things that depend on them. I'd suggest running bitbake at least 3 times before deciding that there's a problem that needs to be fixed.

You can add an argument to bitbake to force it to continue if errors occur (bitbake xbmc-image -k). You probably won't end up with a working image but at least you know everything other than that package is built in advance of your next attempt.

Files that won't download

I have had issues with the builder trying to download files from SourceForge and failing because SourceForge was kindly automatically selecting a mirror that wasn't responding. I worked around this by downloading the file manually from another SourceForge mirror and putting the file in /var/lib/building/udooyocto-xbmc/xbmc-bsp/downloads. Then, in that same directory touch (i.e. create an empty file) with the same name as the downloaded file with .done on the end. This way the builder knows the file has been completely downloaded successfully.

xbmc-13-r1.1 do_configure step fails

Your build fails with the following output:

| checking for zip... no
| configure: error: Could not find a required program. Please see the README for your platform.
| WARNING: exit code 1 from a shell command.
| ERROR: Function failed: do_configure (log file is located at /var/lib/building/udooyocto-xbmc/xbmc-bsp/build-1406027541/tmp/work/udoo_quad-poky-linux-gnueabi/xbmc/13-r1.1/temp/log.do_configure.28666)
ERROR: Task 379 (/var/lib/building/udooyocto-xbmc/xbmc-bsp/sources/meta-stef/recipes-stef/xbmc/xbmc_13.bb, do_configure) failed with exit code '1'
NOTE: Tasks Summary: Attempted 3125 tasks of which 3092 didn't need to be rerun and 1 failed.
Waiting for 0 running tasks to finish:

Summary: 1 task failed:
  /var/lib/building/udooyocto-xbmc/xbmc-bsp/sources/meta-stef/recipes-stef/xbmc/xbmc_13.bb, do_configure
Summary: There was 1 WARNING message shown.
Summary: There was 1 ERROR message shown, returning a non-zero exit code.

Open xbmc-bsp/sources/meta-stef/recipes-stef/xbmc/xbmc.inc and append zip-native on the DEPENDS line, inside the quotes like this:

DEPENDS = "mysql5 libsamplerate0 alsa-lib udev libvorbis boost libass mpeg2dec libmad libmodplug tiff yajl libtinyxml taglib libcdio jasper libmicrohttpd libssh samba rtmpdump libbluray libnfs samba swig-native libxslt libplist shairplay flac zip-native"

Try the build again.

Storing Configuration and Media Library elsewhere on the network

Reference: http://wiki.xbmc.org/index.php?title=HOW-TO:Share_libraries_using_MySQL

Stephan and those upstream of him are still putting quite a bit of development into this software. This means that I'm probably going to be replacing the image on the MicroSD card in the Udoo pretty frequently. I don't want to be reconfiguring everything (adding Media Sources, Themes, etc.) every time there's a new image to install so I want to keep as much as possible external to the Udoo itself.

My actual media is stored on my NAS so that is already taken care of. What we can do additionally is move the library's meta-data into an MySQL server database on the NAS and move XBMC's configuration files into an additional NFS share on the NAS.

This means that when we startup XBMC with a brand new image, it will remember what it's predecessor knew. This would also lay the ground work for having multiple XBMC devices throughout the home that share meta-data and configuration.

Create an NFS Share

On my NAS (ph1-clm.ad.ghanima.net) I created a directory in /var/lib/shares/ called XBMCProfile. I made it world writable (TODO: tighten this up):

chmod -R 666 /var/lib/shares/XBMCProfile/
chmod -R +X /var/lib/shares/XBMCProfile/
chown -R root:root /var/lib/shares/XBMCProfile/

And added an export in my NFS service (/etc/exports):

/var/lib/shares/XBMCProfile 172.30.1.206(ro,sync,no_subtree_check,insecure)

Prepare MySQL/MariaDB

CREATE DATABASE xbmc_videos;
CREATE DATABASE xbmc_music;

Create an advancedsettings.xml

<advancedsettings>
    <videodatabase>
        <type>mysql</type>
        <host>ph1-clm.ad.ghanima.net</host>
	<name>xbmc_videos</name>
        <port>3306</port>
        <user>xbmc</user>
        <pass>xbmc</pass>
    </videodatabase> 
 
    <musicdatabase>
        <type>mysql</type>
        <host>ph1-clm.ad.ghanima.net</host>
	<name>xmbc_music</name>
        <port>3306</port>
        <user>xbmc</user>
        <pass>xbmc</pass>
    </musicdatabase>
 
     <videolibrary>
          <importwatchedstate>true</importwatchedstate>
          <importresumepoint>true</importresumepoint>
     </videolibrary>
 
     <pathsubstitution>
          <substitute>
               <from>special://profile/playlists/</from>
               <to>nfs://ph1-clm.ad.ghanima.net//var/lib/shares/XBMCProfile/xbmc/userdata/playlists/</to>
          </substitute>
          <substitute>
               <from>special://profile/addon_data/</from>
               <to>nfs://ph1-clm.ad.ghanima.net//var/lib/shares/XBMCProfile/xbmc/userdata/addon_data/</to>
          </substitute>
          <substitute>
               <from>special://profile/sources.xml</from>
               <to>nfs://ph1-clm.ad.ghanima.net//var/lib/shares/XBMCProfile/xbmc/userdata/sources.xml</to>
          </substitute>
          <substitute>
               <from>special://profile/mediasources.xml</from>
               <to>nfs://ph1-clm.ad.ghanima.net/var/lib/shares/XBMCProfile/xbmc/userdata/mediasources.xml</to>
          </substitute>
          <substitute>
               <from>special://profile/guisettings.xml</from>
               <to>nfs://ph1-clm.ad.ghanima.net/var/lib/shares/XBMCProfile/xbmc/userdata/cubox-i_guisettings.xml</to>
          </substitute>
     </pathsubstitution>
</advancedsettings>

Note: Using path substitution on guisettings.xml doesn't work. Settings are saved to the redirected path but read from the local version.

Inject the advancedsettings.xml into the image we built

TODO

Import an existing configuration

I wasn't overly interested in importing my media library but I had still spent a fair bit of time getting XBMC set up nicely, nice theme, adjusted for my TV, remote working, etc. I'm going to copy just the configuration elements into the NAS side profile.

I copied: TODO

Additional Python Packages and Bazaar

I had originally thought to have the XBMC configuration periodically checked-in to my bazaar repository for the purposes of backup and then restoring to a freshly re-imaged MicroSD card. This was superceeded by the above but the process is recorded here for future reference.

Manual Downloads

Install some dependencies

smart install python-distutils
smart install python-ctypes
smart install python-compile

Install this Python component that is usually part of the default Python installation but was probably stripped out to save space:

wget http://hg.python.org/cpython/raw-file/de62e7a64346/Lib/contextlib.py
cp contextlib.py /usr/lib/python2.7/site-packages/

The package manager won't install this because it depends on python-ctypes-dev which doesn't exist. Manually installing it works though:

wget http://www.stephan-rafin.net/rpmhf2/cortexa9hf_vfp_neon/python-dev-2.7.3-r0.3.cortexa9hf_vfp_neon.rpm
rpm -ihv python-dev-2.7.3-r0.3.cortexa9hf_vfp_neon.rpm

Build and Install

cd ~
tar -xzf pycrypto-2.6.1.tar.gz
cd pycrypto-2.6.1
python setup.py install
 
cd ~
tar -xzf ecdsa-0.10.tar.gz
cd ecdsa-0.10
python setup.py install
 
cd ~
tar -xzf paramiko-1.12.1.tar.gz
cd paramiko-1.12.1
python setup.py install
 
cd ~
tar -xzf Pyrex-0.9.9.tar.gz
cd Pyrex-0.9.9
python setup.py install
 
cd ~
tar -xzf bzrtools-2.6.0.tar.gz
cd bzrtools
python setup.py install

Now we'll build bzr itself:

cd ~
tar -xzf bzr-2.6.0.tar.gz
cd bzr-2.6.0
python setup.py install
cd ~

Does it work?

bzr --help

Next time...

Next time round, we can build RPMs instead of installing directly which would allow us keep the .rpm files and not repeat this build process each time we need bazaar installed. We can just drop in the .rpms and install them: