That seems reasonable, thanks for patchelf btw, Almost a year ago @zyga-snapd’s and my google foo only found chrpath which had an important notice under BUGS in the manpage.
We already have logic to crawl the snap and find ELF binaries, so this should be rather trivial work indeed (again, thanks for patchelf, I wasn’t looking forward to writing logic to modify those headers).
With regards to myld, it might be best if each new base snap is required to provide a fixed entry point so we can patchelf with interp of something like /snap/<base>/current/lib/snap-ld-linux.
Let me expand on that last part as the original idea in your proposal was to have snapcraft create this little shim. So here’s why I would like it to be part of the base snap:
the entry point is clearly defined.
the base snap knows exactly what ld-linux to call.
if --library-path is the reason to keep it in snapcraft, can I suggest that LD_LIBRARY_PATH poped from the environment and used as the --library-path argument.
the base snap could leverage this snap-ld-linux to patchelf things from the base snap itself such as /usr/bin/python3
There’s no reason to mix this logic across snapd and snapcraft tying their exact implementation together and forcing every single base to ship with these custom loaders, and making classic work or not depending on whether the base author was aware of such edge cases. Snapcraft will need to patch the interpreters, and it knows exactly which interpreter to call because it has the old one at hand.
We must not touch LD_LIBRARY_PATH, or it will break the user’s environment in unrelated ways. We can build the default path dynamically very easily based on which libraries each ELF file is linked with. Make a set of all of them, search inside the snap for these names, build a path that resolves all of them, and inject that into the custom ld.
We can name the custom ld as $SNAP/lib/snap-<original name>, so we can make sense of it, and define the real ld as a constant inside the code.
Indeed we may need to do something on our bases as well to fix their binaries. But note that the issue in this topic was raised precisely because the snap was calling out to binaries in the system instead of inside the base snap. My guess is that this is typical (/usr/bin/python3 is not inside the base for a classic snap).
@sergiusens Can we move this forward and put it in the agenda? Every classic snap today is sort of broken because of this, and changes in the upcoming glibc will make this issues a deal breaker. The sooner we fix that in snapcraft, the less broken snaps we’ll have.
To make sure I understand, I think the plan here is to change the process
of building a classic snap so that instead of having LDFLAGS set during the
build step, something in some later step will patch any ELF binaries in the
snap to have a custom interpreter. This interpreter will call the
interpreter from the core^Wbase snap with a --list so that any dynamic
libraries are resolved from the either the snap being built or the base
snap.
This sounds like a good change to me and will let me simplify the go snap’s
build plugin a whole bunch. When can I get it?
Is there any update on this? I am running Ubuntu 17.10 and would like to install Android Studio, to do this I need to install the latest version of Ubuntu Make which can be installed through snap, however I am getting stuck here:
You can try it by installing snapcraft --edge --classic or, if you’ve already installed it switch to the edge channel with snap refresh snapcraft --edge --classic.
Be sure you’re using the snap if you also have the apt package installed.
Hey folks, quick update here on the progress we’ve made.
A couple of short-term fixes have landed that make progress on this issue, but don’t completely fix it:
LP: #1723208 has been fixed in master, but that did not end up being due to this issue, but rather a leaking LD_LIBRARY_PATH in the snapcraft snap itself.
One of the issues here is that Snapcraft doesn’t exclude libraries from the snap unless the build host is a release that corresponds to a core snap, i.e. currently only Xenial. On releases where this isn’t the case, snapcraft took the step of at least ensuring libc.so.6 didn’t make it into the snap, but that of course ignores everything else in libc, so that measure never worked. PR: #1632 landed in master fixing this issue by making sure every lib in the libc package was excluded.
Another fix in the pipline is PR: #1636 where we get a little smarter about determining the host OS. As soon as that fix lands, combined with the other two, once Snapcraft (a classic snap that we’re using to prove this out) is rebuilt with them we have a snap that runs on Trusty.
That, of course, goes the wrong direction for some of you (older releases rather than newer ones). We’re making progress on that as well, but the problems there take longer to solve (see earlier in this thread). It is a top priority, but the poor soul doing this work just had two sprints and presented at a conference, heh. Expect to hear more soon.
Getting there. We want to release 2.34 first as it has become huge and the changes for this require some code changes for which we want to have a solid baseline to come back to. So my estimate is, if adt starts working on our release branch for 2.34 for it to happen 1 week from now.
Using snapcraft on edge and building from 16.04 today has the working bits to produce sound snaps as long as you do not blindly use the desktop-helper as that sets up all the library paths for “called out” runnables to break LD_LIBRARY_PATH for custom libraries in snap
@sergiusens Can you elaborate what you mean by “do not blindly use the desktop-helper” please? Does this mean we should not use desktop-helpers at all in classic snaps?
It is explained in the linked topic pretty well by @jamesh
But in summary, you can use the part to get the bits, just not the script to launch and that would need crafting on a case by case basis to avoid squatting and breakage (depending if the app launches processes on the host or not).