📜 ⬆️ ⬇️

Recompiling Android libraries under x86. JavaCV and Alljoyn

Android smartphones based on Intel Atom processors have already ceased to be exotic, and the topic of optimizing libraries and applications for the x86 platform has moved from the theoretical plane to a purely practical one: software that works equally well on ARM and x86 will ultimately have an advantage that is optimized for only one architecture. In this regard, we found it useful to translate two articles by Intel engineer Xavier Hallade (Xavier Hallade), describing practical examples of recompiling Android x86 libraries.

Getting x86 version of JavaCV for Android

JavaCV is a wrapper for the OpenCV and ffmpeg libraries. While these libraries are perfectly compatible with the x86 version of Android, JavaCV does not have corresponding build scripts and is not integrated into x86 binaries.
Although compiling suitable x86 versions of JavaCV packages will not take long, for the most rushed ones, we’ll immediately provide links:

Now let's see what it took us to build. You will need traditional build tools (gcc, make, ...), as well as maven.
First you need to recompile cppjars

Recompiling cppjars (OpenCV and ffmpeg)
This is easily achieved using the build scripts included with the cppjars package:

wget https://javacv.googlecode.com/files/javacv-0.7-cppjars.zip unzip javacv-0.7-cppjars.zip cd javacv-cppjars 

Build scripts for Android: build_opencv-android-arm.sh and build_ffmpeg-android-arm.sh . We need to create the equivalent build_opencv-android-x86.sh and build_ffmpeg-android-x86.sh . To do this in-x86 copies replace:

Do not do this blindly - everything will work better if you understand what you are doing :)
')
Here’s what I got in the build_ffmpeg-android-x86.sh file:

 ANDROID_BIN=$ANDROID_NDK/toolchains/x86-4.8/prebuilt/linux-x86_64/bin ANDROID_ROOT=$ANDROID_NDK/platforms/android-14/arch-x86 tar -xjvf ffmpeg-$FFMPEG_VERSION.tar.bz2 mv ffmpeg-$FFMPEG_VERSION ffmpeg-$FFMPEG_VERSION-android-x86 cd ffmpeg-$FFMPEG_VERSION-android-x86 tar -xjvf ../last_stable_x264.tar.bz2 X264=`echo x264-snapshot-*` cd $X264 ./configure --enable-static --enable-pic --disable-cli --disable-opencl --cross-prefix=$ANDROID_BIN/i686-linux-android- --sysroot=$ANDROID_ROOT --host=i686-linux --extra-cflags="-fpic -pipe -DANDROID -DNDEBUG -mtune=atom -mssse3 -ffast-math -mfpmath=sse -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300" --extra-ldflags="-lm -lz -Wl,--no-undefined -Wl,-z,noexecstack" make -j8 cd ../ patch -p1 < ../ffmpeg-$FFMPEG_VERSION-android-x86.patch ./configure --prefix=$ANDROID_NDK/../ --enable-shared --enable-gpl --enable-version3 --enable-libx264 \ --disable-static --disable-symver --disable-doc --disable-ffplay --disable-ffmpeg --disable-ffprobe --disable-ffserver --disable-encoders --disable-muxers --disable-devices --disable-demuxer=sbg --disable-demuxer=dts --disable-parser=dca --disable-decoder=dca --disable-decoder=svq3 --enable-network --enable-version3 --disable-amd3dnow --disable-amd3dnowext --disable-outdev=sdl\ --extra-cflags="-I$X264" --extra-ldflags="-L$X264" --enable-cross-compile --cc=$ANDROID_BIN/i686-linux-android-gcc --sysroot=$ANDROID_ROOT --target-os=linux --arch=x86 --cpu=i686 \ --enable-asm --enable-yasm --enable-pic --extra-cflags="-DANDROID -DNDEBUG -fPIC -pipe -mtune=atom -mssse3 -ffast-math -mfpmath=sse" \ --extra-ldflags="-lm -lz -Wl,--no-undefined -Wl,-z,noexecstack" --disable-stripping --disable-symver --disable-programs make -j8 LIBS="libavcodec/libavcodec.so libavdevice/libavdevice.so libavfilter/libavfilter.so libavformat/libavformat.so libavutil/libavutil.so libpostproc/libpostproc.so libswresample/libswresample.so libswscale/libswscale.so" $ANDROID_NDK/toolchains/x86-4.8/prebuilt/linux-x86_64/bin/i686-linux-android-strip $LIBS mkdir -p com/googlecode/javacv/cpp/android-x86/ cp $LIBS com/googlecode/javacv/cpp/android-x86/ jar cvf ../ffmpeg-$FFMPEG_VERSION-android-x86.jar com/ rm -Rf com/ cd ../ 

Here, ffmpeg- $ FFMPEG_VERSION-android-x86.patch is exactly the same as in the arm version, you can just copy it.
But the file build_opencv-android-x86.sh :

 tar -xzvf opencv-$OPENCV_VERSION.tar.gz mkdir opencv-$OPENCV_VERSION/build_android-x86 cd opencv-$OPENCV_VERSION cd build_android-x86 ANDROID_BIN=$ANDROID_NDK/toolchains/x86-4.6/prebuilt/linux-x86_64/bin/ \ ANDROID_CPP=$ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/4.6/ \ ANDROID_ROOT=$ANDROID_NDK/platforms/android-9/arch-x86/ \ cmake -DCMAKE_TOOLCHAIN_FILE=platforms/android/android.toolchain.cmake -DANDROID_ABI=x86 -DOPENCV_EXTRA_C_FLAGS="-O3 -ffast-math -mtune=atom -mssse3 -mfpmath=sse" -DOPENCV_EXTRA_CXX_FLAGS="-O3 -ffast-math -mtune=atom -mssse3 -mfpmath=sse" -DCMAKE_INSTALL_PREFIX=$ANDROID_NDK/../ -DBUILD_SHARED_LIBS=ON -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_ANDROID_EXAMPLES=OFF -DBUILD_JASPER=ON -DBUILD_JPEG=ON -DBUILD_OPENEXR=ON -DBUILD_PNG=ON -DBUILD_TBB=ON -DBUILD_TIFF=ON -DBUILD_ZLIB=ON -DBUILD_opencv_java=OFF -DBUILD_opencv_python=OFF -DENABLE_PRECOMPILED_HEADERS=OFF -DWITH_1394=OFF -DWITH_FFMPEG=OFF -DWITH_GSTREAMER=OFF -DWITH_TBB=ON -DWITH_CUDA=OFF -DWITH_OPENCL=OFF .. make -j8 LIBS="lib/x86/libopencv*.so lib/x86/libtbb.so" $ANDROID_NDK/toolchains/x86-4.6/prebuilt/linux-x86_64/bin/i686-linux-android-strip $LIBS mkdir -p com/googlecode/javacv/cpp/android-x86/ cp $LIBS com/googlecode/javacv/cpp/android-x86/ jar cvf ../../opencv-$OPENCV_VERSION-android-x86.jar com/ rm -Rf com/ cd ../../ 

Here I removed the -arm patch that generated another android.mk file and relied on platforms / android / android.toolchain.cmake , provided by OpenCV , and also added some specific flags for better optimization:

 -DANDROID_ABI=x86 -DOPENCV_EXTRA_C_FLAGS="-O3 -ffast-math -mtune=atom -mssse3 -mfpmath=sse" -DOPENCV_EXTRA_CXX_FLAGS="-O3 -ffast-math -mtune=atom -mssse3 -mfpmath=sse" 

Now if you run:

 sh ./build_all.sh android-x86 cd .. 

Then get ffmpeg-2.1.1-android-x86.jar and opencv-2.4.8-android-x86.jar .
Now we can finally build the JavaCV package.

Build x86 version of JavaCV
First download and install JavaCPP:

 git clone https://code.google.com/p/javacpp/ cd javacpp/ git checkout 0.6 mvn install cd .. 

Then download the JavaCV sources:

 git clone https://code.google.com/p/javacv/ cd javacv git checkout 0.7 

Now you can build the android-x86 version of JavaCV by setting the android-x86 property in JavaCPP :

 mvn package -Pffmpeg -Djavacpp.options="-properties android-x86 -Dplatform.root=$ANDROID_NDK -Dcompiler.path=$ANDROID_NDK/toolchains/x86-4.6/prebuilt/linux-x86_64/bin/i686-linux-android-g++ -Dcompiler.includepath=$ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/4.6/include\ :$ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/4.6/libs/x86/include\ :../javacv-cppjars/opencv-2.4.8/build_android-x86/\ :../javacv-cppjars/opencv-2.4.8/modules/core/include\ :../javacv-cppjars/opencv-2.4.8/modules/androidcamera/include\ :../javacv-cppjars/opencv-2.4.8/modules/flann/include\ :../javacv-cppjars/opencv-2.4.8/modules/imgproc/include\ :../javacv-cppjars/opencv-2.4.8/modules/highgui/include\ :../javacv-cppjars/opencv-2.4.8/modules/features2d/include\ :../javacv-cppjars/opencv-2.4.8/modules/calib3d/include\ :../javacv-cppjars/opencv-2.4.8/modules/ml/include\ :../javacv-cppjars/opencv-2.4.8/modules/video/include\ :../javacv-cppjars/opencv-2.4.8/modules/legacy/include\ :../javacv-cppjars/opencv-2.4.8/modules/objdetect/include\ :../javacv-cppjars/opencv-2.4.8/modules/photo/include\ :../javacv-cppjars/opencv-2.4.8/modules/gpu/include\ :../javacv-cppjars/opencv-2.4.8/modules/nonfree/include\ :../javacv-cppjars/opencv-2.4.8/modules/contrib/include\ :../javacv-cppjars/opencv-2.4.8/modules/stitching/include\ :../javacv-cppjars/opencv-2.4.8/modules/ts/include\ :../javacv-cppjars/opencv-2.4.8/modules/videostab/include\ :../javacv-cppjars/ffmpeg-2.1.1-android-x86 \ -Dcompiler.linkpath=$ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/4.6/libs/x86\ :../javacv-cppjars/opencv-2.4.8/build_android-x86/lib/x86\ :../javacv-cppjars/ffmpeg-2.1.1-android-x86/libswscale\ :../javacv-cppjars/ffmpeg-2.1.1-android-x86/libavcodec\ :../javacv-cppjars/ffmpeg-2.1.1-android-x86/libswresample\ :../javacv-cppjars/ffmpeg-2.1.1-android-x86/libpostproc\ :../javacv-cppjars/ffmpeg-2.1.1-android-x86/libavfilter\ :../javacv-cppjars/ffmpeg-2.1.1-android-x86/libavformat\ :../javacv-cppjars/ffmpeg-2.1.1-android-x86/libavutil\ :../javacv-cppjars/ffmpeg-2.1.1-android-x86/libavdevice" 

You will find the collected packages in the target / folder:

 2.7M Jan 15 19:09 javacv-android-x86.jar 3.6M Jan 15 19:09 javacv-bin.zip 747K Jan 15 19:09 javacv-src.zip 734K Jan 15 19:09 javacv.jar 

Adding x86 version to your application
You can copy the generated .so files inside javacv-android-x86.jar , ffmpeg-2.1.1-android-x86.jar, and opencv from the packages downloaded from the links at the beginning of the article or from the ones you just compiled. -2.4.8-android-x86.jar to the / lib / x86 / folder of your Android package, in the same way as the arm version to the / lib / armeabi-v7a / folder .

x86 version of Alljoyn for Android

Alljoyn is a cross-platform library for peer-to-peer communication between different devices using different transports.
The library has an open source code (Apache license), originally it was created in the Qualcomm Innovation Center. The project has joined the AllSeen Alliance and is now hosted here .
Even if the precompiled x86 version is not on the official website, source code compilation is perfectly supported.
When you download the Android package, you will see the following:

 cpp/ core AllJoyn functionality, implemented in C++ - built from Git projects alljoyn_core and common - required for all AllJoyn applications java/ optional Java language binding (built from alljoyn_java) - required for Android apps c/ optional ANSI C language binding (built from alljoyn_c) - required by Unity binding unity/ optional Unity language binding (built from alljoyn_unity) about/ implements AllJoyn About Feature. (built from about.git/(cpp and java)) 

If you use java binding alljoyn.jar , then find liballjoyn_java.so in the lib / armeabi / directory . The binaries (.so / .a files) from this package are intended only for ARMv5, but are perfectly compiled from source for other platforms.
From this link you can download the x86 version, which I compiled for you. It has the same architecture as the version for ARMv5.
If you just use AllJoyn .jar for Android, you can take liballjoyn_java.so and place it in the lib / x86 directory of your Android application.
If you want to compile the binary yourself and learn more about this process, here is a description of what I did.

Compiling Alljoyn for x86 platform for Android
First of all download the source code:

 git clone https://git.allseenalliance.org/gerrit/core/alljoyn cd alljoyn 

Then take libcrypto.so and libssl.so from a real x86 device or x86 emulator and put them in the build / android / x86 / release / dist / cpp / lib / folder:

 mkdir -p build/android/x86/release/dist/cpp/lib/ adb pull /system/lib/libcrypto.so build/android/x86/release/dist/cpp/lib/ adb pull /system/lib/libssl.so build/android/x86/release/dist/cpp/lib/ 

Now you can build a library for x86, as described in the documentation; The most boring in this process is the need to have a copy of the AOSP sources:

 export CLASSPATH=/usr/share/java/junit.jar scons OS=android CPU=x86 ANDROID_NDK=/opt/android-ndk ANDROID_SDK=/opt/android-sdk ANDROID_SRC=/home/ph0b/android-build VARIANT=release BINDINGS=cpp,c,java,unity 


Original articles:

Source: https://habr.com/ru/post/219581/


All Articles