Unresolved symbols and LOCAL_ALLOW_UNDEFINED_SYMBOLS

2,447 views
Skip to first unread message

Li Hui

unread,
Apr 27, 2011, 12:28:04 PM4/27/11
to andro...@googlegroups.com
Hi,

I have 2 .so files with cross dependence.
Example liba.so will call functions in libb.so, and libb.so will call functions in liba.so too.
I know its bad, but the situation is more complicated.

My question is how can I load them in java?
When I try to System.loadLibrary the 1st so file, java.lang.UnsatisfiedLinkError will be cause since unresolved symbols.
Now, the 2nd so file have not been loaded, so of course there are unresolved symbols, but they will all be fixed when the 2nd so file is loaded.

Will android discover unresolved symbols on load so library or on exec their functions? ( Like RTLD_LAZY for dlopen )

Below is a simple example to demo my problem.( from hello-jni in ndk)
The hello function is not defined in the code, and when I load it ( not when I call unimplementedStringFromJNI ),
java.lang.UnsatisfiedLinkError will be caused.
In fact, I have never call unimplementedStringFromJNI() in my program.

BTW, you must add LOCAL_ALLOW_UNDEFINED_SYMBOLS=true in android.mk to pass the compile.

Thanks.


jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}


extern void hello(void);

jstring
Java_com_example_hellojni_HelloJni_unimplementedStringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    hello();
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}


lihui

David Turner

unread,
Apr 28, 2011, 3:02:28 AM4/28/11
to andro...@googlegroups.com
On Wed, Apr 27, 2011 at 6:28 PM, Li Hui <xylop...@gmail.com> wrote:
Hi,

I have 2 .so files with cross dependence.
Example liba.so will call functions in libb.so, and libb.so will call functions in liba.so too.
I know its bad, but the situation is more complicated.

My question is how can I load them in java?
When I try to System.loadLibrary the 1st so file, java.lang.UnsatisfiedLinkError will be cause since unresolved symbols.
Now, the 2nd so file have not been loaded, so of course there are unresolved symbols, but they will all be fixed when the 2nd so file is loaded.


You can load both libraries at the same time. I suspect something like that is also going to fail on standard Linux unless you use weak references or other hideous things. Frankly, you'd better fix the issue (e.g. only build a single shared lib).

 
Will android discover unresolved symbols on load so library or on exec their functions? ( Like RTLD_LAZY for dlopen )

Below is a simple example to demo my problem.( from hello-jni in ndk)
The hello function is not defined in the code, and when I load it ( not when I call unimplementedStringFromJNI ),
java.lang.UnsatisfiedLinkError will be caused.
In fact, I have never call unimplementedStringFromJNI() in my program.

BTW, you must add LOCAL_ALLOW_UNDEFINED_SYMBOLS=true in android.mk to pass the compile.

Thanks.


jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}


extern void hello(void);

jstring
Java_com_example_hellojni_HelloJni_unimplementedStringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    hello();
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}


lihui

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

Li Hui

unread,
Apr 28, 2011, 12:31:29 PM4/28/11
to andro...@googlegroups.com
Hi David,

Yes, I am trying to build them into a single shared library, but there
are some problems for me.

My 1st library is similar with native activity but I want to use it on
android 2.2.
So I need:
 1> Some java code in it.
 2> Some jni code in it.
 3> Call a "main" function in user library in it.
I mark this project as a android library by select "Is Library“ in eclipse.

Then, if I put all c code in this project into a shared library,
application project ( who has a user library as I mentioned ) who
reference this project will automatically include this shared library.
But this will cause the library load issue as I mentioned in my last
email.

If I put all c code in this project into a static library, seems ndk
makefile can not include a static library out of project folder and
can only include modules that build in a same project. I have tried:
LOCAL_STATIC_LIBRARIES = libmylibrary.a
LOCAL_STATIC_LIBRARIES = mylibrary
LOCAL_STATIC_LIBRARIES = libmylibrary
LOCAL_STATIC_LIBRARIES =
$(LOCAL_PATH)/../../mylibrary/obj/local/$(TARGET_ARCH_ABI)/libmylibrary.a
LOCAL_STATIC_LIBRARIES =
/cygwin/d/.../mylibrary/obj/local/$(TARGET_ARCH_ABI)/libmylibrary.a (
more bad )
copy the libmylibrary.a to libs/$(TARGET_ARCH_ABI) and using
LOCAL_STATIC_LIBRARIES = libmylibrary.a

But all above can not work. libmylibrary.a will not be included in
link command. ( I see it by add V=1 in build command )


The only way I found that can work is:
LOCAL_LDLIBS = d:/.../mylibrary/obj/local/$(TARGET_ARCH_ABI)/libmylibrary.a,
even
LOCAL_LDLIBS = $(LOCAL_PATH)/../../mylibrary/obj/local/$(TARGET_ARCH_ABI)/libmylibrary.a
or
LOCAL_LDLIBS = /cygwin/d/.../mylibrary/obj/local/$(TARGET_ARCH_ABI)/libmylibrary.a,
can not work ( I am using cygwin ) with error that can not find libmylibrary.a
But this is not a good way I think, because every time libmylibrary.a
changes, the application library will not auto re-link, and I have to
clean it or add -B in command line.

Do you have any suggestion?
Thanks.

lihui

David Turner

unread,
Apr 29, 2011, 8:49:51 AM4/29/11
to andro...@googlegroups.com


On Thu, Apr 28, 2011 at 6:31 PM, Li Hui <xylop...@gmail.com> wrote:
Hi David,



If I put all c code in this project into a static library, seems ndk
makefile can not include a static library out of project folder and
can only include modules that build in a same project.

You can do that by defining a prebuilt module that points to your library.
See docs/PREBUILTS.html for details. 

This should solve your problem.

Li Hui

unread,
Apr 29, 2011, 10:08:15 AM4/29/11
to andro...@googlegroups.com
Hi David,

It works under your way, thanks very much for your effective help.
Here is my last workable version for others reference:

#------Android.mk of library----------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylibrary
LOCAL_SRC_FILES := src/mylibrary.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/src $(LOCAL_PATH)/include
include $(BUILD_STATIC_LIBRARY)

#------Application.mk of library----------
APP_MODULES = mylibrary

#---------Android.mk of application---------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylibrary-prebuilt
LOCAL_SRC_FILES := ../../mylibrary/obj/local/$(TARGET_ARCH_ABI)/libmylibrary.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../mylibrary/jni/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := testApp
LOCAL_SRC_FILES := main.c
LOCAL_LDLIBS := -llog
LOCAL_STATIC_LIBRARIES := mylibrary-prebuilt
include $(BUILD_SHARED_LIBRARY)


lihui

jndis

unread,
Jun 15, 2013, 4:19:55 PM6/15/13
to andro...@googlegroups.com
what's rong with that
LOCAL_PATH := $(call my-dir)
include $(call all-subdir-makefiles)

include $(CLEAR_VARS)
LOCAL_MODULE    := native-audio-jni 
LOCAL_SRC_FILES := \
native-audio-jni.cpp\
sqlite3.c\
mysqlite.h 
LOCAL_STATIC_LIBRARIES := libstk
# for native audio
LOCAL_LDLIBS    += -lOpenSLES
# for logging
LOCAL_LDLIBS    += -llog
# for native asset manager
LOCAL_LDLIBS    += -landroid
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
#LOCAL_LDLIBS    += -libstk
#$(call import-module,$(LOCAL_PATH)/libstk.a)
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE    := libstk 
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libstk.a
LOCAL_EXPORT_C_INCLUDES :=$(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
thx 
Reply all
Reply to author
Forward
0 new messages