I have some two shared libraries and header for them.
I want to build third shared library using functions from previous two libs.
Have problem with makefile i think. When i try to build receive this:
Android NDK: /cygdrive/d/.../jni/Android.mk: Cannot find module with tag 'shared1' in import path
Android NDK: Are you sure your NDK_MODULE_PATH variable is properly defined ?
Android NDK: The following directories were searched:
Android NDK:
/cygdrive/d/.../jni/Android.mk:36: *** Android NDK: Aborting. . Stop.
structure of my project:
jni/
- myfile.c
- Android.mk
jni/dec/
- lot of header files
jni/enc/
- lot of header files
libs/armeabi/
- shared1.so
- shared2.so
also Android.mk sourse:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/dec \
$(LOCAL_PATH)/enc
LOCAL_SHARED_LIBRARIES := shared1 shared2
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := myfile.c
LOCAL_LDLIBS += -lOpenSLES
LOCAL_LDLIBS += -llog
LOCAL_LDLIBS += -landroid
include $(BUILD_SHARED_LIBRARY)
$(call import-module, shared1)
$(call import-module, shared2)
Take a look to this question: Android JNI APK Packing
You need to give another name for libs/armeabi/ folder to avoid conflicts with NDK build and add the following code before the include $(CLEAR_VARS) statement:
include $(CLEAR_VARS)
LOCAL_MODULE:=shared1
LOCAL_SRC_FILES:=3rdparty_libs/shared1.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:=shared2
LOCAL_SRC_FILES:=3rdparty_libs/shared2.so
include $(PREBUILT_SHARED_LIBRARY)
As I understand it, the correct method is to use ndk-build and not invoking the compiler directly.
In Android.mk you need to specify a module for each static library you want to compile, and then specify that your shared library should use it.
Example of a modified Android.mk file of the hello-jni sample project:
LOCAL_PATH := $(call my-dir)
# Define vars for library that will be build statically.
include $(CLEAR_VARS)
LOCAL_MODULE := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := <list_of_src_files>
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_CFLAGS = -Wall -pedantic -std=c99 -g
include $(BUILD_STATIC_LIBRARY)
# First lib, which will be built statically.
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_STATIC_LIBRARIES := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
If you want control over which modules to compile when you run ndk-build you can create create a Application.mk file (in the same directory as Android.mk) and list all the modules as in the following example:
APP_MODULES := <module_name_1> <module_name_2> ... <module_name_n>
I think it Helps you
Related
I am having issues creating a Android prebuilt shared library. In hope of figuring out what I'm doing wrong, I followed Google's example where I found the source for this example in the android-8.1.0_r52 tree at development/ndk/tests/prebuilt-library/jni.
Here's how I configure the ASOP
$ . build/envsetup.sh
$ lunch (I selected 29 aosp_bullhead_userdebug)
Then in the above jni folder I issued "$ mm"
The error I get is (which is the same is my other project)
ninja: error: 'out/target/product/bullhead/obj/SHARED_LIBRARIES/foo-prebuilt_intermediates/export_includes', needed by 'out/target/product/bullhead/obj/SHARED_LIBRARIES/foo-user_intermediates/import_includes', missing and no known rule to make it
When I grep the out/target/products/bullhead folder for "foo" I get nothing.
I also tried replacing
include $(PREBUILT_SHARED_LIBRARY)
with
include $(BUILD_PREBUILT)
and get the same error, but "obj" is replaced with "obj_arm".
Below is the stock Android.mk that comes with the tree.
LOCAL_PATH := $(call my-dir)
# Define BUILD_FOO=1 to rebuild libfoo.so from scratch, then
# copy obj/local/armeabi/libfoo.so to jni/libfoo.so
#
ifneq ($(BUILD_FOO),)
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/foo
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/foo
include $(BUILD_SHARED_LIBRARY)
else # not build libfoo.so, trying to use PREBUILT_SHARED_LIBRARY instead.
# Note: the module is named foo-prebuilt, but the library is libfool.so !
#
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/foo
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := foo-user
LOCAL_SRC_FILES := foo-user.c
LOCAL_SHARED_LIBRARIES := foo-prebuilt
include $(BUILD_SHARED_LIBRARY)
endif
This is the jni/ directory structure
jni/
Android.mk
foo-user.c
libfoo.so
foo/
foo.c
foo.h
I'm making a library in C++ with OpenCV and JsonCpp towards building a library for Android and iOS.
On testing my library for Android, I'm making the JNI files but when I try to load the library I'm getting
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol
"_ZN4Json6WriterD2Ev" referenced by "libXYZ.so"...
and that's because I think I'm not building my Json library very well.
The library that I use is this one: https://github.com/open-source-parsers/jsoncpp
My Android.mk is:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_CAMERA_MODULES:=off
OPENCV_INSTALL_MODULES:=on
include $(LOCAL_PATH)/jsoncpp/Android.mk
include /Users/localmac/Desktop/AndroidDevelopment/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
OPENCV_LIB_TYPE:=SHARED
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_C_INCLUDES += /Users/localmac/mylibrary/OpenCVtry/
LOCAL_C_INCLUDES += /Users/localmac/Desktop/RD/OpenCVtry/Libraries/jsoncpp-master/include
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
LOCAL_MODULE := libXYZ
LOCAL_SRC_FILES := androidClass.cpp main.cpp utils.cpp
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
I have no idea of how to do this.
Thank you in advance.
EDIT it's not the NDK Compiling's fault.
Even if I compile the JsonCpp, I get the
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZN4Json6WriterD2Ev" referenced by "libXYZ.so"...
EDIT My jsoncpp/Android.mk :
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CPP_EXTENSION := .cpp LOCAL_MODULE := libJsoncpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/jsoncpp/include
LOCAL_SRC_FILES := src/lib_json/json_reader.cpp \
src/lib_json/json_value.cpp \
src/lib_json/json_writer.cpp
include $(BUILD_SHARED_LIBRARY)
You're not linking against Jsoncpp in your makefile. You should add the following line:
LOCAL_SHARED_LIBRARIES := libJsoncpp
before the last include $(BUILD_SHARED_LIBRARY).
You must specify module names for this variable (and its sister LOCAL_STATIC_LIBRARIES), that is, what you specified for the LOCAL_MODULE variable.
Also, that spares you from specifiying the includes in the LOCAL_C_INCLUDE variable (as the makefile will include them directly when specifying the library in the variable I mentioned at the top of my post).
EDIT: For the sake of completeness, I'll add that you can specify multiple libraries like that:
LOCAL_SHARED_LIBRARIES = libJsoncpp \
libOpenCV \
...
and the same goes for LOCAL_STATIC_LIBRARIES.
I have two projects. The output of first one is libtest.so file. Using this shared object file in the 2nd project, i want to generate final android executable, AndroidExe.
I generated libtest.so and its Android.mk is given below
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS := -g
LOCAL_ARM_MODE := arm
LOCAL_MODULE :=test
LOCAL_SRC_FILES := test.c
export LD_LIBRARY_PATH=/data/local/tmp
include $(BUILD_SHARED_LIBRARY)
Here the problem i am facing is that, i don't know how to link this .so file in my final executable project. In this final project, i am using one of the function (sum(a,b)) defined in the .so lib.While do build, showing error undefined reference to 'sum'.Its Android.mk file is given below:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS := -g
LOCAL_ARM_MODE := arm
LOCAL_MODULE :=AndroidExe
LOCAL_SHARED_LIBRARIES := libtest.so
LOCAL_SRC_FILES := AndroidExe.c
include $(BUILD_EXECUTABLE)
just check ndk documentation and try some of the samples.
Trying to build a static NDK library using Android's ADT Eclipse tool chain. However, whenever I build with BUILD_STATIC_LIBRARY, no output is produced: I get the message
make: Nothing to be done for `all'."
Any recommendations?
LOCAL_PATH := $(call my-dir)
STL_PATH := "C:/Android/ndk/sources/cxx-stl/gnu-libstdc++/4.6/include"
PLATFORM_INCLUDE := "C:/Android/ndk/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/include"
APP_STL := gnustl_static
include $(CLEAR_VARS)
LOCAL_MODULE := libCore
LOCAL_CPPFLAGS += -std=c++11 -fexceptions -D_OS_ANDROID
LOCAL_LDLIBS := -lGLESv2 -lEGL -lstdc++
LOCAL_C_INCLUDES += $(LOCAL_PATH)/Headers
...
LOCAL_SRC_FILES += Source/Engine/Game.cpp
...
include $(BUILD_STATIC_LIBRARY)
Here is the content of Android.mk file of two-libs sample project from Android NDK.
LOCAL_PATH:= $(call my-dir)
# first lib, which will be built statically
#
include $(CLEAR_VARS)
LOCAL_MODULE := libtwolib-first
LOCAL_SRC_FILES := first.c
include $(BUILD_STATIC_LIBRARY)
# second lib, which will depend on and include the first one
#
include $(CLEAR_VARS)
LOCAL_MODULE := libtwolib-second
LOCAL_SRC_FILES := second.c
LOCAL_STATIC_LIBRARIES := libtwolib-first
include $(BUILD_SHARED_LIBRARY)
You may try building the static library as part of another shared library as shown in the example.
I just did a ndk-build on the two-libs sample project and i could see the .a file along with .so in obj\local\armeabi directory.
Edit:
By default, ndk-build will only build shared libraries and executables, and the modules they depend on. To force a build specify libCore in APP_MODULES as follows.
APP_MODULES := libCore
or in command line as
ndk-build APP_MODULES=libCore
I'm stuck getting my libraries included inside the Android NDK build.
The libraries are correctly compiled and work fine when creating a dummy cpp file and building everything with a direct g++ command in the shell.
The current Android.mk file doesn't work and throws an error that the corresponding header files (that are part of the .a files) can't be found.
How do I include prebuilt static libraries correctly?
My Android.mk file looks like this:
LOCAL_PATH := $(call my-dir)
# V8 Base
include $(CLEAR_VARS)
LOCAL_MODULE := v8_base
LOCAL_MODULE_FILENAME := v8_base_static
LOCAL_SRC_FILES := ../lib/libv8_base.a
include $(PREBUILT_STATIC_LIBRARY)
# V8 Nosnapshot
include $(CLEAR_VARS)
LOCAL_MODULE := v8_nosnapshot
LOCAL_MODULE_FILENAME := v8_nosnapshot_static
LOCAL_SRC_FILES := ../lib/libv8_nosnapshot.a
include $(PREBUILT_STATIC_LIBRARY)
# V8GL Runtime
include $(CLEAR_VARS)
LOCAL_MODULE := v8gl-runtime
LOCAL_SRC_FILES := main.c ../src/v8gl/v8gl.cpp
LOCAL_CPPFLAGS := -D__ANDROID__
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := android_native_app_glue v8_base v8_nosnapshot
# LOCAL_EXPORT_CPPFLAGS := -D__ANDROID__
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
The compiler output is the following, which makes sense, but only shows me that there is no single .a file included and I don't know why:
Compile++ thumb : v8gl-runtime <= v8gl.cpp
(... g++ call)
In file included from jni/../src/v8gl/v8gl.cpp:6:
jni/../src/v8gl/v8gl.h:5:16: error: v8.h: No such file or directory
SOLUTION with absolute path
Thanks to the hint of #alex-cohn I found out that the includes were falsely pointed out.
So I decided to use an environment variable that is set before calling ndk-build that contains the absolute path. That fixes the problem with the includes.
So the last Module, where the actual inclusion is done, is now looking like:
ADK_PATH=/var/whatever/to/your/project/root_not_jni
include $(CLEAR_VARS)
LOCAL_MODULE := v8gl-runtime
LOCAL_SRC_FILES := main.c ../src/v8gl/v8gl.cpp
LOCAL_C_INCLUDES:= $(ADK_PATH)/external/v8/include
LOCAL_CPPFLAGS := -D__ANDROID__
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := android_native_app_glue v8_base v8_nosnapshot
Now it also shows that the libraries are included, because they are compiled afterwards - for whatever reason.
SOLUTION with relative path
All include paths are relative to the project root folder and not the jni folder. That means it will land as a compiler -I flag as something like this:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../file_in_project.root
# resulting g++ flag:
-Ijni/../file_in_project.root
So there's a difference between the relative include paths and the LOCAL_SRC_FILES, which are relative to the jni folder!
You probably have file v8.h in directory ../include or somewhere else...
You should add line
LOCAL_C_INCLUDES = $(LOCAL_PATH)/../include
Note that unlike LOCAL_SRC_FILES where you don't need $(LOCAL_PATH), here you must put the full paths of all directories where the necessary .h files are.