I've built an AOSP system service following this tutorial:
http://www.androidenea.com/2009/12/adding-system-server-to-android.html
Now I want to use a pre-compiled .so file and cannot figure out where to put it so my code will be able to access it.
so, i created a folder at framewaork/base/libs/my_folder/
and put there two files:
my_lib.so
android.mk
the content of the android.mk is :
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= my_lib
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
the make ran without errors, but when the code tried to load the library via:
System.loadLibrary("my_lib");
i got this error:
06-27 13:58:55.581: E/AndroidRuntime(806): Caused by: java.lang.UnsatisfiedLinkError: Library my_lib not found; tried [/vendor/lib/my_lib.so, /system/lib/my_lib.so]
so i added the so file to out/target/product/generic/system/lib
but got the same error.
so where should i place the my_lib.so file ? and is an android.mk needed for it ?
maybe i should register it somewhere on the system ?
Thanks in advance!
So the answer was quite simple.
I really need to copy my lib to the system image, to the system/lib folder, because the make command doesn't copy it from out/target/product/generic/system/lib to system.img
the trick is to add this line
PRODUCT_COPY_FILES += $(LOCAL_PATH)/my_lib.so:system/lib/my_lib.so
to full.mk file. it's location is:
android-source/build/target/product
also put the my_lib.so near it
(as seen by the path)
if you are planning to run the image on a real device, add this line after the device name definition.
f.ex. if you are running on Nexus 4, put it at android-source/device/lge/mako/full_mako.mk
You can add your prebuilt library in Android AOSP source code and it be a part of your AOSP System Image. I am describing step by step procedure for it.
Step 1 Create a folder ( let say myLibs) inside external folder of AOSP source code.
external folder of AOSP source code refers to external open source libraries.
That means libraries that the Android platform depend upon but that are not primarily developed and maintained by the Android open source project.
examples are webkit for the browser, FreeType for fonts, SqlLite for databases and so on. As more features are added to Android, more of these libraries are included in external.
Step 2 Create a Android.mk file
Create a Android.mk file inside your folder(let say myLibs) and copy your .so file in it.
You can use following content for your android.mk file
# Prebuilt Lib
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libMyabc # your lib name
LOCAL_SRC_FILES := libMyabc.so
# your lib .so file name
include $(BUILD_SHARED_LIBRARY)
Step 3 Add your library in Framework
In final step you have to add your library in Android AOSP framework makefile so that it will recognise and build as a part of System image.
You find Framework Android.mk file on following location
/android_aosp_sourcecode_download_folder/framenter code hereeworks/base/core/jni/
Open Android.mk file and add your library in following section
LOCAL_SHARED_LIBRARIES := \
You can put your library name in that section example libMyabc \
That's it... now make it (make -j4) and you find your added so file in following folder
/android_aosp_sourcecode_download_folder/out/target/product/generic/obj/lib
with file name like :- libMyabc.so and libMyabc.so.toc
and you also found it in system/lib folder
/android_aosp_sourcecode_download_folder/out/target/product/system/lib
in my case, solved this problem by creating Android.bp file in the repo where i put my prebuilt libraries, then i added them as product packages in the product mk file. this is an example :
Android.bp :
cc_prebuilt_library {
name: "product_package_name_in_MK_file",
relative_install_path: "sub_lib/sub_sub_lib",
stem: "output_file_name", // .so will be added automatically to out file name.
compile_multilib: "both",
multilib: {
lib32: {
srcs: ["path for src 32bit lib"],
},
lib64: {
srcs: ["path for src 64bit lib"],
},
},
strip: {
none:true,
},
allow_undefined_symbols: true,
check_elf_files: false,
vendor: true,
enabled: true,
}
product_mk file :
...
PRODUCT_PACKAGES += product_package_name_in_MK_file
...
Related
I wish to use jsoup library in Android Open Source Project.
For this I did two things:-
Step 1:
Made a directory jsoup in common as follows: [android]prebuilts/misc/common/jsoup/
In this jsoup folder I added jsoup-1.13.1.jar downloaded from : https://jsoup.org/download
In this same jsoup folder I added another file Android.mk {as it is name and code below:}
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jsoup
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := jsoup-1.13.1.jar
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
LOCAL_DEX_PREOPT := false
include $(BUILD_PREBUILT)
Step 2:
Go to another make file as follows : [android]/frameworks/base/Android.mk
In this Android.mk file I added following line shown below (after the LOCAL_JAVA_LIBRARIES variable is set):
LOCAL_STATIC_JAVA_LIBRARIES += jsoup
Problem:
I have added a file sample.java as follows-
[android]frameworks/base/services/core/java/com/android/server/am/sample.java
In this sample.java file I have import statements as follows-
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
When I build this whole modified android code, I get the following error and the build fails:
frameworks/base/services/core/java/com/android/server/am/sample.java:48: error: package org.jsoup does not exist
frameworks/base/services/core/java/com/android/server/am/sample.java:49: error: package org.jsoup.nodes does not exist
frameworks/base/services/core/java/com/android/server/am/sample.java:50: error: package org.jsoup.select does not exist
I even tried using a method mentioning Android.bp instead of Android.mk but same build error.
Also I am confused in naming of jar file as import statement includes org.jsoup... but jar file itself is just jsoup. (Do I have to change import statement like import jsoup ... or change name of jar file to org.jsoup...)
Any other method other than involving Android.mk or Android.bp is also highly acceptable.
Please, I have no idea of including external jar files in AOSP. The code works fine locally in IntelliJ IDE Java otherwise. Any help is deeply appreciated. Thanks in advance.
You can base your solution on some other jar already added in AOSP.
For example see ZXING library's Android.bp in external/zxing/:
java_import {
name: "zxing-core-1.7",
host_supported: true,
installable: false,
jars: ["core.jar"],
}
Then see the usage on another Makefile: :
LOCAL_STATIC_JAVA_LIBRARIES := \
androidx-constraintlayout_constraintlayout-solver \
androidx.lifecycle_lifecycle-runtime \
androidx.lifecycle_lifecycle-extensions \
guava \
jsr305 \
carsettings-contextual-card-protos-lite \
carsettings-log-bridge-protos-lite \
carsettings-logtags \
statslog-settings \
zxing-core-1.7
Lastly, based on the path of the file you're adding frameworks/base/services/core/java/com/android/server/am/sample.java, you're adding the library to the wrong makefile.
The one you changed (frameworks/base/Android.mk) is for making framework.jar, whereas you're trying to add a class on services.jar
The correct makefile to modify would be: frameworks/base/services/core/Android.bp
Based ENTIRELY upon Answer provided by #RickSanchez, I followed these steps as guided by his answer to bring up a successful build:
Made a directory: [android]prebuilts/misc/common/jsoup/
In this directory jsoup folder, I included a blueprint file Android.bp and jsoup-1.13.1.jar downloaded from https://jsoup.org/download
With the help of Blueprint Soong Flag descriptions info here,
I created my Android.bp talked above as follows:
Android.bp
java_import {
name: "jsoup-1.13.1",
host_supported: true,
installable: false,
jars: ["jsoup-1.13.1.jar"],
}
Next task was to give ref of above created Local Blueprint file to Android.bp present in frameworks/base/services/core/Android.bp
To this, I made the following edit:
In Android.bp either add the following if present or modify the following block -
static_libs: [
"jsoup-1.13.1", /*use jsoup lib */
"android.hardware.authsecret-V1.0-java",
....
....
],
The build is now successful and the sample.java is successfully able to use jsoup library
I'm struggling with this for several days now. At the moment i'm just testing it with a simple C++ project (1 .h & 1 .cpp file) and a minimalistic App including the ndk helloJNI sample code (which worked perfect easily):
Target
Import existing C/C++ files (project) to Android Studio
Approach
After trying out some of the (dozens) of different possibilities, i think/thought the following steps would be the best solution for my purpose:
Create the shared library (Calculator.so) from Visual Studios 2015 "Create shared library for Android" (or something) [successful]
Create jniLibs folder in src/main/ with its subfolders (x86 the relevant one in my case)
Add the Android.mk file in src/main/jniLibs which has to be placed there (?)
Include statement: System.loadLibrary("Calculator") without "lib" and ".so" in MainActivity
The library is listed in Android Studio in its folder jniLibs as like the Android.mk. Moreover if i build the apk, the library is successfully packed (verified by unzipping) and i dont get any errors.
BUT: how can i call the methods in the library? I tried the different solutions offered in other threads, but i think i missed something in my .mk or my steps described above.
Tried
Different #include <myLib> statements in native-lib.cpp, like s
Different Android.mk settings (but i'm new to make files so not even tutorials helped me much with my specific problem ::) )
Other locations for the libCalculator.so like in the subfolder x86
and many others - simply not reminding atm (wasntme)
Your help is highly appreciated!
Android.mk
LOCAL_PATH := $(call my-dir)
APP_ABI := x86
# library info
include $(CLEAR_VARS)
LOCAL_MODULE := Calculator
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/Calculator.so
LOCAL_EXPORT_C_INCLUDES := ..../Visual Studio 2015/Projects/SO_Library/SO_Library
include $(BUILD_SHARED_LIBRARY)
There are lots of things, you can do in Android NDK. For example, Camera hardware is one of the heaviest hardware in Android OS. Detecting faces, things, giving effects and for thousands of features NDK is the best.
Some helps for your steps:
You can built and prebuilt shared(.so) and static(.a) libraries in Android Studio also. Not need Visual Studio.
Don't create jniLibs folder in main folder. When you build your project via gradle, it already creates this folder and put your target libraries. If you want prebuilt any libraries, put these libraries in main/jni/libs folder and prebuilt then with Android.mk.
Don't add the Android.mk file in jnilibs folder. Create this file in main/jni folder. Also Application.mk file.
Call your libraries, in any activity, where you need, in static method. Like this:
static { System.loadLibrary("my_library") }
Without "lib" and ".so" extensions.
When you want to call your native methods, just use "native" keyword. For example:
private native int nGetNumberFromNativeSide();
Just call this method, where you want, and get result. But for ndk building in gradle side, look at this answer. For building library in Android.mk, these sample lines maybe help you:
include $(CLEAR_VARS)
ifneq (,$(filter $(TARGET_ARCH_ABI), armeabi-v7a x86 arm64-v8a x86_64))
LOCAL_MODULE := my_library
LOCAL_SRC_FILES := $(LOCAL_SRC_LOCATION)/native1.cpp native2.cpp
include $(BUILD_SHARED_LIBRARY)
You can put name anything you want, but dont add lib and .so extensions. Ndk is already doing it.
I have already gave Android.mk example.
When you build Android.mk file, it locates your libraries appropriate folder. Like main/libs/x86/libmy_library.so.
I guess this answer will help you. If you have more questions, add to comment, i'll edit my answer and add answers.
I'm having trouble refactoring some make files into manageable modules.
Following is the structure I try to accomplish:
jni/Android.mk
jni/Application.mk
jni/libobj/Android.mk
jni/libpng/Android.mk
jni/libzip/Android.mk
jni/freetype/Android.mk
jni/ftgles/Android.mk
jni/qcar/Android.mk
jni/imagetargets/Android.mk
Note: I started from the Vuforia SDK ImageTargets example and added
some other libraries like reading OBJ, PNG and ZIP files. I've also
included the freetype and ftgles library.
I call the other make files from my the root Android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include jni/libobj/Android.mk
include jni/libpng/Android.mk
include jni/libzip/Android.mk
include jni/freetype/Android.mk
include jni/ftgles/Android.mk
include jni/qcar/Android.mk
include jni/imagetargets/Android.mk
You can see all make files in a gist on github.
The compiler gives following error:
Install : libFTGLES.so => libs/armeabi/libFTGLES.so Compile++
arm : ImageTargets <= ImageTargets.cpp
jni/imagetargets/ImageTargets.cpp:44:24: fatal error: libpng/png.h: No
such file or directory compilation terminated. make: *
[obj/local/armeabi/objs/ImageTargets/ImageTargets.o] Error 1
Any idea how to make the libpng (and other modules) headers available for the imagetargets module?
I think that specifying the path to the includes in each sub-makefile using LOCAL_EXPORT_C_INCLUDES would ensure that the headers are available when building the final module.
Check the documentation for this flag in the NDK documentation (available in your NDK directory), but from what I understand, it will do exactly what you're trying to do: automatically export the include path of each sub-module to the final module.
I have written C++ file in JNI folder of my application. I am using Windows system with NDK and Cygwin 1.7.I want reffer to CURL library available in Cygwin.How can we refer to external .h(libraries/header) files while creating JNI application in Android?I have created a combined Android and C++ project. But I am referring CURL header file. When I build the project I am getting fatal error: curl/curl.h: No such file or directory issue.
Follow these steps:
Converting from Android project to C/C++ project:
Right click on your project name, go to 'Android Tools' and click 'Add native support'
Adding paths to external .h files:
Right click on your project name, go to 'Properties', under 'C/C++ General', go to 'Paths and Symbols', under 'Includes' tab, add the folder in which your .h file is. Remember to add to all languages and configurations if asked.
Also, since you are in Windows, I think you will need to change your Build command (which is in the 'C/C++ Build' section in project properties) to "bash C:\Development\android-ndk-r8\ndk-build.cmd"
Add the following to your Android.mk:
LOCAL_CFLAGS += -I$/PATH/TO/YOUR/curl.h
LOCAL_LDLIBS += -L$/PATH/TO/YOUR/libcurl.a.for.android -lcurl
The libcurl.a you have installed in cygwin is not usable for android, you need a version targetting android. If you don't have it, build it yourself.
When you get that libcurl.a file, do not forget to copy the headers folder of curl (get into your usr/include/curl from Cygwin) and add this folder to the JNI one in your project, so it knows the headers while compiling.
Which means also referring in your Android.mk :
for the libcurl library
LOCAL_SRC_FILES := libcurl.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/curl
and for your C++ files
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/curl
LOCAL_WHOLE_STATIC_LIBRARIES := libcurl
Please used this tutorial is nice one.
Don't forgot to change this setting after convert project to C / C ++ native project.
Builder Settings to Build Command
bash C:\tools\android-ndk-r8b-windows\android-ndk-r8b\ndk-build
This is my path of NDK you can change this path accordingly your NDK path.
I am facing issues in using an external shared library in my Android application. I created an Android.mk file as given below:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyApp
LOCAL_SRC_FILES := myexternallib.so
include $(PREBUILT_SHARED_LIBRARY)
Using ndk-build I am able to generate a local native library and I use this native library in my System.loadLibrary method.
When I run the application I get an error java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1486]: 2659 unknown reloc type 19 # ( 4220)
On further search I found a link which recommends to build the shared library using the android toolchain. So I used one of the toolchain arm-eabi-gcc, which is available in the prebuilt/linux_x86/toolchain/arm-eabi-4.4.3/bin directory of the android source code, to build my source files. I get an error arm-eabi-gcc: error trying to exec 'cc1': execvp: No such file or directory. I also noticed that the toolchain folder does not have a file named cc1.
Am I following the right procedure? Is there some other way to reference external shared library in Android code?
It is true that you should use Android toolchain.
Android NDK comes with detailed instructions on using its toolcahin: http://source-android.frandroid.com/ndk/docs/STANDALONE-TOOLCHAIN.html. If you have specific questions about this document, feel free to ask.