In android, when you open a terminal emulator or connect an adb shell, there is a command service that you can execute which allows you to interact with system services to some degree. For my purposes the functionality is too limited though and I would like to expand it a little.
Unfortunately this executable is not documented.
I have located the source code here: service.cpp
There is also a file called Android.bp in the same directory with the following content:
cc_binary {
name: "service",
srcs: ["service.cpp"],
shared_libs: [
"libcutils",
"libutils",
"libbinder",
],
cflags: [
"-DXP_UNIX",
"-Wall",
"-Werror",
],
}
cc_binary {
name: "vndservice",
proprietary: true,
srcs: ["service.cpp"],
shared_libs: [
"libcutils",
"libutils",
"libbinder",
],
cflags: [
"-DXP_UNIX",
"-DVENDORSERVICES",
"-Wall",
"-Werror",
],
}
Those cflags look like g++ flags to me. I don't really know g++, but after a lot of trial and error I ended up with this:
# Download required source code
git clone https://android.googlesource.com/platform/superproject
cd superproject
git submodule init
git submodule update frameworks/native
git submodule update system/libbase
git submodule update system/core
git submodule update system/logging
# Set required include directories in CPATH
export CPATH="./frameworks/native/include:./system/libbase/include:./system/core/libcutils/include:./system/core/libutils/include:./system/logging/liblog/include:./system/core/libsystem/include:./frameworks/native/libs/binder/include"
# Build
g++ -DXP_UNIX -Wall -Werror -o service ./frameworks/native/cmds/service/service.cpp
Unfortunately I get a massive amount of errors:
https://pastebin.com/fnu7LJLU
My G++ version is:
g++ (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2)
Any ideas why this is failing?
Related
I want to build aosp native test and debug it on emulator. Is it possible to build executable with debugging symbols?
I have tried to add -g and -ggdb to Android .bp:
cflags: [
"-Werror",
"-Wall",
"-g",
],
but it didn't help, I still getting stripped executable.
In the module declaration, add:
strip: {
keep_symbols: true,
},
Reference: link.
You can find the unstripped binaries in $ANDROID_PRODUCT_OUT/symbols.
I'm trying to generate a custom android image, to run under the emulator, using a kernel version compiled by myself (the idea is to include debug symbols). I found a lot of information on google about it so I checked out the branch android-goldfish-4.14-dev, and tried to compile it a couple of times, but this crash happens any time I run the compiled kernel.
[ 0.851597] ? generic_make_request+0x123/0x300
[ 0.852314] submit_bio+0x73/0x140
[ 0.852854] ? bio_alloc_bioset+0xcc/0x1e0
[ 0.853504] ? submit_bio+0x73/0x140
[ 0.854052] ? guard_bio_eod+0x2c/0xf0
[ 0.854622] submit_bh_wbc+0x180/0x1b0
[ 0.855195] __bread_gfp+0x54/0xe0
[ 0.855744] ext4_fill_super+0x1f6/0x3a10
[ 0.856377] ? vsnprintf+0x24f/0x4e0
[ 0.856943] ? down_write+0x12/0x40
[ 0.857497] ? snprintf+0x45/0x70
[ 0.858021] mount_bdev+0x17f/0x1b0
[ 0.858572] ? mount_bdev+0x17f/0x1b0
[ 0.859149] ? ext4_calculate_overhead+0x490/0x490
[ 0.859896] ext4_mount+0x15/0x20
[ 0.860420] mount_fs+0x155/0x180
[ 0.860942] ? alloc_vfsmnt+0x1bb/0x230
[ 0.861547] vfs_kern_mount.part.23+0x80/0x150
[ 0.862240] do_mount+0x5ea/0xd20
[ 0.862764] ? memdup_user+0x4f/0x80
[ 0.863329] SyS_mount+0x98/0xe0
[ 0.863842] mount_block_root+0x109/0x2da
[ 0.864478] ? set_debug_rodata+0x17/0x17
[ 0.865107] mount_root+0x6a/0x6d
[ 0.865634] prepare_namespace+0x13e/0x176
[ 0.866287] kernel_init_freeable+0x224/0x251
[ 0.866971] ? rest_init+0xb0/0xb0
[ 0.867507] kernel_init+0xe/0x101
[ 0.868045] ret_from_fork+0x35/0x40
I'm trying to compile it for running under qemu x86.
Another possibility can be get an android oreo image with the kernel debug symbols; do you know if there are precompiled images with kernel debug symbols?
Thanks!
If the problem is actually in kernel, below are instructions how to build it from sources.
1. Obtain kernel sources
First of all, you need to figure out the device which you want to build the kernel for. Knowing the device name, you can clone correct Android kernel sources for it and build it. For example, for goldfish you should use kernel from:
https://android.googlesource.com/kernel/goldfish/
If you're not sure which kernel to use for your device, try to use so called "Android common kernel":
https://android.googlesource.com/kernel/common/
Basically it works like this:
Android common kernel is based on regular Linux kernel, adding some Android-specific patches on top of it
Android kernels for specific devices are based on common kernel, adding some device-specific patches on top of it.
Now that you "git cloned" the kernel, checkout to version branch you want to use:
$ git checkout android-4.14
2. Configure toolchain
I assume you want to build kernel for x86_64 architecture. If so, configure your toolchain like this:
$ export PATH=$AOSP_DIR/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin:$PATH
$ export CROSS_COMPILE=x86_64-linux-androidkernel-
$ export ARCH=x86_64
where $AOSP_DIR -- path to your AOSP sources. If you don't have AOSP sources, you can obtain the toolchain separately (outside of kernel sources directory):
$ git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9
3. Obtain Android kernel configs
Download Android kernel configs (outside of your kernel directory):
$ git clone https://android.googlesource.com/kernel/configs android-kernel-configs
4. Configure and build the kernel
Now, in your kernel source code directory, you can create kernel configuration (.config file) using corresponding defconfig file and Android config fragments. For example, for goldfish you should use this command:
$ ./scripts/kconfig/merge_config.sh \
arch/x86/configs/x86_64_ranchu_defconfig \
../android-kernel-configs/android-4.14/android-base.config \
../android-kernel-configs/android-4.14/android-recommended.config \
../android-kernel-configs/android-4.14/android-recommended-x86.config
Now .config file is generated. At this point you may want to run make menuconfig and modify the kernel configuration for your needs (e.g. enable some debug options, etc).
Build the kernel:
$ make -j4
It should built fine, but I didn't test it (neither the building, nor the running in the emulator). So if you can verify if those instructions work, please provide your comments.
I'm trying to compile FFMpeg for Android and I have troubles running the APK on Android 4 (on Android 5 I don't get this shitty unsatisfied link error):
05-09 15:16:18.880 22160-22304/com.gpac.Osmo4 I/LibrariesLoader﹕ Loading library avcodec...
05-09 15:16:18.910 22160-22304/com.gpac.Osmo4 E/dalvikvm﹕ dlopen("/data/app-lib/com.gpac.Osmo4-1/libavcodec.so") failed: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "log2f" referenced by "libavcodec.so"...
05-09 15:16:18.920 22160-22304/com.gpac.Osmo4 E/LibrariesLoader﹕ Failed to load library : avcodec due to link error Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "log2f" referenced by "libavcodec.so"...
java.lang.UnsatisfiedLinkError: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "log2f" referenced by "libavcodec.so"...
I'm using NDK 10d, toolchain 4.9 but I was trying with NDK 8 and 9 also and I was getting the same result.
The only difference when I compile with older NDK versions is that I get a warning message:
incompatible declaration of built-in function log2f
I checked libm.so (where log2f should be) which is on the target device and of course there is no log2f function defined there but replacing the library by hand probably would crash some other stuff + I need to root the phone.
I know this is a linker issue and it should not be that hard to fix but I ran out of ideas.
EDIT:
I'm trying to compile ffmpeg 2.4.3
The script that I'm using to configure:
#!/bin/bash
if [ "$NDK" = "" ]; then
echo NDK variable not set, assuming ${HOME}/android-ndk
export NDK=${HOME}/android-ndk
fi
echo "Compiling with NDK located at: $NDK"
ROOT_DIR=`cd ..; pwd`
CUR_DIR=`pwd`
echo "Fetching Android system headers"
if [ ! -d "$ROOT_DIR/android-source/frameworks/base" ]; then
git clone --depth=1 --branch cm-11.0 https://github.com/CyanogenMod/android_frameworks_base.git "$ROOT_DIR/android-source/frameworks/base"
fi
if [ ! -d "$ROOT_DIR/android-source/system/core" ]; then
git clone --depth=1 --branch cm-11.0 https://github.com/CyanogenMod/android_system_core.git "$ROOT_DIR/android-source/system/core"
fi
if [ ! -d "$ROOT_DIR/android-source/frameworks/av" ]; then
git clone --depth=1 --branch cm-11.0 https://github.com/CyanogenMod/android_frameworks_av "$ROOT_DIR/android-source/frameworks/av"
fi
if [ ! -d "$ROOT_DIR/android-source/hardware/libhardware" ]; then
git clone --depth=1 --branch cm-11.0 https://github.com/CyanogenMod/android_hardware_libhardware.git "$ROOT_DIR/android-source/hardware/libhardware"
fi
if [ ! -d "$ROOT_DIR/android-source/frameworks/native" ]; then
git clone --depth=1 --branch cm-11.0 https://github.com/CyanogenMod/android_frameworks_native.git "$ROOT_DIR/android-source/frameworks/native"
fi
echo "Fetching Android libraries for linking"
# Libraries from any froyo/gingerbread device/emulator should work
# fine, since the symbols used should be available on most of them.
if [ ! -d "$ROOT_DIR/android-libs" ]; then
wget http://download.cyanogenmod.org/get/jenkins/65493/cm-10.2.1.3-serranoltexx.zip -P../
unzip ../cm-10.2.1.3-serranoltexx.zip system/lib/* -d../
mv ../system/lib "$ROOT_DIR/android-libs"
rmdir ../system
rm ../cm-10.2.1.3-serranoltexx.zip
fi
ANDROID_SOURCE="$ROOT_DIR/android-source"
echo "ANDROID_SOURCE: $ANDROID_SOURCE"
ANDROID_LIBS="$ROOT_DIR/android-libs"
OBJS="$ROOT_DIR/objs"
if [ "$DEST" = "" ]; then
rm -rf $ROOT_DIR/build/stagefright
mkdir -p $ROOT_DIR/build/stagefright
DEST=$ROOT_DIR/build/stagefright
fi
#for ABI in "armeabi-v7a" "armeabi" "x86"; do
for ABI in "armeabi-v7a" "armeabi"; do
if [ "$ABI" = "x86" ]; then
ARCH="x86"
TOOLCHAIN=`echo $NDK/toolchains/x86-4.9/prebuilt/*-x86*`
else
ARCH="arm"
TOOLCHAIN=`echo $NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/*-x86*`
fi
SYSROOT=$NDK/platforms/android-18/arch-$ARCH
# Expand the prebuilt/* path into the correct one
export PATH=$TOOLCHAIN/bin:$PATH
FLAGS="--target-os=linux --arch=$ARCH"
FLAGS="$FLAGS --sysroot=$SYSROOT"
FLAGS="$FLAGS --enable-shared --disable-doc --disable-ffplay --disable-ffprobe --disable-ffserver --disable-symver"
if [ "$ARCH" = "arm" ]; then
FLAGS="$FLAGS --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- --cpu=armv7-a --enable-libstagefright-h264"
#FLAGS="$FLAGS --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- --cpu=armv7-a"
else
FLAGS="$FLAGS --cross-prefix=$TOOLCHAIN/bin/i686-linux-android- --disable-asm"
fi
EXTRA_CFLAGS="-I$DEST/$ABI/include"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/base/include -I$ANDROID_SOURCE/system/core/include"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/native/include"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/native/include/media/openmax"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/av/include"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/av/media/libstagefright"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$NDK/sources/cxx-stl/gnu-libstdc++/4.9/include -I$NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/$ABI/include"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/hardware/libhardware/include"
if [ "$ARCH" = "arm" ]; then
EXTRA_CFLAGS="$EXTRA_CFLAGS -march=armv7-a -mfloat-abi=softfp -mfpu=neon -Wl,--no-undefined" #-Werror=implicit-function-declaration"
fi
EXTRA_LDFLAGS="-Wl,--fix-cortex-a8 -L$ANDROID_LIBS -Wl,-rpath-link,$ANDROID_LIBS -L$NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/$ABI"
EXTRA_CXXFLAGS="-Wno-multichar -fno-exceptions -fno-rtti"
FLAGS="$FLAGS --prefix=$DEST/$ABI"
mkdir -p $DEST/$ABI
mkdir -p $OBJS/$ABI
echo $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" --extra-cxxflags="$EXTRA_CXXFLAGS" > $DEST/$ABI/info.txt
echo "Configuring ..."
cd $OBJS/$ABI
$ROOT_DIR/configure $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" --extra-cxxflags="$EXTRA_CXXFLAGS" | tee $DEST/$ABI/configuration.txt
[ $PIPESTATUS == 0 ] || exit 1
echo "Making ..."
#make clean
make -j4 || exit 1
make install || exit 1
cd $CUR_DIR
done
You can use the latest NDK, only set platform to android-19 and not the latest android-21.
You use the libraries from some cyanogenmod build, which are "too good". For example, you get from there a libm.so that has log2(). Instead, you need the least common denominator of libm.so versions on supported devices. You don't need to look for such library; you have the "official" version in NDK.
I understand that to enable hardware codec, you need some "unofficial" libs. But be careful and put the directory with the downloaded libs closer to the end of your lookup list. Or safer still, only copy the few libs (like libcutils.so) that your link really needs.
I'm developing an android cmake project that compiles succesfully on my 32-bit Ubuntu 12.04 machine at work (I will call it WorkMachine). When I want to compile it at home, I installed a 32-bit Ubuntu 12.04 virtual machine (I will call it HomeMachine), I git cloned the project on it, and when I start the compilation, it will block with an error.
CMAKE_CFLAGS are:
CMAKE_CXXFLAGS are:
-- Configuring done
-- Generating done
-- Build files have been written to: /home/raa/Dropbox/Demo/android_build
[ 0%] Built target bitstream
[ 0%] Built target distrat
[ 1%] Built target fisher
[ 1%] Built target gtest
[ 7%] Built target jpeg-8c
[ 7%] Built target map
[ 8%] Built target resampler
[ 9%] Built target timer
[ 92%] Built target fftw3f-3
[ 96%] Built target vlfeat
[ 96%] Built target extract_shared
[ 97%] Built target shared
[ 97%] Built target cssc_train
Linking CXX executable ../../bin/extract
/home/raa/Dropbox/Demo/libraries/fftw-3.3.3/api/configure.c:28: error: undefined reference to 'fftwf_dft_conf_standard'
collect2: error: ld returned 1 exit status
make[2]: *** [../bin/extract] Error 1
make[1]: *** [src/CMakeFiles/extract.dir/all] Error 2
make: *** [all] Error 2
Here I am reporting gcc version (the same on both computers)
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
But how is that possible?
It seems the problem is not due to some cmake cache or similar chaches, because if I git clone the project on another directory on the WorkMachine, the code compiles well too.
What can I check in order to resolve the problem? If you need additional details, please ask me.
Thank you for your time.
Riccardo
the solution to Riccardos problem is to change the commandline parameter of ar from r to q (see man page for difference, basically q does not check for duplicats)
do this via
SET(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
you probably want to check if CMAKE_AR is "ar" (might be different on other systems)
whoa! Solved! It was really a weird behaviour from cmake: I had three files conf.c that must be merged into a static library. When cmake run the AR program to create the library, it executed a command that was like:
ar cr dir1/source1.c dir1/source2.c ... dft/conf.c rdft/conf.c
ar r reodft/conf.c dir2/source3.c
so, maybe due to the huge number of object files that were to be linked, cmake splitted ar commands in two command, BUT second command overwrited one of the two file conf.c that were added with the first command, so symbols defined with the first ar command were lost! This is clearly a bug in ar because even if the source file is the same, maybe the content may vary, thus symbols are not to be deleted. Thanks to all! Your suggestions brought me to the right solution!
How can I build my source for android with NDK.
Already I download ndk and I don't know how can I set arch compiler path.
This is my "build-for-android.sh" code:
#!/bin/sh
cairo=system
curl=system
pal=android
alsa=no
pulse=no
sles=yes
ffmpeg=yes
gallium=no
egl=yes
glx=no
PKG_CONFIG_PATH=$MOONLIGHT_PREFIX/lib/pkgconfig
if [ -d /usr/X11/share/aclocal ]; then
export ACLOCAL_FLAGS="-I /usr/X11/share/aclocal"
fi
./autogen.sh --host=arm-linux-androideabi --prefix=$MOONLIGHT_PREFIX --with-manual-mono=yes --with-testing=no --enable-browser-support --disable-desktop-support --with-unwind=no --with-ffmpeg=$ffmpeg --with-alsa=$alsa --with-pulseaudio=$pulse --with-opensles=$sles --with-pal=$pal --with-curl=$curl --with-cairo=$cairo --with-gallium-path=$gallium --enable-sdk=no --with-egl=$egl --with-glx=$glx CFLAGS="-DPLATFORM_ANDROID -I$MOONLIGHT_PREFIX/include $CFLAGS" LDFLAGS="-L$MOONLIGHT_PREFIX/lib $LDFLAGS" CXXFLAGS="-fno-rtti -DPLATFORM_ANDROID -I$MOONLIGHT_PREFIX/include $CFLAGS"
make $#
when I run it I get error below:
checking for arm-linu-androideabi-g++... no
checking for arm-linu-androideabi-c++... no
checking for arm-linu-androideabi-gpp... no
checking for arm-linu-androideabi-aCC... no
checking for arm-linu-androideabi-cc... no
.
.
.
.
I can see them in ~/Android/android-ndk-r8b/toolchains/arm-linux-androideabi-4.4.3/prebuild/linux-x86/bin/* directory.
OK. I found it.:
First, a standalone toolchain is created to make the configure script easier to use
~$ android-ndk-r5b/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=android-8-toolchain
Next, the toolchain's bin directory is added to the PATH.
~$ export PATH=$PATH:~/android-8-toolchain/bin/