Problem with LOCAL_SRC_FILES when using PREBUILT_SHARED_LIBRARY

2,988 views
Skip to first unread message

Ryan McFall

unread,
Jun 22, 2011, 4:05:46 PM6/22/11
to android-ndk
I am trying to build a JNI library that calls functions from libgif.
I have downlaoded the source code for libgif and built it using the
android toolchain. So far so good. This creates libgif.so, which
points to libgif.so.4, which points to libgif.so.4.16. This seems to
be standard procedure to deal with soname.

I would like to be able to include libgif.so.4.16 as a prebuilt shared
library. Unfortunately, when I do:
LOCAL_SRC_FILES := libgif.so.4.16
in my Android.mk file, ndk-build complains:
LOCAL_SRC_FILES should point to a file ending with ".so"
Android NDK: The following file is unsupported: libgif.so.4.16

If I copy libgif.so.4.16 to libgif.so, then ndk-build is happy.
However, due to the SONAME entry in libgif, my JNI library contains a
reference to the library named libgif.so.4.16 (because that's the
SONAME the linker found when it linked built the .so for my library),
and when the application is deployed to the emulator/device, loading
the library fails because it's looking for libgif.so.4.16.

I suppose I can modified the build process for libgif so that the
SONAME entry is libgif.so, but it doesn't seem like I should have to
do this; it seems this would be a fairly common problem. It doesn't
make sense in particular that ndk-build expects LOCAL_SRC_FILES to be
files that end in .so, as most shared libraries will in fact have a
major and minor version number.

Any ideas/solutions would be appreciated!

Thanks,
Ryan

eocanha

unread,
Jun 27, 2011, 10:58:18 AM6/27/11
to android-ndk
On 22 jun, 22:05, Ryan McFall <mcfall.r...@gmail.com> wrote:

> If I copy libgif.so.4.16 to libgif.so, then ndk-build is happy.
> However, due to the SONAME entry in libgif, my JNI library contains a
> reference to the library named libgif.so.4.16 (because that's the
> SONAME the linker found when it linked built the .so for my library),
> and when the application is deployed to the emulator/device, loading
> the library fails because it's looking for libgif.so.4.16.

Of course, having proper support for shared library versioning would
be wonderful. In the meanwhile, the dirty hack of changing the library
soname solves the problem.

Changing a library soname isn't something easy [1]. If the new name
lenght is the same than the old name lenght I've found that a simple
search&replace is enough. If the new name is shorter (which is your
case), you can pad it with zeros to get the original length.

In your case, try this from your project directory after having done
ndk-build:

rpl -R -e libgif.so.4.16 "libgif.so\x00\x00\x00\x00\x00" libs obj

As a side note, I've found problems loading transitive library
dependencies and I've needed to use System.loadLibrary() for each of
the child libraries in the required order. This link [2] has useful
tricks to debug library dependencies.

[1] http://sourceware.org/ml/binutils/2008-12/msg00160.html
[2] http://mpigulski.blogspot.com/2010/09/debugging-dlopen-unsatisfiedlinkerror.html

eocanha

unread,
Jun 27, 2011, 8:48:30 AM6/27/11
to android-ndk
On 22 jun, 22:05, Ryan McFall <mcfall.r...@gmail.com> wrote:

> If I copy libgif.so.4.16 to libgif.so, then ndk-build is happy.
> However, due to the SONAME entry in libgif, my JNI library contains a
> reference to the library named libgif.so.4.16 (because that's the
> SONAME the linker found when it linked built the .so for my library),
> and when the application is deployed to the emulator/device, loading
> the library fails because it's looking for libgif.so.4.16.

I'm running into the same problem trying to link to other libraries
built with libtool. I've found a terribly dirty hack to solve the
problem: changing the soname after the library is compiled.

Some people [1] say that doing this in the proper way isn't easy, but
in my case I only want to remove the soversion part of the soname. The
new name would be shorter and allocations for more room in the library
aren't needed, so I perform a simple search & replace, filling the
extra characters (".4.16", now unneeded) with "\0".

In your case, try this command from the root of your project after the
ndk-build stage:

rpl -R -e libgif.so.4.16 "libgif.so\x00\x00\x00\x00\x00" libs obj

If you follow these instructions, you'll see that now the child
library is resolved. When linking from Java, however, I've needed to
open the children libraries first and the main library in the end with
System.loadLibrary().

Of course all these dirty hacks wouldn't be needed if proper support
for versioned libraries was added to ndk-build.

Let me know if it solves the problem for you. :-)

David Turner

unread,
Jun 29, 2011, 7:43:35 AM6/29/11
to andro...@googlegroups.com
On Wed, Jun 22, 2011 at 10:05 PM, Ryan McFall <mcfal...@gmail.com> wrote:
I am trying to build a JNI library that calls functions from libgif.
I have downlaoded the source code for libgif and built it using the
android toolchain.  So far so good.  This creates libgif.so, which
points to libgif.so.4, which points to libgif.so.4.16.  This seems to
be standard procedure to deal with soname.

It's only standard on Linux, not on Android.
 
I would like to be able to include libgif.so.4.16 as a prebuilt shared
library.  Unfortunately, when I do:
LOCAL_SRC_FILES := libgif.so.4.16
in my Android.mk file, ndk-build complains:
LOCAL_SRC_FILES should point to a file ending with ".so"
Android NDK: The following file is unsupported: libgif.so.4.16

If I copy libgif.so.4.16 to libgif.so, then ndk-build is happy.
However, due to the SONAME entry in libgif, my JNI library contains a
reference to the library named libgif.so.4.16 (because that's the
SONAME the linker found when it linked built the .so for my library),
and when the application is deployed to the emulator/device, loading
the library fails because it's looking for libgif.so.4.16.

I suppose I can modified the build process for libgif so that the
SONAME entry is libgif.so, but it doesn't seem like I should have to
do this; it seems this would be a fairly common problem

I'm sorry, but that's exactly what you'll need to do.
 
.  It doesn't
make sense in particular that ndk-build expects LOCAL_SRC_FILES to be
files that end in .so, as most shared libraries will in fact have a
major and minor version number.


I'm sorry, but even changing the NDK wouldn't be enough. You would have to modify the Ant build rules, the Android Eclipse plugin, and the device's Package Manager to recognize versioned library names. Which means this wouldn't work on existing devices anyway. It's not gonna happen.
 
Any ideas/solutions would be appreciated!

Thanks,
Ryan

--
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.


Reply all
Reply to author
Forward
0 new messages