Compiling and running pulseaudio from git

来源:互联网 发布:实验网络应用层协议 编辑:程序博客网 时间:2024/05/16 08:49
A few budding developers have asked me recently about this and to make life easy, I decided to write up this guide! There are some gotchas to look out for so please read carefully!

Are we ready? OK, lets being!

The shell output shown below will include my machine's name, "Eoollo". My bash prompt also shows the current git branch thanks to the git-prompt package in Mandriva (you can enable it manually by following this guide). Note that for various reasons I wont go into in this guide, the development version of PA is currently 0.9.19, this is despite the current released version being 0.9.21. Its due to how the git tree is organised, and I'm hoping to fix this soon. Edit: Git master is now tracking PA 1.0 (not for any specific milestone of 1.0, but just because a 3-point version number is kinda annoying. Essential the version policy is now decided and all should be working fine now. There may still be a 0.9.23 based of the current stable-queue branch, but the next release from master will be 1.0.
May the Source Be With You

The first job is to clone our code repository. You first have to pick where you want to keep your development version. In the example below I've decided to use a folder under my home directory called "padev"

[Ubuntu@Eoollo ~]$ git clone git://git.0pointer.de/pulseaudio.git padev
Cloning into padev...
remote: Counting objects: 39578, done.
remote: Compressing objects: 100% (6760/6760), done.
remote: Total 39578 (delta 32779), reused 39578 (delta 32779)
Receiving objects: 100% (39578/39578), 14.56 MiB | 1.97 MiB/s, done.
Resolving deltas: 100% (32779/32779), done.
[Ubuntu@Eoollo ~]$

Now you should have a ~/padev/ folder containing the code.

Compile Time

Now it's time to compile the code, but before we do this, we have to prepare the checkout for compilation. Handily there is a script provided to make this easy for us.

[Ubuntu@Eoollo ~]$ cd padev/
[Ubuntu@Eoollo padev (master)]$ ./bootstrap.sh -V
+ case $(uname) in
++ uname
...
+ make clean
make: *** No rule to make target `clean'.  Stop.
[Ubuntu@Eoollo padev (master)]$

There is an error about not being able to "make clean" here but you can safely ignore that.

Next we'll create a build directory. This is not mandatory, but it helps keep temporary build files etc. separate from the code in the checkout (there are special git commands to delete such files but all the same, I feel this is cleaner). After creating the build directory, we change to it and run the configure script.

[Ubuntu@Eoollo padev (master)]$ mkdir build
[Ubuntu@Eoollo padev (master)]$ cd build/
[Ubuntu@Eoollo build (master)]$ ../configure --prefix=$(pwd)
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...
config.status: executing po/stamp-it commands

---{ pulseaudio 0.9.19-562-g395da }---

prefix:                        /home/Ubuntu/padev/build
sysconfdir:                    ${prefix}/etc
localstatedir:                 ${prefix}/var
System Runtime Path:           ${prefix}/var/run/pulse
System State Path:             ${prefix}/var/lib/pulse
System Config Path:            ${prefix}/var/lib/pulse
Compiler:                      gcc -std=gnu99
CFLAGS:                        -g -O2 -Wall -W -Wextra -pipe -Wno-long-long -Winline -Wvla -Wno-overlength-strings -Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op -Wsign-compare -Wformat-security -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Winit-self -Wdeclaration-after-statement -Wfloat-equal -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels -Wcast-align -Wstrict-aliasing=2 -Wwrite-strings -Wno-unused-parameter -ffast-math -Wp,-D_FORTIFY_SOURCE=2 -fno-common -fdiagnostics-show-option -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include

Have X11:                      yes
Enable OSS Output:             yes
Enable OSS Wrapper:            yes
Enable CoreAudio:              no
Enable Alsa:                   yes
Enable Solaris:                no
Enable GLib 2.0:               yes
Enable Gtk+ 2.0:               yes
Enable GConf:                  yes
Enable Avahi:                  yes
Enable Jack:                   yes
Enable Async DNS:              yes
Enable LIRC:                   yes
Enable DBUS:                   yes
Enable HAL:                    yes
Enable udev:                   yes
Enable HAL->udev compat:       no
Enable BlueZ:                  yes
Enable TCP Wrappers:           yes
Enable libsamplerate:          yes
Enable IPv6:                   yes
Enable OpenSSL (for Airtunes): yes
Enable tdb:                    yes
Enable gdbm:                   no
Enable simple database:        no
Enable fftw:                   yes

System User:                   pulse
System Group:                  pulse
Access Group:                  pulse-access
Enable per-user EsounD socket: yes
Force preopen:                 no
Preopened modules:             all
[Ubuntu@Eoollo build (master)]$

You should pay particular attention to the --prefix argument passed to configure. Rather than "installing" this version of PulseAudio, we'll just run it from the source tree. This is both quicker and saves any potential conflict with your system-installed PulseAudio packages.

You should also pay attention to the table at the end which lists the available support. In order for automatic card detection to work properly with your build, you really should ensure that udev support in particular is available. If it does not print a "yes" line in the output then you probably do not have the "udev-devel" package for your distro installed.
Let's Build

OK, so you're ready to build! But not quite. Due to an upstream bug, the translations for .desktop files are not written if the destination folder does not exist, so let's create it manually

[Ubuntu@Eoollo build (master)]$ mkdir -p src/daemon
[Ubuntu@Eoollo build (master)]$

OK, with all the prep work done, we really do build it.

[Ubuntu@Eoollo build (master)]$ make
echo 0.9.19-562-g395da > ../.version-t && mv ../.version-t ../.version
make  all-recursive
...
file=`echo zh_TW | sed 's,.*/,,'`.gmo \
 && rm -f $file && /usr/bin/msgfmt -o $file ../../po/zh_TW.po
make[2]: Leaving directory `/home/Ubuntu/padev/build/po'
make[2]: Entering directory `/home/Ubuntu/padev/build'
make[2]: Leaving directory `/home/Ubuntu/padev/build'
make[1]: Leaving directory `/home/Ubuntu/padev/build'
[Ubuntu@Eoollo build (master)]$

Now that it's built successfully we can run it, but we'll do a little bit of preparation first. As ALSA currently lacks UCM (Use Case Management) (although this is due to be added soon), PulseAudio supports a fairly robust "probing" system to determine how your sound hardware works. In order to run these probes it has to know where to look for the "mixer profile" definitions. As we are running from the build tree, we'll cheat a little and use a symlink so that our development build can find the files.

[Ubuntu@Eoollo build (master)]$ mkdir -p share/pulseaudio
[Ubuntu@Eoollo build (master)]$ ln -s ../../../src/modules/alsa/mixer share/pulseaudio/alsa-mixer
[Ubuntu@Eoollo build (master)]$

In order to run some test tools, we also need to manually create some symlinks that are normally done as part of the install process.

[Ubuntu@Eoollo build (master)]$ ln -s pacat src/paplay
[Ubuntu@Eoollo build (master)]$ ln -s pacat src/parec
[Ubuntu@Eoollo build (master)]$

Run, Forest, Run!

Now that things are built and some symlinks are in place, we can run our nice shiny development version. You should first ensure that the system-installed PulseAudio daemon is not running. In order to do this, you should disable autospawn by doing:

echo "autospawn=no" >> ~/.pulse/client.conf

Once this is done, you should reboot. PulseAudio will likely still start when you log in to X11 by virtue of the start-pulseaudio-x11 script that is run at login, but some systems that rely on PA autospawn may not initialise correctly (e.g. under KDE knotify and kmix may start in 'ALSA mode'. This is generally not a problem, but you should be aware of the consequences.

So if your system PA has been run, simply execute:

pulseaudio -k

To kill the currently running daemon. You can then start your development version via:

[Ubuntu@Eoollo build (master)]$ src/pulseaudio -n -F src/default.pa -p $(pwd)/src/.libs/ -vvvv
W: main.c: Couldn't canonicalize binary path, cannot self execute.
I: main.c: setrlimit(RLIMIT_NICE, (31, 31)) failed: Operation not permitted
I: main.c: setrlimit(RLIMIT_RTPRIO, (9, 9)) failed: Operation not permitted
D: core-rtclock.c: Timer slack is set to 50 us.
D: core-util.c: RealtimeKit worked.
I: core-util.c: Successfully gained nice level -11.
I: main.c: This is PulseAudio 0.9.19-562-g395da
...

This will produce a lot of debug output, so you should leave that terminal running. The command line arguments are as follows: "-n" says "do not process the (system) default.pa". This is generally only needed if you have a ~/.pulse/default.pa file, but it does no harm to include it always. "-F src/default.pa" says to "process the script src/default.pa" and "-p $(pwd)/src/.libs" tells PA where to look for it's modules (i.e. from your build tree).

Note that the state files saved by PulseAudio in ~/.pulse/ folder will very likely NOT conflict with your system PA's files. This is because our development PA build does not know the right path to look for /var/lib/dbus/machine-id. Because of this, the prefix used on files will default to the host name of your machine, not the string of apparently random numbers and letters that you may see in there already. If you cross reference, the output from cat /var/lib/dbus/machine-id will show the same number as used here. We do this to ensure we can have separate preferences for different machines when your home directory is shared over e.g. NFS - the machine-id is more stable than the hostname which is why we prefer that as a prefix.
Running a Client App

So now that everything is running, you should be able to run a client application. As the build tree comes with some utilities you can run them directly from there:

[Ubuntu@Eoollo build (master)]$ src/paplay -vv /usr/share/sounds/ia_ora-startup.wav
Opening a playback stream with sample specification 's16le 2ch 22050Hz' and channel map 'front-left,front-right'.
Connection established.
Stream successfully created.
Buffer metrics: maxlength=4194304, tlength=176400, prebuf=174640, minreq=1764
Using sample spec 's16le 2ch 22050Hz', channel map 'front-left,front-right'.
Connected to device alsa_output.pci-0000_00_1b.0.analog-stereo (0, not suspended).
Stream started.
Stream underrun.
Playback stream drained.: 1007045 usec.
Draining connection to server.

If, however you want to run a more advanced client application, then you need to employ a little hack to tell your system to use your development version of libpulse. This is quite trivial:

[Ubuntu@Eoollo build (master)]$ export LD_LIBRARY_PATH=$(pwd)/src/.libs
[Ubuntu@Eoollo build (master)]$ mplayer /path/to/your/fav.mp3
...

Easy eh? That's all you need to do to run PulseAudio from git. You can now easily try out patches, write your own modules and help contribute! Happy hacking.
Some notes on Overlinking

So, just before I sign off, I thought it was best to mention overlinking. PulseAudio itself uses a shared library that is used by both client and server. This library is "libpulsecommon-0.9.x.so". Client applications should NOT link to this file directly - instead libpulse will load it in for you. This can lead to some strange results. e.g. consider the following output:

[Ubuntu@Eoollo ~]$ ldd `which paplay` | grep pulse
    libpulse.so.0 => /usr/lib64/libpulse.so.0 (0x00007f5bd9fc7000)
    libpulsecommon-0.9.21.so => /usr/lib64/libpulsecommon-0.9.21.so (0x00007f5bd9d76000)
[Ubuntu@Eoollo ~]$ ldd `which mplayer` | grep pulse
    libpulse.so.0 => /usr/lib64/libpulse.so.0 (0x00007f617c1f4000)
    libpulsecommon-0.9.21.so => /usr/lib64/libpulsecommon-0.9.21.so (0x00007f6175f08000)

This looks more or less the same right? Not quite. Compare this to:

[Ubuntu@Eoollo ~]$ objdump -p `which paplay` | grep pulse
  NEEDED               libpulse.so.0
  NEEDED               libpulsecommon-0.9.21.so
  required from libpulse.so.0:
[Ubuntu@Eoollo ~]$ objdump -p `which mplayer` | grep pulse
  NEEDED               libpulse.so.0
  required from libpulse.so.0:

So what you can see here is that my paplay really does need both, but mplayer actually only does not directly need libpulsecommon-0.9.21.so. But what does this mean to you when running things? Well, due to the fact that PulseAudio has this kind of circular dependancy internally, we cannot use the --no-undefined or --as-needed build options. This means that the PulseAudio package is Over linked. This is why the paplay utility needs libpulsecommond-0.9.21.so directly, unlike mplayer, which does not.

So if you try and use the above guide and ultimately run the system provided paplay utility, you'll find you run into problems. This is because the system libpulsecommon-0.9.21.so will be used, not your freshly compiled version (which could have a completely different version number - e.g. libpulsecommon-0.9.19.so!).

While we don't need to run the system paplay (as we have built our own version), it's easy to forget this quirk and break things. If you want to be sure, you can place a symlink in your build folder to fool the system into loading your libpulsecommon, even when the versions don't "match". As this is an overlinking problem, there is little danger in doing this hack:

[Ubuntu@Eoollo build (master)]$ ln -s libpulsecommon-0.9.19.so src/.libs/libpulsecommon-0.9.21.so
[Ubuntu@Eoollo build (master)]$

This puts the necessary symlink in place to make my dev build (0.9.19) replace the system build (0.9.21). This only has effect with the LD_LIBRARY_PATH variable set, so it wont interfere with anything on your system.

Depending on your your distro packages things, the problems of overlinking may be present in more than just the paplay utility. So check this out and use objdump -p to confirm the client application you want to run is linked correctly and use the symlink hack if needed.
原创粉丝点击