At runtime when the app is launched on emulator, it predictably fails,
citing that it cannot find libshared.so.
As is known, the runtime will only look for shared libraries in
"system/lib" (and I cannot put my libshared.so in there).
Is there a "best-practice" way to get the runtime to be able to find
my shared library (libshared.so)?
e.g. I have deployed it to my /data/data/com.example.test/app/lib
directory (which is where the JNI libapp.so goes), so I just want the
runtime to also search this path when searching for shared libraries.
In the source code for Android 2.1, I can see that the runtime
linker.c is now using the LD_LIBRARY_PATH environmental variable to
search for libraries, but how can I actually modify the variable?
I've tried exporting it from adb shell (where I've included the
additional library search path I need), and then started my activity
from the shell using "am", but the LD_LIBRARY_PATH seems to be reset
to only "/system/lib" when the application launches (verified using
System.getenv in Java).
I have even written a "putenv" JNI wrapper (for the C function) so
that I can call putenv and set the LD_LIBRARY_PATH variable from my
Java app before the System.loadlibrary call that loads my JNI library.
Whilst this actually does seem to update the LD_LIBRARY_PATH variable,
it does not seem to fix the problem (runtime linker still cannot find
the library).
I was also trying to use the "-rpath" linker option during linking of
libapp.so, but it does not seem to be being honoured by the runtime
linker.
Thanks for anyone's help.
Kind regards,
Eugene
P.S. Apologies to David Turner - I accidentally also replied-to-author
with this question earlier...
Hi,
I have a JNI app (libapp.so) which links with another of my shared
libraries (libshared.so, pre-built with android toolchain). I'm using
Android 2.1.
At runtime when the app is launched on emulator, it predictably fails,
citing that it cannot find libshared.so.
As is known, the runtime will only look for shared libraries in
"system/lib" (and I cannot put my libshared.so in there).
Is there a "best-practice" way to get the runtime to be able to find
my shared library (libshared.so)?
e.g. I have deployed it to my /data/data/com.example.test/app/lib
directory (which is where the JNI libapp.so goes), so I just want the
runtime to also search this path when searching for shared libraries.
In the source code for Android 2.1, I can see that the runtime
linker.c is now using the LD_LIBRARY_PATH environmental variable to
search for libraries, but how can I actually modify the variable?
I've tried exporting it from adb shell (where I've included the
additional library search path I need), and then started my activity
from the shell using "am", but the LD_LIBRARY_PATH seems to be reset
to only "/system/lib" when the application launches (verified using
System.getenv in Java).
I have even written a "putenv" JNI wrapper (for the C function) so
that I can call putenv and set the LD_LIBRARY_PATH variable from my
Java app before the System.loadlibrary call that loads my JNI library.
Whilst this actually does seem to update the LD_LIBRARY_PATH variable,
it does not seem to fix the problem (runtime linker still cannot find
the library).
I was also trying to use the "-rpath" linker option during linking of
libapp.so, but it does not seem to be being honoured by the runtime
linker.
Thanks for anyone's help.
Kind regards,
Eugene
P.S. Apologies to David Turner - I accidentally also replied-to-author
with this question earlier...
--
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.
I will just clarify some things to make sure I have explained
correctly and because I made a mistake in my previous post...
My JNI application is called "app" (app.java).
The JNI shared lib is: libapp.so
I have an additional shared lib (that I built with the Android
toolchain on linux/ubuntu), called: libshared.so
I run the NDK/build the JNI lib using cygwin on windows.
In the Android.mk file I have (among other stuff):
LOCAL_SRC_FILES := appjni.cpp # native code that calls
functions declared in libshared.so
LOCAL_MODULE:= app
LOCAL_LDLIBS += -lshared # link in shared library
libshared.so
Note that this means I am linking the shared library libshared.so
into the JNI shared library libapp.so, because appjni.cpp makes calls
to functions declared/defined in libshared.so.
The runtime linker will need to find the libshared.so library when
libapp.so is loaded (i.e. from my java app).
The build/link works successfully.
In app.java, I call System.loadLibrary("app"); as per the usual way
to load the JNI library.
Ehen I launch the activity using the emulator in debug, I get the
following logcat message:
02-04 23:39:06.949: INFO/dalvikvm(404): Unable to dlopen(/data/data/
com.example.app/lib/libapp.so): Cannot load library:
link_image[1721]: 30 could not load needed library 'libshared.so'
for 'libapp.so' (load_library[1051]: Library 'libshared.so' not found)
This error occurs at the System.loadLibrary("app") call in app.java.
I understand the final part of the error is coming from the runtime
linker (bionic linker.c) complaining that it can't find my
libshared.so.
Now I have actually created another JNI library called putenv which
simply wraps the C putenv function in a native JNI wrapper.
In app.java, I call
System.loadLibrary("putenv");
putenv("LD_LIBRARY_PATH=/data/data/com.example.app/lib");
String sEnv = System.getenv("LD_LIBRARY_PATH");
and I have verified that sEnv == "/data/data/com.example.app/lib"
after this call.
I then go ahead with the System.loadLibrary("app"); call, but I get
the same error in logcat.
Of course there is no preference for putting my additional shared lib
in /data/data/com.example.app/lib, I have tried putting it in other
places (e.g. just /data), but it can never be found.
I cannot put it in /system/lib because it is full.
FYI I can successfully build and run JNI apps (that don't depend on
shared libraries linked in), I'm only having this issue when I link/
use libshared.so in the build of libapp.so.
What I don't understand is, if I've modified the LD_LIBRARY_PATH env
variable, why doesn't the linker find the library at runtime?
Is there something else I can do to be able to place my shared library
in a 'findable' location for the runtime linker?
I don't wish to use "dlopen" etc at runtime to make the calls to
libshared.so. I understood (?) that there is not much different
between manually using dlopen and linking the shared library at build
time (so long as the runtime system can find the shared library on the
target system).
> you should place your native shared libraries in
> /data/data/<package-name>/lib.
> I doubt /data/data/<packagename>/<subdir>/lib would work.
Thanks, sorry, I misseplt the path in my original post, that's where I
put it.
> Oh no, please don't do that, there are some good reason to avoid
> hard-coding paths in shared libraries like that.
hehe yes, it was just another of my attempts at getting the runtime
linker to find my shared library :)
Thanks again for your assistance
Kind regards
Eugene
On Feb 4, 3:36 pm, David Turner <di...@android.com> wrote:
> > android-ndk...@googlegroups.com<android-ndk%2Bunsu...@googlegroups.com>
Looking at bionic/linker/linker.c, it's parsing the LD_LIBRARY_PATH
environment value at startup time. I don't think a change to
LD_LIBRARY_PATH made once the process is running will be noticed by
the linker.
Doing a quick web search, this appears to be the expected behavior on
Linux.
I don't think you can solve your problem this way. Can you do an
explicit System.loadLibrary("shared") before your
System.loadLibrary("app")?