ch0wned – Building Amarok 1.4.10 in $HOME on Redhat EL4/EL5

Written by max on 2010-04-05

ch0wned. adj. This is the state when you are a linux user and don't have root access.

Intro

All I wanted to do was play Internet radio via a SOCKS proxy. Is that too much to ask for on Redhat EL4? Apparently so. So after many hours of frustration, here is how you get Amarok 1.x (1.4.10 was the last one made) to compile and run from your homedir on Linux 2.ANCIENT.

UPDATE 1/28/2011: Updated for EL5 too!

This guide assumes you’re leaving off from my previous post : http://warped.org/blog/2009/03/04/chown3d-part-2-gtk-and-glib-in-your-own-home-directory/ where you’ve setup a script called config_gapp.

Prerequisites

  • amarok-1.4.10.tar.bz2
  • binutils-2.20.1.tar.bz2 (EL4 Only)
  • xine-lib-1.1.18.1.tar.bz2
  • taglib-1.6.1.tar.gz
  • ruby-devel package or ruby 1.8+ installed in $HOME
  • ffmpeg-0.5.1.tar.bz2
  • My Patches (EL4 or /dev/dsp1 only)

Building

For taglib, ffmpeg, and binutils:

config_gapp
make
make install
cp taglib-1.6.1/taglib.pc ~/lib/pkgconfig

For xine-lib :

config_gapp --without-speex
make
make install

For amarok:

config_gapp

Then apply this patch for EL4 only:

diff -ru amarok-1.4.10/amarok/src/mediadevice/generic/genericmediadevice.cpp amarok-1.4.10-max/amarok/src/mediadevice/generic/genericmediadevice.cpp
--- amarok-1.4.10/amarok/src/mediadevice/generic/genericmediadevice.cpp	2008-08-13 14:21:51.000000000 -0700
+++ amarok-1.4.10-max/amarok/src/mediadevice/generic/genericmediadevice.cpp	2010-04-05 16:21:11.000000000 -0700
@@ -557,7 +557,7 @@
     args["artist"] = artist;
     args["albumartist"] = albumartist;
     args["initial"] = albumartist.mid( 0, 1 ).upper();
-    args["filetype"] = mb.url().pathOrURL().section( ".", -1 ).lower();
+    args["filetype"] = mb.url().url().section( ".", -1 ).lower();
     QString track;
     if ( mb.track() )
         track.sprintf( "%02d", mb.track() );
@@ -657,7 +657,7 @@
 
     if( !kioCopyTrack( bundle.url(), desturl ) )
     {
-        debug() < < "Failed to copy track: " << bundle.url().pathOrURL() << " to " << desturl.pathOrURL() << endl;
+        debug() << "Failed to copy track: " << bundle.url().url() << " to " << desturl.url() << endl;
         return 0;
     }
 
@@ -833,7 +833,7 @@
 void
 GenericMediaDevice::dirListerClear( const KURL &url )
 {
-    QString directory = url.pathOrURL();
+    QString directory = url.path();
     GenericMediaFile *vmf = m_mfm[directory];
     if( vmf )
         vmf->deleteAll( false );
@@ -842,7 +842,7 @@
 void
 GenericMediaDevice::dirListerDeleteItem( KFileItem *fileitem )
 {
-    QString filename = fileitem->url().pathOrURL();
+    QString filename = fileitem->url().path();
     GenericMediaFile *vmf = m_mfm[filename];
     if( vmf )
         vmf->deleteAll( true );
diff -ru amarok-1.4.10/amarok/src/plugin/plugin.h amarok-1.4.10-max/amarok/src/plugin/plugin.h
--- amarok-1.4.10/amarok/src/plugin/plugin.h	2008-08-13 14:21:51.000000000 -0700
+++ amarok-1.4.10-max/amarok/src/plugin/plugin.h	2010-04-05 16:07:18.000000000 -0700
@@ -9,9 +9,11 @@
 
 #define AMAROK_EXPORT_PLUGIN( classname ) \
     extern "C" { \
-          KDE_EXPORT Amarok::Plugin* create_plugin() { return new classname; } \
+           __attribute__ ((visibility("default"))) Amarok::Plugin* create_plugin() { return new classname; } \
     }
 
+          //KDE_EXPORT Amarok::Plugin* create_plugin() { return new classname; } 
+
 #include <qmap .h>
 #include <qstring .h>
 
--- amarok-1.4.10/amarok/src/amarokcore/amarokconfig.cpp	2010-04-05 17:19:09.000000000 -0700
+++ amarok-1.4.10-max/amarok/src/amarokcore/amarokconfig.cpp	2010-04-05 15:46:37.000000000 -0700
@@ -465,8 +465,8 @@
   KConfigSkeleton::ItemBool  *itemMonitorChanges;
   itemMonitorChanges = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Monitor Changes" ), mMonitorChanges, true );
   addItem( itemMonitorChanges, QString::fromLatin1( "MonitorChanges" ) );
-  KConfigSkeleton::ItemPathList  *itemCollectionFolders;
-  itemCollectionFolders = new KConfigSkeleton::ItemPathList( currentGroup(), QString::fromLatin1( "Collection Folders" ), mCollectionFolders );
+  KConfigSkeleton::ItemString *itemCollectionFolders;
+  itemCollectionFolders = new KConfigSkeleton::ItemString ( currentGroup(), QString::fromLatin1( "Collection Folders" ), mCollectionFolders );
   addItem( itemCollectionFolders, QString::fromLatin1( "CollectionFolders" ) );
 
   setCurrentGroup( QString::fromLatin1( "MySql" ) );
 
</qstring></qmap>

Then go ahead with:

make
make install

Using /dev/dsp1 in Amarok 1.4

Let’s say you have an external soundcard or headphone amp plugged in USB and the thing registers as /dev/dsp1.

You will need to modify xine-lib to handle this :

--- xine-lib-1.1.18.1/src/audio_out/audio_oss_out.c.orig        2011-01-28 14:52:17.000000000 -0800
+++ xine-lib-1.1.18.1/src/audio_out/audio_oss_out.c     2011-01-28 15:07:03.000000000 -0800
@@ -662,7 +662,7 @@
  * If not, the function returns 0.
  */
 static int probe_audio_devices(oss_driver_t *this) {
-  const char *base_names[2] = {"/dev/dsp", "/dev/sound/dsp"};
+  const char *base_names[2] = {"/dev/dsp", "/dev/dsp1"};
   int base_num, i;
   int audio_fd, rate;
   int best_rate;
@@ -707,7 +707,7 @@
   int              audio_fd;
   int              num_channels, status, arg;
   static char     *sync_methods[] = {"auto", "getodelay", "getoptr", "softsync", "probebuffer", NULL};
-  static char     *devname_opts[] = {"auto", "/dev/dsp", "/dev/sound/dsp", NULL};
+  static char     *devname_opts[] = {"auto", "/dev/dsp", "/dev/dsp1", NULL};
   int devname_val, devname_num;
   /* for usability reasons, keep this in sync with audio_alsa_out.c */
   static char     *speaker_arrangement[] = {"Mono 1.0", "Stereo 2.0", "Headphones 2.0", "Stereo 2.1",

Then choose Amarok – Engine – Xine – OSS Device Configuration – Device = /dev/sound/dsp1. Enjoy. If you did the above steps and then got to this step, you will need to ‘make clean’ and ‘config_gapp’ again in xinelib and amarok.

Errors

Here are some of the error messages I encountered along the way that were solved w/ the prerequisites and patch. Hopefully this helps future googlers.

/usr/bin/ld: .libs/xine.o: relocation R_X86_64_PC32 against `xine_event_send' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value

Needs a newer version of binutils that handles X86_64 better.

amarokconfig.cpp: In constructor `AmarokConfig::AmarokConfig()':
amarokconfig.cpp:468: error: `ItemPathList' is not a member of `KConfigSkeleton'
amarokconfig.cpp:468: error: `itemCollectionFolders' was not declared in this scope
amarokconfig.cpp:469: error: `class KConfigSkeleton::ItemPathList' has not been declared

This is due to the old version of KDE 3.3 on EL4. Needs the patch above to amarokconfig.cpp.

void-engine.cpp:22: error: visibility arg must be one of "default", "hidden", "protected" or "internal"

Again, some ancient KDE 3.3 bug that is fixed by the patch above.

genericmediadevice.cpp: In member function `QString GenericMediaDevice::buildDestination(const QString&, const MetaBundle&)':
genericmediadevice.cpp:560: error: 'const class KURL' has no member named 'pathOrURL'
genericmediadevice.cpp: In member function `virtual MediaItem* GenericMediaDevice::copyTrackToDevice(const MetaBundle&)':
genericmediadevice.cpp:660: error: 'const class KURL' has no member named 'pathOrURL'
genericmediadevice.cpp:660: error: 'const class KURL' has no member named 'pathOrURL'
genericmediadevice.cpp: In member function `void GenericMediaDevice::dirListerClear(const KURL&)':
genericmediadevice.cpp:836: error: 'const class KURL' has no member named 'pathOrURL'
genericmediadevice.cpp: In member function `void GenericMediaDevice::dirListerDeleteItem(KFileItem*)':
genericmediadevice.cpp:845: error: 'const class KURL' has no member named 'pathOrURL'

More ancient KDE 3.3 stuff — pathOrURL() doesn’t exist yet, so we use either url() or path().

Last thing : doc/ was giving me issue, so I removed it from the Makefile under TOPSUBDIRS.

Running

I kept getting errors about “no sound-engine plugins found” until I added the two paths to $KDEDIRS as below :

#!/bin/sh
 
export KDEDIRS=$HOME/lib64/kde3:$HOME:/usr
 
exec run_gapp amarok "$@"