I am having a problem when using a pre-built static library when the compiler is looking for headers.
I have a .cpp that needs to use a header file from a static library. My Android.mk is as followed :
include $(CLEAR_VARS)
LOCAL_MODULE := LibA
LOCAL_SRC_FILES := libs/libA.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.cpp
LOCAL_STATIC_LIBRARIES := LibA
include $(BUILD_SHARED_LIBRARY)
hello.cpp requires a header that can be found in the static library but the compiler says it can't find it. Do I have to have headers seperated from that static library ?
Headers are not included in static libraries. Even if they were, the compiler has no way to read a .a file, only the linker will do that.
I'm not a prof, but I've learned that you allways need a corresponding .h-file
included! In those .h-files the compiler gets the info "how to use" the libraries
as they defines the functions that are inside the libs.
Good luck
Martin
try "LOCAL_LDLIBS" in 2nd step.
Related
In my Android application, I have quite a few open-source C++ projects that are built as static libraries. Essentially, Android.mk builds all the libraries as static and links them all to create my final core.so library.
Our nightly build checks out all the files from the source control in a clean directory and builds everything that is needed.
I am looking at how I can optimize our nightly build. As the third-party code does not change (may be once every six months), I would like to build them just once and check in the generated libs. I am guessing these libs would have a ".a" extension. The nighly build will simply check out these libs and link them to create my final core.so.
Basically, I am hoping I can break my existing Android.mk into two different ones - one for building static libraries and one for building the final shared library that the Android code can use.
I am wondering if this is possible. Regards.
You're looking for prebuilt library support.
Assuming your static library declaration looks something like this:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)
you can make it use a prebuilt instead:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := libs/foo.a
include $(PREBUILT_STATIC_LIBRARY)
and include in your core lib just the same:
include $(CLEAR_VARS)
LOCAL_MODULE := myCore
LOCAL_SRC_FILES := core/core.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
So you could have a seperate Android.mk, or just use a conditional variable.
ifeq ($(USE_PREBUILT_LIBS),)
# declare with BUILD_STATIC_LIBRARY
else
# declare with PREBUILT_STATIC_LIBRARY
endif
I have .so file which i have created using a c library .Now i want to use .so file in another project for call those functions. I don't know how to use that library. How to call any function from that library? I have tried but found error as Native method not found.I am a beginner with Ndk in android.any help on this..??
I have referred many links those were not solved my problem as
Native method not found,
java.lang.UnsatisfiedLinkError: Native method not found,
I am facing the same as this link but it is unanswered. link is
Need NDK Help: How to call a C++ function for shared library from another project that uses C++
My Android.mk file is as follows from which i have created .so file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ShairportSample
LOCAL_SRC_FILES := ShairportSample.cpp
APP_PLATFORM := android-19
include $(BUILD_SHARED_LIBRARY)
you can call functions implemented inside the .so you want to reuse from another NDK lib, by setting it as prebuilt shared library your're depending on inside your Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ShairportSample
LOCAL_SRC_FILES := libs/$(TARGET_CPU_ABI)/libShairportSample.so
LOCAL_EXPORT_C_INCLUDES := PATH_TO_ShairportSample.h
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := yournewlib
LOCAL_SRC_FILES := yournewlib.cpp
LOCAL_SHARED_LIBRARIES += ShairportSample
include $(BUILD_SHARED_LIBRARY)
From your Java code you'll have to load ShairportSample lib from your Java before loading yournewlib.
Otherwise, if you want to reuse your .so directly from Java, you should export a Java library (.jar) that uses it. Then you can reuse this Java lib from your other project.
first of all, you should make sure the .so file being compiled correctly, named it like this libYourLibName.so, put it into libs/armeabi folder.
secondly, make sure you have loaded the .so file from static block
static {
System.loadLibrary("YourLibName");
}
may this will help you
I have an Android project written in C++ and have a problem in linking phase. The code is put in some static libraries which should be linked together.
I have found a lot of questions and answers on the net about this topic and most of them suggest to put my libraries to LOCAL_STATIC_LIBRARIES in the Android.mk file. But, if I do this, I found the content of LOCAL_STATIC_LIBRARIES is simply ignored: my libraries are not linked, and adding any dummy text here does not generate any error or warning message.
I tried it this way:
LOCAL_STATIC_LIBRARIES := MyLib.a
or with full path:
LOCAL_STATIC_LIBRARIES := $(LOCAL_PATH)/MyLib.a
none of them worked.
If I put my static libraries to LOCAL_LDLIBS then it is linked, but I got a warning message about non-system libraries are used, and probably the build will be wrong.
The content of my Android.mk file is:
LOCAL_LDLIBS := $(LOCAL_PATH)/MyLib.a ...
and I got this message:
Android NDK: WARNING:jni/Android.mk:myapp: non-system libraries in linker flags: jni/MyLib.a
Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module
I could not find how to use LOCAL_STATIC_LIBRARIES right way, please help me!
I have android-ndk-r9 and android-sdk_r22.2.1 on a OpenSuSE x86 and using target=android-18
See JBL's answer here.
The LOCAL_STATIC_LIBRARIES variable does not work that way. First you need a section that defines the library you want to include:
include $(CLEAR_VARS)
LOCAL_PATH = .
LOCAL_MODULE := curl
LOCAL_EXPORT_C_INCLUDES := ../curl/include
LOCAL_SRC_FILES := ../curl/lib/libcurl.a
include $(PREBUILT_STATIC_LIBRARY)
THEN, you can include it using
include $(CLEAR_VARS)
LOCAL_MODULE = mylib
CFLAGS = ...
...
LOCAL_STATIC_LIBRARIES = curl
include $(BUILD_STATIC_LIBRARY)
Most probably the problem lies in that you are giving the extension of the library:
LOCAL_STATIC_LIBRARIES := MyLib.a
I think, it should be written as:
LOCAL_STATIC_LIBRARIES := MyLib
I have a program I am porting that links together multiple libraries when creating the executable. I have built all those libraries using the stand alone toolchain and using the standalone toolchain I am able to create an executable that works on an android device. So, it seems like the libraries I have built are functional. Now I am trying to incorporate those libraries with an app. So, in my android.mk I have something like this:
LOCAL_PATH := $(call my-dir)
ROOT_PATH := $(LOCAL_PATH)
include $(call all-subdir-makefiles)
include $(CLEAR_VARS)
LOCAL_PATH = $(ROOT_PATH)
LOCAL_MODULE := test-libs
LOCAL_STATIC_LIBRARIES := staticA
LOCAL_SHARED_LIBRARIES := sharedA sharedB sharedC sharedD
LOCAL_SRC_FILES := test-libs.c
include $(BUILD_SHARED_LIBRARY)
For each of the libraries, I have a Android.mk like this
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sharedA
LOCAL_SRC_FILES := libsharedA.so
include $(PREBUILT_SHARED_LIBRARY)
The static library and one of the shared libraries have no dependencies on anything and if I only include them all is cool. One shared prebuilt library is dependent on the static prebuilt library only and the others are dependent on the prebuilt static library and other prebuilt shared libraries.
The problem is if I load any that are dependent on the static library via System.loadLibrary() I get the useful message:
Unable to dlopen(libsharedA.so) Cannot load library: link_image
Digging through this and following the suggestions here about how to use strace:
http://mpigulski.blogspot.com/2010/09/debugging-dlopen-unsatisfiedlinkerror.html
I found that when the shared libraries are loaded, they cannot locate a function that is in my static library.
So, how do I correctly use a prebuilt shared library whose use is dependent on a prebuilt static library and not have this issue?
Shared libraries should not depend on static libraries.
Static libraries are for linking (at compile-time) into an executable, not for adding at runtime.
If your shared library A uses a static library B, then either build a shared version of B or include B when you link A together.
I compiled Sox et al with NDK. So, I have all Android-friendly shared libs.
I made a simple test file which calls a sox function.
NDK build tells me:
undefined reference to `sox_open_read'
sox_open_read is defined in sox.h. I know it's finding sox.h because it gives me a warning about that file:
In file included from (...)/sox/sox.h:19
So maybe it wants to find sox_open_read in the actual libsox.so. Well, I've tried about a 100 different ways to tell it where the sox shared lib is e.g.
LOCAL_SHARED_LIBRARY := sox
LOCAL_LDLIBS := -L$(LOCAL_PATH_FULL)/jni/libs/libsox.so
However, It will work if I specify Sox as a static library:
#LOCAL_SHARED_LIBRARY := sox
LOCAL_STATIC_LIBRARIES := sox
LOCAL_LDLIBS := -L$(LOCAL_PATH_FULL)/jni/libs/libsox.so
It's my understanding that I don't want to staticly link to the sox lib - I want to dynamically link to it.
You should define libsox.so as a prebuilt library. Create a makefile as the following and put your prebuilt libsox.so in the same directory with this makefile. After that, you can use libsox same as you've rebuilt it. Don't forget to include this makefile into your build.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libsox
LOCAL_SRC_FILES := libsox.so
include $(PREBUILT_SHARED_LIBRARY)