Unable to load shared library ".so" in Application using snap

Hello , I am trying to load shared library “.so” which is available in “/usr/lib/” directory on my application using dlopen() but it always fails in snap.
Using snap , i am only providing binary “DPR_service:”
It actually works using other format like “.deb” format and hence , it looks like i missing something in snap or doing wrong .

Any comments regarding this will be helpful .
Below is my snapcraft.yamls file :


name: dpr-test
version: “1.0-test”
summary: DPR App
description: |
DPR App

confinement: strict
base: core18

grade: stable

parts:
dpr-test:
plugin: dump
source: .
stage-packages:
- pciutils

apps:
dpr-test:
command: bin/DPR_service
environment:
LD_LIBRARY_PATH: $LD_LIBRARY_PATH:$SNAP/usr/lib/

layout:
/usr/lib/libDPR.so:
bind: $SNAP_DATA/usr/lib/libDPR.so


I am running it using below commands -
snap install --devmode --dangerous *.snap
dpr-test -h

Thanks

$SNAP_DATA is /var/snap/<snapname>/current, how does your lib get there ? try using $SNAP instead …

Thanks for reply .

Actually , library libDPR.so is already placed in “/usr/lib/libDPR.so” directory for me .
I have created an application which loads this library using dlopen("/usr/lib/libDPR.so",) and do some functionality related to network.

Now , this loading always get failed in Application, when i create “snap”. So , i have added " layout" .
I am a beginner in “snap”, please let me know , do i need to use “layout” in this or i have missed something?

Thanks

Your snap runs in its own “mount namespace”, so sees a different view of the file system compared to other processes on the system. In particular, the libraries you see in /usr/lib are the ones from the base snap you’ve chosen. This helps ensure that your application behaves the same no matter what distro release people install it on.

As your snap is using core18 as its base, you’ll only see the libraries available in /snap/core18/current/usr/lib. If you need additional libraries, you should ship them as part of your snap. If your application needs the library to appear under /usr/lib, you can use layouts to have them mounted in the appropriate location as you’ve done for libDPR.so.

Thanks for your reply.

I understand now that , i need to ship it and then needs to mount it in snap and then use the path of snap in dlopen() for loading shared library.

is there any example which i can refer ? i have stored lib in local path lib/libDPR.so but not sure what to do after that .
Thanks

just use a layout pointing to the location in your snap … i.e. if it lives in lib/ you can:

layout:
   /lib/libDPR.so:
     bind: $SNAP/lib/libDPR.so

that would make the lib apper as /lib/libDPR.so to your snpped applications

or:

layout:
   /usr/lib/libDPR.so:
     bind: $SNAP/usr/lib/libDPR.so

to make it appear in /usr/lib …

(the issue above was that you used $SNAP_DATA instead of $SNAP, the SNAP_DATA dir is an empty writable dir your snap package can use. you would have to use an install hook to copy the lib there first if you wanted such a layout entry to work)

Thanks for reply .

This works for me but in 2 steps .
It will be helpful , if you can check below steps :

Step 1 -
File exists in usr/lib/libDPR.so (“usr” directory in same path as “snapcraft.yaml file”)
Change layout like below :

layout:
  /usr/lib/libDPR.so:
     bind: $SNAP/usr/lib/libDPR.so

Execute commands for installing and running
a) snapcraft clean
b) snapcraft && sudo snap install --devmode --dangerous *.snap && dpr-test

Output -
cannot update snap namespace: cannot use “/snap/dpr-test/x1/usr/lib/libDPR.so” as bind-mount source: not a directory
snap-update-ns failed with code 1: File exists

Step 2 - Create “lib” directory and copy file “libDPR.so” file in “lib” directory
Change layout like below :

layout:
  /usr/lib/libDPR.so:
     bind: $SNAP/usr/lib/libDPR.so
  • Remove /usr/lib/libDPR.so (If we dont remove it , we will get below error as output after runing commands as mentioned below :
    cannot update snap namespace: cannot use “/snap/dpr-test/x1/usr/lib/libDPR.so” as bind-mount source: not a directory
    snap-update-ns failed with code 1: File exists)

Execute commands for installing and running
a) snapcraft clean
b) snapcraft && sudo snap install --devmode --dangerous *.snap && dpr-test -h

Output -
It works fine - dlopen("/snap/dpr-test/x1/lib/libDPR.so")
i.e shared libraray gets loaded and everything works OK

But this works in 2 steps for me . I have tried it several times but same result.

Any comment regarding this will be helpful.
Thanks

oops, soory, my mistake, bind: should instead be bind-file: (symlink: might work as well, indeed bind: expects directories)

1 Like

Thank you @ogra
It looks working fine for me now

1 Like