GNU triplet via SNAP_ARCH_TRIPLET

Summary

In bug LP: #1742565 a way for the snap to get the gnu arch triplet (like x86_64-linux-gnu) in addition to the SNAP_ARCH (amd64) is requested.

Many snaps use paths internally that use the triplet to find plugins or libraries which means that currently there are a lot of wrapper scripts that contain code like:

case $SNAP_ARCH in
  amd64) export TRIPLET=x86_64-linux-gnu
...

by providing this as an environment via snap run we are one step close to the goal of getting rid of wrapper scripts.

Common case

The common case is that snaps are build using snapcraft with an ubuntu toolchain. In this case we know the triplet and PR#4477 implements a new SNAP_ARCH_TRIPLET environment.

General case

The triplet is dependent on the toolchain used to build the snap. So in the general case someone may build a snap using a toolchain configured for x86_64-linux-musl. So providing this env for the general case requires help from the snap. The snap would have to provide a mapping table like:

amd64 x86_64-linux-musl
i386 i386-linux-musl
...

for all arches it ships/cares about. Ideally auto-generated from snapcraft.

Use cases

The use cases for this environment is mostly to find setup LD_LIBRARY_PATH to something like $SNAP/usr/lib/$SNAP_ARCH_TRIPLET/ and to configure plugin paths. One suggestion by @niemeyer was that we could write a ld.so.conf file inside the snap run environment that would setup the common paths automatically (like $SNAP/usr/lib/$SNAP_ARCH_TRIPLET/) so that there is no need to setup LD_LIBRARY_PATH at all anymore. This would not solve the export for plugins though but we may provide both.

Next steps

So given the above, I would suggest we provide:

  1. SNAP_ARCH_TRIPLET for the common case
  2. a way for snaps to define their own triplet mapping (we need to discuss how this is defined, maybe simply via a yaml map in snap.yaml?)
  3. consider providing ld.so.conf pre-configured with the triplet
1 Like

Most distributions don’t do Debian-style multilib directory paths, and instead follow FHS-style multilib paths. In this case, $SNAP_ARCH_TRIPLET is pointless for ld.so lookup path setup.

So this should probably not be an automatic thing…

Could we somehow augment snapd and the base snap(s) to define on a per-base-snap basis how each base snap’s OS usually does library paths? That way, for the 64bit userland, a solus base snap could define /lib and /lib32 while the ubuntu core snap defines /lib/x86_64-linux-gnu and /lib/i386-linux-gnu.

Just throwing that out there… I don’t know how easy or difficult it would be to implement or even if it makes sense. It’s some random musing :slight_smile:

You should not need to do this, since the base snap should already contain the ldso configuration for doing this.

If you think about it, it’s silly that such a property would be necessary, because within the environment of the snap, these are already configured through the construction of the base snap.

The better question to ask is where is the deficiency that leads to this being something that might be considered necessary to make it function.

That was exactly my point in the conversation we had as well. It feels like a solution to a problem we shouldn’t have. Having a default environment variable that we know won’t make sense in many cases because it’s built with a single base feels awkward.

This should probably be dynamic and with clear expectable logic, or come as part of the base as Neil suggests.

I’ve seen requirements in the desktop-* parts which need to build variables pointing to subdirectories of /usr/lib/x86_64-linux-gnu for things like pulseaudio. I’ve also used similar mechanisms in my own launcher scripts for libraries which include part of their functionality in non-standard directories (as pulseaudio does).

Right, those are the problems we shouldn’t have. Asking people to know about a magic environment variable which can be used in a particular way for the problem to not exist, and by the way it only works in some cases, doesn’t feel like the right answer.

yeah, there are plenty of subdirs that wont be managed by the linker config … like pulse or mesa … for these you will still need the direct path

You can’t magic away the problem without it though, because in the majority of cases where this becomes a problem we’re installing things that are built on the assumption that they’ll not be relocated from their intended paths. Consider icons as a simile where an application would hard-code the path to /usr/share at build time based on the fact that you requested to install to /usr anticipating the final snap to contain a usr directory which maps analogously to /usr on a non-snap installation. The problem here is that libraries sometimes also hard code their own installation paths for parts of their runtime. A friendly library/application provides for an environment variable to override these paths, but sometimes they don’t.

The real crux of this issue is that we’re relocating applications after they’re built and expecting them to still run as-is.

We cannot both know exactly how the variable should be set for the snap+base at hand, but not know whether it’s necessary. Either we know how the base+snap at hand were relocated and then we should solve the real issue, or we shouldn’t pretend we know.