Closed peanutbutterandcrackers closed 4 years ago
The latest alsa-lib looks to the relative directory where the libasound.so is located:
You didn't write the purpose/demand to evaluate your request.
@perexg - Hello there,
Please forgive me for not clarifying things up. I will now try to explain my situation. However, I must admit that I am no expert and this is therefore just a request. Please do let me know if I have been unable to articulate myself well enough, or if I have left anything unclear, and I will try to explain that further.
I use GNU Guix a functional package manager. It can sit on top of any other distro. And, I recently ran into an issue where a program that was packaged using guix didn't produce sound on my machine. I looked at it, and it turned out that it was looking looking for libasound_module_conf_pulse.so
in the directory that you said, <libasound.so.dir>/alsa-lib/<plugin.so>
. Now, for guix, baked packages are the result of a function, the input of which are all the inputs necessary to prepare the package. Each package ends up in it's own 'store' in /gnu/store
. So, the package alsa-lib
happens to end up one directory in /gnu/store
whereas alsa-plugins
ends up in another. No problem there. Because guix has a way to mix two packages into one. The union-build
. And I wrote a union build of these two packages: alsa-lib
and alsa-plugins
, today. The pkg-config
.pm
files were also edited to account for the new path. Everything worked. I present a tree listing of the build tree here:
.
├── bin
│ └── aserver
├── include
│ ├── alsa
│ │ ├── asoundef.h
│ │ ├── asoundlib.h
│ │ ├── conf.h
│ │ ├── control_external.h
│ │ ├── control.h
│ │ ├── error.h
│ │ ├── global.h
│ │ ├── hwdep.h
│ │ ├── input.h
│ │ ├── mixer_abst.h
│ │ ├── mixer.h
│ │ ├── output.h
│ │ ├── pcm_external.h
│ │ ├── pcm_extplug.h
│ │ ├── pcm.h
│ │ ├── pcm_ioplug.h
│ │ ├── pcm_old.h
│ │ ├── pcm_plugin.h
│ │ ├── pcm_rate.h
│ │ ├── rawmidi.h
│ │ ├── seq_event.h
│ │ ├── seq.h
│ │ ├── seqmid.h
│ │ ├── seq_midi_event.h
│ │ ├── sound
│ │ │ ├── asoc.h
│ │ │ ├── asound_fm.h
│ │ │ ├── emu10k1.h
│ │ │ ├── hdsp.h
│ │ │ ├── hdspm.h
│ │ │ ├── sb16_csp.h
│ │ │ ├── sscape_ioctl.h
│ │ │ ├── tlv.h
│ │ │ ├── type_compat.h
│ │ │ └── uapi
│ │ │ ├── asoc.h
│ │ │ ├── asound_fm.h
│ │ │ ├── emu10k1.h
│ │ │ ├── hdsp.h
│ │ │ ├── hdspm.h
│ │ │ ├── sb16_csp.h
│ │ │ ├── sscape_ioctl.h
│ │ │ └── tlv.h
│ │ ├── timer.h
│ │ ├── topology.h
│ │ ├── use-case.h
│ │ └── version.h
│ ├── asoundlib.h
│ └── sys
│ └── asoundlib.h
├── lib
│ ├── alsa-lib
│ │ ├── libasound_module_conf_pulse.la
│ │ ├── libasound_module_conf_pulse.so
│ │ ├── libasound_module_ctl_pulse.la
│ │ ├── libasound_module_ctl_pulse.so
│ │ ├── libasound_module_pcm_pulse.la
│ │ └── libasound_module_pcm_pulse.so
│ ├── libasound.la
│ ├── libasound.so
│ ├── libasound.so.2
│ ├── libasound.so.2.0.0
│ ├── libatopology.la
│ ├── libatopology.so
│ ├── libatopology.so.2
│ ├── libatopology.so.2.0.0
│ └── pkgconfig
│ ├── alsa.pc
│ └── alsa-topology.pc
└── share
├── aclocal
│ └── alsa.m4
├── alsa
│ ├── alsa.conf
│ ├── cards
│ │ ├── AACI.conf
│ │ ├── aliases.conf
│ │ ├── ATIIXP.conf
│ │ ├── ATIIXP-MODEM.conf
│ │ ├── ATIIXP-SPDMA.conf
│ │ ├── AU8810.conf
│ │ ├── AU8820.conf
│ │ ├── AU8830.conf
│ │ ├── Audigy2.conf
│ │ ├── Audigy.conf
│ │ ├── Aureon51.conf
│ │ ├── Aureon71.conf
│ │ ├── CA0106.conf
│ │ ├── CMI8338.conf
│ │ ├── CMI8338-SWIEC.conf
│ │ ├── CMI8738-MC6.conf
│ │ ├── CMI8738-MC8.conf
│ │ ├── CMI8788.conf
│ │ ├── CS46xx.conf
│ │ ├── Echo_Echo3G.conf
│ │ ├── EMU10K1.conf
│ │ ├── EMU10K1X.conf
│ │ ├── ENS1370.conf
│ │ ├── ENS1371.conf
│ │ ├── ES1968.conf
│ │ ├── FireWave.conf
│ │ ├── FM801.conf
│ │ ├── FWSpeakers.conf
│ │ ├── GUS.conf
│ │ ├── HDA-Intel.conf
│ │ ├── HdmiLpeAudio.conf
│ │ ├── ICE1712.conf
│ │ ├── ICE1724.conf
│ │ ├── ICH4.conf
│ │ ├── ICH.conf
│ │ ├── ICH-MODEM.conf
│ │ ├── Loopback.conf
│ │ ├── Maestro3.conf
│ │ ├── NFORCE.conf
│ │ ├── PC-Speaker.conf
│ │ ├── pistachio-card.conf
│ │ ├── PMac.conf
│ │ ├── PMacToonie.conf
│ │ ├── PS3.conf
│ │ ├── RME9636.conf
│ │ ├── RME9652.conf
│ │ ├── SB-XFi.conf
│ │ ├── SI7018.conf
│ │ ├── TRID4DWAVENX.conf
│ │ ├── USB-Audio.conf
│ │ ├── vc4-hdmi.conf
│ │ ├── VIA686A.conf
│ │ ├── VIA8233A.conf
│ │ ├── VIA8233.conf
│ │ ├── VIA8237.conf
│ │ ├── VX222.conf
│ │ ├── VXPocket440.conf
│ │ ├── VXPocket.conf
│ │ └── YMF744.conf
│ └── pcm
│ ├── center_lfe.conf
│ ├── default.conf
│ ├── dmix.conf
│ ├── dpl.conf
│ ├── dsnoop.conf
│ ├── front.conf
│ ├── hdmi.conf
│ ├── iec958.conf
│ ├── modem.conf
│ ├── rear.conf
│ ├── side.conf
│ ├── surround21.conf
│ ├── surround40.conf
│ ├── surround41.conf
│ ├── surround50.conf
│ ├── surround51.conf
│ └── surround71.conf
└── doc
├── alsa-lib-1.2.2
│ └── COPYING
└── alsa-plugins-1.2.2
├── COPYING
└── COPYING.GPL
17 directories, 145 files
As you can see in the listing above, this is a proper union of the two packages.
Now, before I go further, perhaps a summary is in order:
.so
files in /usr/lib
, execuatables in /usr/bin
, etc -- in it's own separate store
in /gnu/store
as /gnu/store/unique_build_hash-package-name
.alsa-lib
is one package with it's own store
in /gnu/store/build-hash-alsa-lib
alsa-plugins:pulseaudio
is another one with it's own store
in /gnu/store/build-hash-alsa-plugins-pulseaudio
.aegisub
requires alsa-plugins:pulseaudio
to be available to it during runtime.alsa-lib
and alsa-plugins:pulseaudio
. And the union (hereafter known as alsa-union
) works. There's no problem there.However, when I built the package aegisub
with alsa-union
as an input instead of mere alsa-lib
, during run time, the program was looking for the plugins in the the store
of alsa-lib
, and not the store
of alsa-union
. I was wondering why this might be the case, and it seems that it is because alsa-lib
sets it's plugin-dir during build time to be the directory relative directory to where libasound.so
is located. And this propagates over to alsa-union
(as the packages alsa-lib
and alsa-plugins:pulseaudio
are the inputs to the function that creates the union package).
Now, if alsa-lib
, along with the plugin-dir that it has set during build, also honoured a few environment variables (for instance ALSA_PLUGIN_PATH
, etc.) during runtime, I could export the proper variables and it would work. But as things stand right now, the package aegisub
is still looking for libasound_module_conf_pulse.so
in the original location of alsa-lib
(which was burned into it during build-time).
I did try writing a package definition that would set the --plugiin-dir of alsa-lib
during build-time to point to the path to the union's store at /gnu/store/hash-alsa-union
. But since the union is only built after the actual libs, that task seems impossible.
Now that I've went ahead and written all of that, I am having second thoughts. I just realized that I haven't quite noticed any libraries respecting environment variables during run-time. Perhaps there might be good reasons not to do so. So, perhaps this entire request is an ill-informed one.
However, I'm still going to post this. Perhaps you could have some useful insight that you could give me regarding the matter. Or some advice. Anything.
Sorry about the long convoluted post. I would appreciate any advice/suggestions that you might have.
Hey there,
For the moment, I have resolved this by choosing a different route, entirely.
Instead of creating a union build, I ended up redefining alsa-lib
to build with --with-plugindir
set to the /gnu/store/...-alsa-plugins-pulseaudio/lib/alsa-plugins
. And that seems to have resolved the issue just as well, and in quite a bit of fewer lines of package declaration.
I think this issue can now be closed. But I will wait on you to see if you have any suggestions.
Thank you for your time!
I was wondering why this might be the case, and it seems that it is because alsa-lib sets it's plugin-dir during build time to be the directory relative directory to where libasound.so is located.
The current alsa-lib code uses the RTLD_DI_ORIGIN glibc extension to determine the libasound.so path at runtime. The hardcoded path is used only if this mechanism does not work:
It seems that runtime linker (ld-linux.so) does not use libasound from the directory you expect or the alsa-lib is not compiled with the RTLD_DI_ORIGIN code.
@perexg - This does sound like a better path. Please excuse my lack of knowledge, but what other inputs should I add to the alsa-lib
package? glibc
?
The following is the build log of alsa-lib
in guix as it stands currently:
alsa-lib-1.2.2.drv.build.log
The problem is probably this rpath: -Wl,-rpath=/gnu/store/zcjdb23gbhl0pcnvvm8rnlprkfl43cv5-alsa-lib-1.2.2/lib . It should point to the union tree.
I have asked another guix contributor, who is far more qualified than I am, to look into the matter. If need be, I will ask some further questions. You have been quite helpful. Thank you very much for your help.
Hi! I am said contributor :)
So, in Guix, since libraries are in different directories that are not guessable, we set the rpath at build time, so the dynamic loader can actually find them. One issue is that, at build time, we only know the path of inputs (dependencies) of the package, but we can't guess the path of any other package. So we can build alsa-lib with an rpath that includes its output and dependencies, but since alsa-plugins depends on alsa-lib, at that point, we do not know which directory alsa-plugins will be installed to.
The union is simply built after having built alsa-lib and alsa-plugins, by copying (or symlinking) all their files into a single directory under /gnu/store
. Doing so, we preserve the rpath of the libraries and binaries. IIUC, alsa-lib looks for the pulseaudio plugin in its rpath, fails to do so, and falls back to its hard-coded directory.
We can wrap binaries to set LD_LIBRARY_PATH or similar and fix that for binaries, but that wouldn't work for a library. Similarly, we could patchelf it, but that's less than satisfying :).
Other libraries, like qtbase (see https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/qt.scm#n579) actually have a similar mechanism to what @peanutbutterandcrackers asked for here, where they can read the value of, for instance, QT_PLUGIN_DIR, to find libraries in other packages that depend on it. Guix has the ability to set these variables for the user, if they need them.
Currently, alsa-lib and alsa-plugins work well on the Guix System, because of configuration. Since we control the whole system configuration, we have a simple mechanism to set an /etc/asound.conf
file that references the pulseaudio plugin. This works for the Guix System itself, but not for guix on a foreign distro, since we don't control the configuration of foreign distros.
Hello,
If I understand correctly, this issue as it pertains to Guix has also been discussed previously on our bug tracker a few months ago:
It includes a patch that makes alsa-lib respect the environment variable GUIX_ALSA_PLUGIN_DIRS. It does work but I haven't deployed it for Guix users yet:
I implemented the ALSA_PLUGIN_DIR support in commit 8580c081c25678d11278efcb61bd15cf44d0a225 . Note that only one directory lookup is supported for the moment which is the difference from GUIX_ALSA_PLUGIN_DIRS .
Hello there,
I would like to request a feature to set things like
ALSA_PLUGIN_DIR
etc during runtime using environment variables. Currently, these seem to be set-able only at build-time, or by using a.asoundrc
file.Or, if something like that is already possible, please do point me to the relevant documentation. Thank you very much.