I am missing several libraries in my snap. It builds just fine, but when I run it, it outputs the following:
error while loading shared libraries: liblapack.so.3: cannot open shared object file: No such file or directory
I have both liblapack-dev and liblapack3 in my stage-packages. I checked the folder /usr/lib/x86_64-linux-gnu/ in my VM, which includes liblapack.a, liblapack.so as well as liblapack.so.3. I assume that $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET` is added automatically to the LD_LIBRARY_PATH, right? Therefore, I’m wondering why these can’t be found. The error message unfortunately doesn’t tell me where it is looking for this library. I’m using the catkin-tools plugin and ROS, if this is relevant.
The second suspicious warnings arise after the build:
This part is missing libraries that cannot be satisfied with any available stage-packages known to snapcraft:
- usr/lib/x86_64-linux-gnu/libpsm_infinipath.so.1
These dependencies can be satisfied via additional parts or content sharing. Consider validating configured filesets if this dependency was built.
I checked the folder /usr/lib/x86_64-linux-gnu/ as well and it contains libpsm_infinipath.so.1. It obviously works for all other stage-packages except these 2.
Not sure anymore, if I use them correctly. But this worked so far. I defined different parts with all the build-packages and stage-packages and then added them with after: [part1, part2] in my workspace part.
I’m mostly concerned about liblapack, since I can’t even run my application without this library.
My snapcraft.yaml looks like this (relevant parts relatively at the end):
It appears that it relies on a postinst action to link (using update-alternatives) /usr/lib/x86_64-linux-gnu/libpsm_infinipath.so.1 to /usr/lib/libpsm1/libpsm_infinipath.so.1.16
Snapcraft does not run postinst actions for staged packages unfortunately, so this may require some manual fixups.
You have a couple options, but I can’t really test it without a good example:
add libpsm1 to the library path, but you may still need that .so.1 link
From what I’m told, liblapack also needs to be added to the library path to function as well.
So this may work for you for the runtime issue: LIBRARY_PATH: $LD_LIBRARY_PATH:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/lapack:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/blas:$SNAP/usr/lib/libpsm1
The symlink for the major api versions may be required as well (libpsm_infinipath.so.1 -> libpsm_infinipath.so.1.16 and liblapack.so.3 -> liblapack.so.3.7.1).
You could do that with an override-prime, override-build, or override-stage.
to the apps. I didn’t realize that there’s also a lapack folder. The runtime error with the missing library is gone. But I still don’t understand why I need to add these folders although the same libraries/ symlinks are already in the ARCH_TRIPLET folder.
I assume I need to add the library path for every app now, right?
When I check the symlink of /usr/lib/x86_64-linux-gnu/libpsm_infinipath.so.1 in the VM, it points to /usr/lib/libpsm1/libpsm_infinipath.so.1.16, which is obviously where the file is. I don’t even understand the error message, since the libpsm_infinipath.so.1 clearly exists.
I’m reading and reading, but the information is very sparse. I’m trying to make some assumptions to find out how this really works and finally solve this:
The stage-packages for my particular snap are put in the folder stage in my VM and the build-packages are just in their normal places in the VM (?).
How does snapcraft know missing stage-packages if they are only used during runtime (otherwise the snap would probably not succeed). I got an error before from a missing library without snapcraft giving me that hint during the build. Why is this different with libpsm?
Where are these stage-packages missing? In $SNAPCRAFT_STAGE or $SNAPCRAFT_PRIME? And how is $SNAP related to these?
What do I need to symlink? Files inside $SNAPCRAFT_STAGE, $SNAPCRAFT_PRIME or $SNAP (which I don’t know where to find)?
Why is the LD_LIBRARY_PATH necessary when I need to symlink anyway? The LD_LIBRARY_PATH obviously doesn’t save me from the error message during the build.
In my snapcraft.yaml above, I had both libpsm_infinipath1 and libpsm_infinipath1-dev also in the build packages. I removed them from the build-packages and have it only in the stage-packages now. The error I get now changed from usr/lib/x86_64-linux-gnu/libpsm_infinipath.so.1 to just libpsm_infinipath.so.1.
And I found this hint at the very bottom of this page:
Layouts cannot replace an existing but incompatible filesystem object. This means, for example, that files cannot replace directories or symbolic links, files cannot replace a directory, and existing symbolic links cannot be redirected to a new target.
Snapcraft will do its own dependency resolution. It’s not perfect, but that’s why they are only presented as warnings. The difference in behavior you are seeing is because snapcraft will resort to scanning the entire snap for libraries, assuming the snap author setup the correct LD_LIBRARY_PATH for runtime.
$SNAP is a runtime variable set in the process of the running snap. $SNAPCRAFT_STAGE,PRIME are build-time variables.
Maybe try something like this, using a relative symlink at build-time:
If the source symlink is correct, and it resides in your library path, you won’t need to modify LD_LIBRARY_PATH.
For example, if you added $SNAP/usr/lib/libpsm1 to your LD_LIBRARY_PATH, the symlink example above would be:
ln -sf libpsm_infinipath.so.1.16 $SNAPCRAFT_PART_INSTALL/usr/lib/libpsm1/libpsm_infinipath.so.1
It’s already pretty clear now. Still some questions for the learning effect:
Snapcraft will search for the libraries given in the snapcraft.yaml or the libraries used in my code? So why couldn’t it find the libpsm then, but it could find lapack. Both of them are not at the “default” location.
So this means the warning is not even so important if I know that I have set the correct LD_LIBRARY_PATH for runtime?
I don’t have the feeling for this structure yet. Are the directories just copied from one to another and they keep the paths? How can you otherwise know where to link to in $SNAP if you can’t look it up in the VM?
Makes me wonder why the layout-approach didn’t work. Is it only for runtime?
Because it is looking for libpsm_infinipath.so.1, not libpsm_infinipath.so.1.16. Once that symlink is there, I imagine the warning should be going away?
For symlinking purposes at build time, you cannot rely on $SNAP, and must use a relative links, which should work wherever they end up (assuming it’s correct).