Re: Final shared library has no symbols

4,189 views
Skip to first unread message

David Turner

unread,
Apr 4, 2013, 9:29:28 AM4/4/13
to andro...@googlegroups.com



On Tue, Apr 2, 2013 at 3:06 PM, Robert Castle <rob...@robertcastle.co.uk> wrote:
Hi,

I am using the NDK to build various shared libraries that will be loaded by the Unity3D game engine, as such they are standalone libraries with no Java code and no Activities. They are pure C and C++.

When I build a shared library everything seems to work except the .so that is output in libs/<target-platform>/ contains no symbols. However, in obj/local/<target-platform>/ there is a complete .so file with all the symbols. I have used nm to check that there are no symbols, and the one in lib is only a few 100kb in size, where the obj one is many Mb and is comparable in size to its iOS static lib counterpart. Using the lib in the obj folder in Unity works.

What do you mean exactly by "no symbols"? By design, ndk-build will do the following:

1) build all code with full debug symbols and info (even in "release" mode which implies -O2) and place it under obj/local/
2) copy stripped versions of the obj/local/ installable binaries (i.e. shared libraries and executables) into libs/$ABI/

NOTE: The stripping should not remove exported ELF symbols, only the debug ones.

The reason for doing this is that only the stuff under lib/$ABI/ is picked by the APK building tools, and embedded into final Android packages.
There is no reason to put debug symbols into the lib/ binaries because remote debugging (e.g. with ndk-gdb) will use the stuff under obj/local/ which has everything needed by GDB on the host. Putting these symbols on the device would thus be a waste of disk space.
 
Note also that static libraries are not copied to lib/, this is intentional because these do not contain real executable code, and can't be loaded/run on a device, hence don't need to be in an Android APK.

Why is the build system stripping everything? And how do I stop it?

You can't really stop it, but you can use the binaries under obj/local/ if you need the full debug symbols. Note that I don't know how Unity3D works.
 
On a related note, when I build static libraries (for use as a prebuilt module for inclusion in other shared libs) they never get copied to the libs/ folder, I have to do it manually. Is this correct?

Yes, see above.
 
Here is a sample of what I am doing.

Directory Layout:

/<path to code>/
  ndk-modules/
    moduleA/
      Android.mk
      Application.mk
      <src code>
    moduleB/
      Android.mk
      Application.mk
      <src code>


Application.mk

APP_OPTIM := debug
APP_ABI := armeabi-v7a
APP_PLATFORM := android-14
APP_STL := stlport_static
APP_CPPFLAGS := -frtti -fexceptions -mfloat-abi=softfp -mfpu=neon
APP_BUILD_SCRIPT := Android.mk
APP_MODULES := moduleA

Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

export MYPATH := $(LOCAL_PATH)

LOCAL_CPP_EXTENSION := .cc .cpp .cxx
LOCAL_ARM_MODE  := arm
LOCAL_PATH      := $(NDK_PROJECT_PATH)
LOCAL_MODULE    := moduleA
LOCAL_CFLAGS    := -Werror
LOCAL_SRC_FILES := <list of cpp files>
LOCAL_LDLIBS := -llog -ldl

LOCAL_EXPORT_C_INCLUDES := $(MYPATH)/include

include $(BUILD_SHARED_LIBRARY)

When building a static lib the only change is that the final line is

include $(BUILD_STATIC_LIBRARY)


And finally, I am building the library with the following command:

$NDKROOT/ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk NDK_MODULE_PATH=../ 


Thanks.

Robert.

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

Robert Castle

unread,
Apr 4, 2013, 2:48:13 PM4/4/13
to andro...@googlegroups.com


On Thursday, April 4, 2013 2:29:28 PM UTC+1, Digit wrote:



On Tue, Apr 2, 2013 at 3:06 PM, Robert Castle <rob...@robertcastle.co.uk> wrote:
Hi,

I am using the NDK to build various shared libraries that will be loaded by the Unity3D game engine, as such they are standalone libraries with no Java code and no Activities. They are pure C and C++.

When I build a shared library everything seems to work except the .so that is output in libs/<target-platform>/ contains no symbols. However, in obj/local/<target-platform>/ there is a complete .so file with all the symbols. I have used nm to check that there are no symbols, and the one in lib is only a few 100kb in size, where the obj one is many Mb and is comparable in size to its iOS static lib counterpart. Using the lib in the obj folder in Unity works.

What do you mean exactly by "no symbols"? By design, ndk-build will do the following:

1) build all code with full debug symbols and info (even in "release" mode which implies -O2) and place it under obj/local/
2) copy stripped versions of the obj/local/ installable binaries (i.e. shared libraries and executables) into libs/$ABI/

NOTE: The stripping should not remove exported ELF symbols, only the debug ones.

The reason for doing this is that only the stuff under lib/$ABI/ is picked by the APK building tools, and embedded into final Android packages.
There is no reason to put debug symbols into the lib/ binaries because remote debugging (e.g. with ndk-gdb) will use the stuff under obj/local/ which has everything needed by GDB on the host. Putting these symbols on the device would thus be a waste of disk space.
 
Note also that static libraries are not copied to lib/, this is intentional because these do not contain real executable code, and can't be loaded/run on a device, hence don't need to be in an Android APK.

What I mean is that the .so file in the obj dir is obviously a complete .so - all the compiled code is there. But during the transfer to the lib dir the build system is stripping out all of the compiled code leaving an empty husk on a .so file. This happens with debug and release builds. As I said before, I am using nm to list the symbol tables. the obj so has one, the lib so does not. The build system seems to be determining that none of the functions are used and removing them. As there is no main() function and no Java JNI code referencing any of the library code, is this why the build system ignores it all? And how do I override this stripping functionality when building a prebuilt shared library?
 

Why is the build system stripping everything? And how do I stop it?

You can't really stop it, but you can use the binaries under obj/local/ if you need the full debug symbols. Note that I don't know how Unity3D works.

After posting, I found that adding 
cmd-strip := 
 to my Android.mk to override the stripping function copied the so in the obj to lib untouched, but obviously this is not the desired behaviour if I need the debug symbols removed. This poster seems to have been having the same issue I have when building standalone modules.

Is the ndk-build system not suited to building standalone prebuilt modules? should I be using the standalone toolchain instead?

Junwei Van

unread,
Dec 11, 2014, 9:42:52 PM12/11/14
to andro...@googlegroups.com
Thanks Robert, "cmd-strip := " worked,nice job! 
Reply all
Reply to author
Forward
0 new messages