Is -rpath working?

1,744 views
Skip to first unread message

appforce.org

unread,
May 2, 2010, 5:52:11 AM5/2/10
to android-ndk
I've several shared libs bundled in my application, and I use -rpath /
data/data/my-package/lib when linking the lib that depends on the
others. That doesn't seem to work and linker is only looking into /
system/lib and /lib, doesn't find my libs and crashes. On 1.6 ADP I
can load the libs from Java by supplying absolute path, but on
emulators and 2.1 Milestone it is not working and still fails to load
the libs. Is there any way to make -rpath work?

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.

David Turner

unread,
May 2, 2010, 12:26:24 PM5/2/10
to andro...@googlegroups.com
I don't think it is supported. But System.loadLibrary("foo") should look for /data/data/<package-name>/lib/libfoo.so automatically anyway,
and the dynamic linker should look in the same directory for dependent libraries too.

Have you tried to manually load the libraries in sequence from Java. I.e. if libfoo depends on libbar which depends on libzoo, something like

System.loadLibrary("zoo");
System.loadLibrary("bar");
System.loadLibrary("foo");

should work.

Also, generally speaking, you should not rely on hard-coded paths like /data/data/<package-name>/ since it is likely that these are going to
change in a future release of the platform.

appforce.org

unread,
May 2, 2010, 12:53:14 PM5/2/10
to android-ndk
That's exactly what I'm doing - loading the shared libs in the proper
sequence from Java. I've tried both System.load with full path and
System.loadLibrary and none works on emulator or Milestone (2.1). It
does work on ADP with 1.6 though. When I strace (on 2.1 emulator) the
loading process it clearly shows that linker looks in /system/lib, but
reports "not found" in my apps' dir. libfreetype.so loads properly
from Java, but when it tries to load the lib that depends on
libfreetype, it doesn't seem to know it's already loaded and looks in /
system/lib.

[pid 486] stat64("/system/lib/libfreetype.so", 0x451bf7c0) = -1
ENOENT (No such file or directory)
[pid 486] stat64("/system/lib/libfreetype.so", 0x451bf7c0) = -1
ENOENT (No such file or directory)
[pid 486] stat64("/lib/libfreetype.so", 0x451bf7c0) = -1 ENOENT (No
such file or directory)
[pid 486] munmap(0x80c00000, 475136) = 0
[pid 486] writev(3, [{"\4", 1}, {"dalvikvm\0", 9}, {"Unable to
dlopen(/data/data/org.appforce.bgar/lib/libbgar.so): Cannot load
library: link_image[1721]: 30 could not load needed library
\'libfreetype.so\' for \'libbgar.so\' (load_library[1051]:
Library"..., 230}], 3) = 240

C++ RTMP Server

unread,
May 2, 2010, 1:14:05 PM5/2/10
to andro...@googlegroups.com
Hi David,

I'm trying to compile a native executable who is making use of a shared library. Normally, if I try to run my app I get this:

link_image[1721]: 237 could not load needed library 'libshared-library.so' for '/data/executable' (load_library[1051]: Library 'libshared-library.so' not found)CANNOT LINK EXECUTABLE

Which is somehow understandable giving the fact that the linker only searches /system/lib and /lib. The problem is that we don't have easy access to those directories. However, I found a workaround for this:

LOCAL_LDFLAGS := -Wl,-soname,/data/libshared-library.so

Basically, I just trick the runtime linker.

Which works as expected. But I'm afraid that this is not the correct way of doing it. Can you recommend something more standard for loading shared libraries from native applications (besides creating wrapper app who dlopens all required libs and calls the surrogate "main" function from one of it)?

Cheers,
Andrei

------
Eugen-Andrei Gavriloaie
Web: http://www.rtmpd.com

Angus Lees

unread,
May 2, 2010, 8:56:13 PM5/2/10
to andro...@googlegroups.com
On Mon, May 3, 2010 at 02:26, David Turner <di...@android.com> wrote:
I don't think it is supported. But System.loadLibrary("foo") should look for /data/data/<package-name>/lib/libfoo.so automatically anyway,
and the dynamic linker should look in the same directory for dependent libraries too.

Are you sure about that last bit?

I've noticed that dlopen() from a native library with an unqualified filename does *not* look in your /data/data/<app>/lib/ directory.  I had to fully-qualify my pathnames before passing them to dlopen() in my simple testing.  (I haven't tried this across other Android versions so the behaviour may have changed over time).  System.loadLibrary() from Java finds local app libraries just fine.

(Speculating without having read the relevant source code)  Perhaps the runtime linker uses the same search path and is also not searching the app-specific lib dir for DT_NEEDED libraries.


I have had much greater success just linking dependent libraries statically.  Assuming you don't need to choose which library to load at runtime, I also found that static linking produced smaller total size on disk (we can't really reuse shared libraries between apps anyway), and let me strip unused code (ie: ld --gc-sections) more easily.  I recommend building a libfreetype.a and linking against that instead.

 - Gus
Reply all
Reply to author
Forward
0 new messages