This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Makefile for making dynamic native lib

Hello!

Tell me please what  compiler options I should use to make dynamic native lib for arm? 

I want load this library from Android app and now I get error 

05-24 15:56:12.312: I/nativeCode(6703): Cannot load library: link_image[1995]: failed to link libnative.so

So I suppose there are problems with arm-none-linux-gnueabi-gcc options (from Sourcery_G++_Lite)

Makefile

C_FLAGS	+= -O3 -march=armv7-a -mtune=cortex-a8 -mfpu=neon -ftree-vectorize -mfloat-abi=softfp 
C_FLAGS	+= -DPLATFORM=3730
CSTOOL_DIR=/Chet/CodeSourcery/Sourcery_G++_Lite
ARM_GCC=$(CSTOOL_DIR)/bin/arm-none-linux-gnueabi-gcc

libnative.so: swap.o
	$(ARM_GCC) $(C_FLAGS) -shared -o libnative.so swap.o 
swap.o: swap.c
	$(ARM_GCC) $(C_FLAGS) -c -fPIC swap.c
clean:
	rm -f *.o *.so MAIN

P.S. my device is TDM-3730W Blizzard Interface board with installed on it Android 2.2 

  • You can try code samples from Android NDK

    http://developer.android.com/sdk/ndk/index.html

    http://developer.android.com/sdk/ndk/overview.html#samples

    some of those are in the Android source code inside NDK folder

    ./mydroid/development/ndk/samples/

    if you plan to use dlopen() check

    /android-ndk/workdir/ndk/docs/STABLE-APIS.html (look for "Dynamic Linker Library")

    some security comments apply when accessing the system using libraries and depending of its type or use

    http://source.android.com/tech/security/index.html

    http://developer.android.com/guide/practices/security.html

  • Thank you for your response. But these links doesn't solve my issue. =(

    I think there is no problem with dlopen. Because problem appears even if I use System.loadLibrary() instead dlopen()

    I can't load only my library. May be my makefile for library is wrong? 

    Thirst I loaded native lib 

    static {
    	System.loadLibrary("NativeLib");
    	}

    NativeLib successfully started. Then I called function from this lib load_lib_from_cpp(mylib.so)

    In that function I try to load mylib.so

     dl_handle = dlopen( lib, RTLD_LAZY );
      if (!dl_handle) {
    	  error = (char *) dlerror();
    	  if (error != NULL)
    	  	  __android_log_print(ANDROID_LOG_INFO,"nativeCode",error);
    	  else {
    		  sprintf(sError,"%s is not found",lib);
    		  __android_log_print(ANDROID_LOG_INFO,"nativeCode",sError);
    	  }
    	  return -1;
      }

    And I got error 

     05-24 15:56:12.312: I/nativeCode(6703): Cannot load library: link_image[1995]: failed to link mylib.so

  • I added in Android.mk -ldl option. (as STABLE-APIS.html requires)

    LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog -ldl

    I still have error 

    01-01 02:34:35.554: D/dalvikvm(6336): Trying to load lib /data/data/qqq.zzz.test/lib/libNative.so 0x43fed100
    
    01-01 02:34:35.554: D/dalvikvm(6336): Added shared lib /data/data/qqq.zzz.test/lib/libNative.so 0x43fed100
    
    01-01 02:34:35.554: D/dalvikvm(6336): No JNI_OnLoad found in /data/data/qqq.zzz.test/lib/libNative.so 0x43fed100, skipping init
    
    01-01 02:34:35.601: I/nativeCode(6336): Cannot load library: link_image[1995]: failed to link mylib.so

    Three first strings tell us that native lib is loaded. Last string describes error while loading mylib.so

    Help please!

    P.S. mylib.so is sutiated in app directory /data/data/qqq.zzz.test

  • Finally I have changed my makefile for library. As you can see, I use another compiler. arm-linux-androideabi-gcc instead arm-none-linux-gnueabi-gcc

    NDK_DIR=/usr/local/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
    ARM_GCC=$(CSTOOL_DIR)/bin/arm-none-linux-gnueabi-gcc
    ANDROID_GCC=$(NDK_DIR)/arm-linux-androideabi-gcc
    NDK_ROOT=/usr/local/android-ndk-r8
    
    CPPFLAGS = $(NDK_ROOT)/platforms/android-8/arch-arm/usr/include
    CFLAGS =-nostdlib
    LDFLAGS = -Wl,-rpath-link=$(NDK_ROOT)/platforms/android-8/arch-arm/usr/lib/ -L$(NDK_ROOT)/platforms/android-8/arch-arm/usr/lib/
    LIBS=-lc
    android_libdsp.so: swap.o
    	$(ANDROID_GCC) $(CFLAGS)  -shared -o android_libdsp.so swap.o 
    swap.o: swap.c
    	$(ANDROID_GCC) $(CPPFLAGS) $(CFLAGS) -c -fPIC swap.c
    clean:
    	rm -f *.o *.so 
    

    Changes in makefile solved the problem with dlopen(), but problem with dlsym() have appeared %)) 

    01-01 07:00:44.624: I/nativeCode(8696): Symbol not found:

    I will be grateful for any ideas))

  • You can move your library code to use a sample from Android NDK, using hello-jni should be ok.

    About your makefile, I ran a search in Android NDK and there are no projects using Makefile files, that is why of suggesting moving code to one of the samples, when compiling the library there are some other processed made in the background you can check them by reading involved files running a search for BUILD_SHARED_LIBRARY or the type of binary you are using.

    ./android-ndk-r7b/build/core/build-all.mk
    ./android-ndk-r7b/build/core/build-module.mk
    ./android-ndk-r7b/build/core/build-shared-library.mk
    ./android-ndk-r7b/build/core/definitions.mk

    An optional compilation process involves 2 parts, using Android NDK's build system for .so file and using Android SDK with Eclipse to build .apk, it requires to create new project and use a sample code then this creates the Android.mk.

    I can see that your library name is android_libdsp.so, that means you could need to implement it has part of the system and implement a service with system root permission in order to access HW, see next links for more information.

    http://e2e.ti.com/support/omap/f/849/t/178679.aspx   mostly focus in next post  http://e2e.ti.com/support/omap/f/849/p/178679/648158.aspx#648158

    An advanced option to use is in (compiled from inside Android source code):

    ./mydroid/device/sample/frameworks/PlatformLibrary/README.txt

    Android's .apk client code is here

    ./mydroid/device/sample/apps/client

    If you move this library from .cpp to .c most significant change is to add JNIEnv in NDK's functions as first argument for .c. Compiler selects between .c and .cpp base in file extension, by this if you name it .c add only c code.

    Try to read Android's NDK documentation to get a full picture of what is possible to do with it, there are samples for native applications and other options.

    When using a Platform Library it seems to be required a .xml file to configure this permissions, a reference to this is in README.txt and in next link

    http://developer.android.com/guide/topics/manifest/manifest-intro.html

    The .xml file in this sample is com.example.android.platform_library.xml, main instructions about how it is used and how to integrate it in previously mentioned README.txt, and ./mydroid/device/sample/products/sample_addon.mk, but in next README.txt it is compiled as a full package in a .jar solution to be used by the system.

    ./mydroid/device/sample/README.txt

    I had traced back some instructions to copy this .xml when system is build to next locations, it uses the instructions from sample_addon.mk. like example

    ./mydroid/device/ti/blaze_tablet/device.mk that is called from ./mydroid/device/ti/blaze_tablet/full_blaze_tablet.mk and this one in the build chain for each product Android.mk.

    Unfortunately I restarted my local repository without backing up those changes, but you must find enough information to implement it in present post.

  • Manuel Contreras, 
    thank you very much for detailed responce. 

    But I really can't move code of my library to jni/cpp of Android project. I want dynamically load library from native side. 

    I have two projects. One of them is Android app with Native code, which just loads dynamically library android_libdsp.so

    Another project is that library (android_libdsp.so). Code of this library is simple just for learning how things are going. It has only one function. Here is it: 

    int calculate (int x, int y)
    {
        return (x*x+y*y);
    }

    In makefile I use cross-platform compilator from Android toolchains (/usr/local/android-ndk-r8/toolchains/arm-linux-androideabi4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc) 

    NDK_DIR=/usr/local/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
    ANDROID_GCC=$(NDK_DIR)/arm-linux-androideabi-gcc
    NDK_ROOT=/usr/local/android-ndk-r8
    
    CPPFLAGS = $(NDK_ROOT)/platforms/android-8/arch-arm/usr/include
    CFLAGS =-nostdlib
    LDFLAGS = -Wl,-rpath-link=$(NDK_ROOT)/platforms/android-8/arch-arm/usr/lib/ -L$(NDK_ROOT)/platforms/android-8/arch-arm/usr/lib/
    LIBS=-lc
    
    android_libdsp.so: swap.o
    	$(ANDROID_GCC) $(CFLAGS)  -shared -o android_libdsp.so swap.o 
    
    swap.o: swap.c
    	$(ANDROID_GCC) $(CPPFLAGS) $(CFLAGS) -c -fPIC swap.c
    clean:
    	rm -f *.o *.so MAIN

    Then in another project (Android app) in native side I use dlopen() to load android_libdsp.so 

    dl_handle = dlopen( lib, RTLD_LAZY );
      if (!dl_handle) {
    	  error = (char *) dlerror();
    	  if (error != NULL) {
    	  	  __android_log_print(ANDROID_LOG_INFO,"nativeCode",error);
    	  	  return -1;
    	  }
    	  else {
    		  sprintf(sError,"%s is not found",lib);
    		  __android_log_print(ANDROID_LOG_INFO,"nativeCode",sError);
    		  return -2;
    	  }
      }

    It loads android_libdsp.so with no prolem. But if I am trying to call function calculate() I get error. 

    func = (int (*)(int, int)) dlsym( dl_handle, "calculate" );
      error = (char *) dlerror();
      if (error != NULL) {
    	  __android_log_print(ANDROID_LOG_INFO,"nativeCode",error);
    	  return -3;
      }

    Function returns -3 and in Logcat of Eclipse I can see 

    01-01 07:00:44.624: I/nativeCode(8696): Symbol not found:



  • I think it goes off of specifics of Android NDK's build system, it could be not supported to use that way. It is a difficult answer to provide since it is a custom solution by you.

    Try to check next file and "showcommands" modifier target, it could help for debugging purposes,

    ./mydroid/build/core/build-system.html

    or

    /android-ndk/docs/HOWTO.html

    "How to force the display of build commands"

    There are  too many variables and specific processor flags involved for each specific compilation, and that can vary depending on each device configuration, easiest way is to use Android specific build tools for this purpose, if something changes between releases it will only require to get latest Android NDK version.