How to include util-linux in AOSP? - android

How do I include util-linux from here in AOSP? Where should I add this util-linux folder in AOSP so that I can build AOSP and these utils could be added in /system/bin/ or /system/xbin/? And is there any specific Makefile or Android.mk that I need to make it to compile with Android build?

I have added an application from util-linux package in AOSP.
Here's how I did it. I added the util-linux (2.34) from https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.34/util-linux-2.34.tar.gz in external of AOSP folder.
I just wanted to add chrt from util-linux. Therefore, I run the normal make command in util-linux to see what files are compiled for chrt. I took a note and created an Android.mk accordingly. I am sure there's a better way to do it hierarchically by making the library first and then make the chrt executable. However, this works too.
I added the following Android.mk at external\util-linux\. The Android.mk looks like the following:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sohamchrt
LOCAL_SRC_FILES := schedutils/chrt.c lib/blkdev.c lib/canonicalize.c \
lib/crc32.c lib/crc32c.c lib/idcache.c lib/fileutils.c \
lib/ismounted.c lib/color-names.c lib/mangle.c lib/match.c lib/mbsalign.c \
lib/mbsedit.c lib/md5.c lib/pager.c lib/parse-date.c lib/pwdutils.c lib/randutils.c \
lib/setproctitle.c lib/strutils.c lib/timeutils.c lib/ttyutils.c lib/exec_shell.c \
lib/strv.c lib/sha1.c lib/signames.c lib/linux_version.c lib/loopdev.c \
lib/plymouth-ctrl.c lib/cpuset.c lib/path.c lib/procutils.c lib/sysfs.c
LOCAL_CFLAGS = -DHAVE_NANOSLEEP -include config.h \
-isystem bionic/libc/upstream-openbsd/android/include
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_EXECUTABLE)
Now, when I run m -j8 iso_img, then Android tries to compile sohamchrt. I named the package sohamchrt because chrt is already provided by toybox which have limitations.
The problem is util-linux is not fully compatible with bionic. So, I needed to make some changes to some .c and .h files such as fileutils.c, include/c.h, etc.
After successful compilation, the binary sohamchrt appears in /system/bin when Android is running, and it works with no issues.
This is also a guide on how you can add a C source file for a userspace executable binary in AOSP.

It's always worth checking whether a library you want to add already exists at https://android.googlesource.com/. In your case, unfortunately, it does not.
As util-linux does not come with an Android.bp. You will have to understand how util-linux is built and how Soong works to create a custom Android.bp for integration. The correct folder to place it would be external/util-linux/.
Maybe you will want to take a shortcut and just add util-linux as prebuilt binaries. That will reduce the effort.
Please check licensing issues first, though.

Related

Is it possible to know the value of LOCAL_SRC_FILES before compiling starts?

I'm completely new to Android development, but I'm facing this problem. We have an Android application project. It uses Android.mk and there are some ifeq...else...endif clauses which assign different values to LOCAL_SRC_FILES.
Is it possible, with a command or a tool, to know the value of LOCAL_SRC_FILES before compiling starts, given that the compiling environment has been initialized?
Yes, kind of. You could add a rule that prints LOCAL_SRC_FILES and run make on that, e.g. make print_local_src_files with this in makefile:
print_local_src_files:
#echo $(LOCAL_SRC_FILES)
If you can't or won't edit Android.mk, you can source multiple makefiles in a single make invocation:
make -f Android.mk -f print.mk print_local_src_files

How to use a custom toolchain with ndk-build?

I've spent a day on this and can't seem to configure my dev environment for a NDK toolchain that will support standard C++ libraries. The story is I'm trying to cross compile libnfnetlink and libnetfilter_queue for ARM (Android).
First I'm using the following:
Nexus 5 with CyanogenMod 11 (I forget, doesn't matter I'm not even on the device yet)
Ubuntu 12.04 32-bit
Android SDK bundle: adt-bundle-linux-x86-20140702
Android NDK: android-ndk-r10c
There is a great blog on doing this here but its incomplete as Netfilter uses stlc++ and there's no word on a NDK install/setup that would work with simply calling ndk-build. Just copying the files into /jni and calling ndk-build won't work alone.
Anyways, my specific problem is when I straight copy the Netfilter lib source structure into an empty Project's /jni directory, I get this:
user#ubuntu:~/Projects/NetfilterTest/NetfilterNativeTest/jni$ ndk-build
[armeabi] Compile thumb : netfilter_queue <= libnetfilter_queue.c
In file included from /home/user/Projects/NetfilterTest/NetfilterNativeTest/jni/libnetfilter_queue/src/libnetfilter_queue.c:35:0:
/home/user/Projects/NetfilterTest/NetfilterNativeTest/jni/libnetfilter_queue/src/internal.h:4:20: fatal error: config.h: No such file or directory
compilation terminated.
make: *** [/home/user/Projects/NetfilterTest/NetfilterNativeTest/obj/local/armeabi/objs/netfilter_queue/libnetfilter_queue/src/libnetfilter_queue.o] Error 1
The config.h file can't be found. After some googling I realize its because the standard C++ libraries aren't available in the prebuilt tool chains.
Everything points to me creating my own tool chain. So I build my own cross compiler using the scripts that the NDK includes.
cd /home/user/android-ndk-r10c/build/tools
./make-standalone-toolchain.sh --platform=android-19 --ndk-dir=/home/user/android-ndk-r10c/ --install-dir=/home/user/android-ndk-r10c/prebuilt/android-arm/android-19
To confirm that config.h is included in my tool chain I searched for it. It's there:
user#ubuntu:~/Projects/NetfilterTest/NetfilterNativeTest/jni$ find /home/user/android-ndk-r10c/prebuilt/android-arm/android-19/ -iname config.h
/home/user/android-ndk-r10c/prebuilt/android-arm/android-19/sysroot/usr/include/linux/config.h
Naturally I need to setup my environment and the Android.mk
JAVA_HOME=/usr/local/java/jdk1.6.0_45
JRE_HOME=$JAVA_HOME/jre
ANDROID_SDK=/home/user/adt-bundle-linux-x86-20140702
ANDROID_NDK=/home/user/android-ndk-r10c
ANDROID_CHAIN=/home/user/android-ndk-r10c/prebuilt/android-arm/android-19
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin:$ANDROID_SDK/sdk/platform-tools:$ANDROID_SDK/sdk/tools:$ANDROID_NDK:$ANDROID_CHAIN/bin
SYSROOT=$ANDROID_NDK/platforms/android-19/arch-arm
CC=arm-linux-androideabi-gcc
export CC
export ANDROID_SDK
export ANDROID_NDK
export SYSROOT
export JAVA_HOME
export JRE_HOME
export PATH
Here's my Android.mk (based on Roman10's blog:
LOCAL_PATH:=$(call my-dir)
#####################################################################
# build libnflink #
#####################################################################
include $(CLEAR_VARS)
LOCAL_MODULE:=nflink
LOCAL_C_INCLUDES:= $(LOCAL_PATH)/libnfnetlink/include
LOCAL_SRC_FILES:=\
libnfnetlink/src/iftable.c \
libnfnetlink/src/rtnl.c \
libnfnetlink/src/libnfnetlink.c
include $(BUILD_STATIC_LIBRARY)
#####################################################################
# build libnetfilter_queue #
#####################################################################
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libnfnetlink/include \
$(LOCAL_PATH)/libnetfilter_queue/include
LOCAL_MODULE:=netfilter_queue
LOCAL_SRC_FILES:=libnetfilter_queue/src/libnetfilter_queue.c
LOCAL_STATIC_LIBRARIES:=libnflink
include $(BUILD_STATIC_LIBRARY)
#####################################################################
# build our code #
#####################################################################
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libnfnetlink/include \
$(LOCAL_PATH)/libnetfilter_queue/include
LOCAL_MODULE:=nfqnltest
#LOCAL_LDLIBS:=-lstdc++
LOCAL_SRC_FILES:=nfqnl_test.c
LOCAL_STATIC_LIBRARIES:=libnetfilter_queue
LOCAL_LDLIBS:=-llog -lm
include $(BUILD_EXECUTABLE)
I still get config.h not found using ndk-build.
I've read that the ndk-build command leverages a config.mk/setup.mk that Google includes in the NDK and has to be modified to point to an alternative toolchain.
I'm completely floored that Google's own tools can't simply point to a custom toolchain that they give you scripts to create. If anyone has any suggestions on how I can use my toolchain to compile Netfilter or just in general it would be a great help.
Thanks in advance!
I can't find any reference to either internal.h or config.h when I search for a version of libnetfilter_queue.c on the web, so I'm not sure what version of the file you're using - can you point to which one you have?
Also, the config.h it looks for isn't the one you found in your toolchain (which should be included as linux/config.h) but most probably is one that you're expected to generate by running a configure script. So unless you've run the configure script (or have a pregenerated config.h from elsewhere) you can't really build it.
Finally, nothing of this has anything to do with libstdc++ since all your source files seem to be pure C, not C++.

Adding prebuilt set of files structured in folders to android out folder

I have glibc compiled for arm which is different from Android glibc or the bionic C as the glibc environment I have complied will help in providing more api's.
Now I can copy the glibc environment on /system/ folder while Android is running, and on doing chroot I can run my programs on glibc environment.
Currently I am compiling glibc and Android separately and then tarring the glibc and copying it on Android emulator sdcard and then untarring it on /system folder and then doing chroot on /system/glibc
I compile glibc separately and then place it somewhere in Android source code.
Now while compiling Android source, what should I do so that the entire prebuilt folder structure of glibc gets copied to /system folder and become part of part of system.img.
With this when I copy the system.img to Android emulator and launch it, glibc is already present in /system folder and just need to run the apps in glibc environment.
UPDATE
after I did as per Yuri mentioned in his answer (I created glibc folder and copied everything into it), when I compile the code I get below output.
build/core/main.mk:490: * Some files have been added to ALL_PREBUILT.
build/core/main.mk:491: *
build/core/main.mk:492: * ALL_PREBUILT is a deprecated mechanism that
build/core/main.mk:493: * should not be used for new files.
build/core/main.mk:494: * As an alternative, use PRODUCT_COPY_FILES in
build/core/main.mk:495: * the appropriate product definition.
build/core/main.mk:496: * build/target/product/core.mk is the product
build/core/main.mk:497: * definition used in all products.
build/core/main.mk:498: *
build/core/main.mk:499: * unexpected glibc in ALL_PREBUILT
build/core/main.mk:500: *
build/core/main.mk:501: * ALL_PREBUILT contains unexpected files. Stop.
So I added glibc in build/core/legacy_prebuilts.mk
But then I get
make: * No rule to make target mkdir', needed byout/target/product/generic/root/glibc'. Stop.
Finally I did it in a very unusual way.
I had 3 options:
Use BUILD_PREBUILT variable, but drawback it you can do it for a
single file, but I had multiple files and in a particular forlder
structure
Use PRODUCT_COPY_FILES. But somehow it was not working for me
PRODUCT_COPY_FILES is for a device, and it was not a new device for
me. I was working on emulator.
Using the solution given by Yuri, using ALL_PREBUILT +=, but as Yuri
mentioned it was for GB and I am using JB and ICS and hence was not
working for me.
The approach i took is to use shell script within the Android.mk file.
I used some like this:
Assume you have a folder named my_folder containing entire prebuilt folder structure which needs to be copied to anddroid out folder as is, inside my_folder, I created Android.mk and entered below text:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
$(shell mkdir -p $(TARGET_OUT)/my_folder/)
$(shell cp -rf $(LOCAL_PATH)/* `pwd`/$(TARGET_OUT)/my_folder/)
This way all my prebuilt set of files and folders in my_folder directory were copied as is to system folder in android out.
I hope this helps someone.
PRODUCT_COPY_FILES must be placed in product mk files (device/mydevice/..), not module files (Android.mk). This is mentioned here.
This format is used for copying dirs:
PRODUCT_COPY_FILES += $(call find-copy-subdir-files,*,vendor/mydir,system/app)
This command is not working for apk files though, giving error:
build/core/Makefile: *** Prebuilt apk found in PRODUCT_COPY_FILES: vendor/mydir/ray-system-ui-release.apk:system/app/ui-release.apk, use BUILD_PREBUILT instead!. Stop.
Here is an example from the book "Embedded Android" that will help you. Create a folder in the root of your aosp project called rootfs-glibc, put there the code that you want to copy, and create there Android.mk file with the following content:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# This part is a hack, we're doing "addprefix" because if we don't,
# this dependency will be stripped out by the build system
GLIBC_ROOTFS := $(addprefix $(TARGET_ROOT_OUT)/, rootfs-glibc)
$(GLIBC_ROOTFS): mkdir -p $(TARGET_ROOT_OUT) cp -af $(TOPDIR)rootfs-glibc/* $(TARGET_ROOT_OUT) rm
# The last command just gets rid of this very .mk since it's copied as-is
ALL_PREBUILT += $(GLIBC_ROOTFS)
There is a note that this is true for Gingerbread. Maybe in newer versions of Android the make system has been changed.
Consider using a PHONY_PACKAGE with a custom installation step.
Unlike the $(shell cp whatever) answer above, this will only run during the installation step, rather than on every Make step (which is certainly not what you want).
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := some_module
LOCAL_ADDITIONAL_DEPENDENCIES := FORCE # Decide if you need this
LOCAL_POST_INSTALL_CMD = cd $(LOCAL_PATH) && cp -a mystuff $(TARGET_OUT_WHATEVER)
include $(BUILD_PHONY_PACKAGE)
I was thinking if I could do this way
1. I have both android and glibc compiled separetely.
2. Once both are compiled, I manually copy the glibc entire folder to /out/target/product/generic/system/glibc/ folder
3. Then I run "make snod"
Would that work?

How to use Existing .so file in android application [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I was searching for library which should convert .doc/.docx to .pdf in android platform.
I got PdFTron android sdk,in that they have given libPDFNetC.so file.
For Conversion, there is class called Convert, inside that there is a method toPDF(),
in that method they have internally called native method FileToPdf().I tried that code but unable to call that native method and was getting errors
I want to know that if there is existing .so file present with you and if you want to call native method which is present in .so file then is there need to use JNI?. i dont know much about JNI. any help.
You have to link your final shared library that is generated by the Android NDK using the ndk-build to the PDF shared library you said you already have compiled for the ARM architecture.
(Ensure that this is the case, otherwise the library won't work on Android!)
For that, if for example you have the following directory structure:
jni
└── libs
└────── my_shared_lib.so
└── Android.mk
└── Application.mk
You need to have the following content inside the Android.mk file:
LOCAL_PATH := $(call my-dir)
# define our prebuilt shared library as a module to the build system
include $(CLEAR_VARS)
LOCAL_MODULE := mysharedlib
LOCAL_SRC_FILES := libs/my_shared_lib.so
include $(PREBUILT_SHARED_LIBRARY)
# The final shared library that will be bundled inside the .apk
include $(CLEAR_VARS)
LOCAL_MODULE := mynativelib
LOCAL_LDLIBS := -landroid -llog
LOCAL_CPPFLAGS := -O0 -g3 -std=c++11 -Wall -Wextra
LOCAL_SHARED_LIBRARIES := mysharedlib
LOCAL_C_INCLUDES := myheader1.h myheader2.h
LOCAL_SRC_FILES := src_file1.cpp src_file2.cpp
include $(BUILD_SHARED_LIBRARY)
and the contents of the Application.mk file (for using the C++ Standard Library, and build the the final shared library for two different versions of the ARM architecture):
APP_OPTIM := debug
APP_PLATFORM := android-14
APP_STL := gnustl_static
APP_ABI := armeabi armeabi-v7a
Then after you compile your code from within Eclipse or from the command line using the ndk-build script it'll compile you final shared library and link it against your prebuilt shared library (i.e. the PDF shared library you said you are trying to use).
For shared libraries the apk that is generated and deployed to the device/emulator contains the final shared library as well as all the prebuilt shared libraries you linked against, in contrast with linking against static libraries which are not bundled inside the apk.
For your use case you should have two shared libraries in the lib directory of your Android application after the apk is unpacked on the device.
You can check this by running the following command from a terminal:
adb shell ls -l /data/data/com.company.myapp/lib
Replace com.company.myapp with your application's package name.
Also, don't forget to put the following inside a static context of a Java class:
class MyClass
{
static
{
try
{
System.loadLibrary("mynativelib");
}
catch (UnsatisfiedLinkError ule)
{
Log.e(TAG, "WARNING: Could not load native library: "
+ ule.getMessage());
}
}
// other code here...
}
Notice the use of the same name inside the System.loadLibrary method call as the final shared library name.
You need to make sure the .so file that maps to the native interface is available on your system, and can be found by Java.
There should be a call like System.loadLibrary("<libraryname>") or System.load("/path/to/libs/lib<libraryname>.so") somewhere in your Java code.
That will instruct the JVM to search for the library with the given name and load it.
System.load("/path/to/libs/lib<libraryname>.so") will just look for the file specified as argument, and load it.
System.loadLibrary("<libraryname.") will look in the configured library path for a library with the name lib<libraryname>.so . The library path is taken from the system variable java.library.path .
Also make sure that the library version you are loading is compatible with the Java JNI mapping!
To work on ndk , there is a .mk (make file) that is complied under JNI to get the .so file.
.mk file is written in the native code using the c /c++ snippet.
Now to compile using JNI , there are the two common ways:
1.While working old ADT + SDK versions:
You would require a linux environment to be configured on the windows configuration for running the JNI commands on shell. This environment can be achieved via various software available on net such as cygwin setup.
2.If the ADT + SDK versions that you use are updated:
Then there is a NDK pluggin available in ADT itself . So it easier to work on the ndk and native library.
For more details on NDK visit here

Problems trying to build PocketSphinx for Android using NDK

I'm trying to build PocketSphinx for Android using the PocketSphinxAndroidDemo project. I've given up om my quest to build it using Cygwin and Windows and installed an Ubuntu VM. I'm making progress but I seem to be stuck and I can't seem to figure it out. It has to be something simple that I'm missing. The ndk-build gives the following output (clipped):
Compile thumb : pocketsphinx_jni <= pocketsphinx_wrap.c
/home/user/development/PocketSphinxAndroidDemo/jni/pocketsphinx_wrap.c:760:26: error: pocketsphinx.h: No such file or directory
/home/user/development/PocketSphinxAndroidDemo/jni/pocketsphinx_wrap.c:761:28: error: sphinxbase/err.h: No such file or directory
The header files are (obviously) not in the same folder as the JNI files. The LOCAL_C_INCLUDES flag has been set in Android.mk file to include the needed headers -
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(SPHINX_PATH)/sphinxbase/include/android \
$(SPHINX_PATH)/sphinxbase/include/sphinxbase \
$(SPHINX_PATH)/sphinxbase/include \
$(SPHINX_PATH)/pocketsphinx/include
I should note that my SPHINX_PATH variable looks like this, and it's correct -
SPHINX_PATH := ~/development
If I copy the header files over into the /jni/ folder I get farther but then the compiler starts yelling at me for header files missing in other locations. Surely I'm missing something simple. Isn't there somewhere I can set a "Look in these locations for header files before blowing up" flag?
I'm not a C/C++ or a Linux guy so I'm kind of in the dark here. Any help would be greatly appreciated. Thanks!
Solved my problem. Maybe someone will find this information useful :)
What I did was a complete rebuild of all the static library projects, and then my app, using "ndk-build -B"
Modify jni/Android.mk file
Change Line 162 :
LOCAL_STATIC_LIBRARIES := sphinxutil sphinxfe sphinxfeat sphinxlm pocketsphinx
to :
LOCAL_STATIC_LIBRARIES := pocketsphinx sphinxlm sphinxfeat sphinxfe sphinxutil
That will resolve your issue.

Categories

Resources