2

I'm trying to create a shared library object (which will be loaded into R using dlopen) which links to the static rather than the dynamic version of a third-party library. (The goal is to have one rather than two shared libraries that the user needs to move in place.)

Here is the call used to link the final executable:

gcc -std=gnu99 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -flto=auto -Wl,-z,relro -o RNetica.so Cases.o Continuous.o Edges.o Experience.o Inference.o Networks.o Node.o Random.o Registration.o Session.o -dn -L/home1/ralmond/Projects/RNetica/src/Netica/Netica_API_607/lib -lnetica -dy -lstdc++ -L/usr/lib/R/lib -lR

This produces libRNetica.so which is designed to be loaded into R using dlopen.

Inside the Netica_API_607/lib directory, I have both libnetica.a and libnetica.so. I thought that the -dn and -dy switches would hint to the linker to use libnetica.a instead of libnetica.so. However, when I try to load libRNetica.so using dlopen I get the following error message:

 unable to load shared object '/home/ralmond/R/x86_64-pc-linux-gnu-library/4.1/00LOCK-RNetica/00new/RNetica/libs/RNetica.so':
  libnetica.so: cannot open shared object file: No such file or directory

The problem is that there are a limited number of places (e.g., /usr/local/lib) that R will look for the shared library. I can move libnetica.so one of these places, but that requires root access so people without admin privileges can't install the program. (I've read how using the shared library is better, but in this case, the lack of admin access is a problem. Also, the Netica library is fairly specialized, so the performance hit will be small.)

Is there some flag I can pass to the linker to link statically instead of dynamically?

ralmond
  • 116
  • 5

1 Answers1

2

Inside the Netica_API_607/lib directory, I have both libnetica.a and libnetica.so

This should work:

gcc -shared ... -L/home1/.../Netica_API_607/lib -Wl,-Bstatic -lnetica -Wl,-Bdynamic ...

Alternatively, you should be able to do this:

gcc -shared ... /home1/.../Netica_API_607/lib/libnetica.a ...

I thought that the -dn and -dy switches would

These switches are "global"; that is: -dn sets a boolean inside the linker to "never use shared libraries", and the -dy flips that boolean back to default, regardless of where on the command line these switches occur.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Thanks, this did indeed cause the linker to link against the `.a` rather than the `.so` file. So this answered my question. Unfortunately, the `.a` file was built with an old version of GCC, so I still have more work to do. – ralmond Jul 27 '21 at 19:19