Android смартфоны на базе процессоров Intel Atom уже перестали быть экзотикой, и тема оптимизации библиотек и приложений под х86 платформу перешла из теоретической плоскости в чисто практическую: софт, одинаково хорошо работающий и на ARM, и на х86 в конечном счете будет иметь преимущество перед тем, что оптимизирован только под одну архитектуру. В связи с этим мы посчитали полезным перевести две статьи инженера Intel Ксавье Алляда (Xavier Hallade), описывающие практические примеры перекомпиляции Android библиотек под х86.
Хотя компиляция подходящих х86 версий пакетов JavaCV и не займет много времени, для самых торопливых сразу же приведем ссылки:
Теперь давайте посмотрим, что нам потребовалось для сборки. Вам понадобятся традиционные средства сборки (gcc, make, …), а также maven.
Для начала необходимо перекомпилировать cppjars
Скрипты сборки для Android: build_opencv-android-arm.sh и build_ffmpeg-android-arm.sh. Нам нужно создать эквивалентные build_opencv-android-x86.sh и build_ffmpeg-android-x86.sh. Для этого в -х86 копиях заменим:
Не делайте этого вслепую – все будет работать лучше, если вы понимаете, что делаете :)
Вот что в результате у меня получилось в файле build_ffmpeg-android-x86.sh:
Здесь ffmpeg-$FFMPEG_VERSION-android-x86.patch точно тот же самый, что и в arm версии, можете его просто скопировать.
А вот файл build_opencv-android-x86.sh:
Здесь я удалил вызов -arm патча, который генерировал другой android.mk файл и положился на platforms/android/android.toolchain.cmake, предоставляемый OpenCV, а также добавил некоторые специфичные флаги для большей оптимизации:
Теперь если вы выполните:
То получите ffmpeg-2.1.1-android-x86.jar и opencv-2.4.8-android-x86.jar.
Теперь мы, наконец, можем собрать пакет JavaCV.
После скачайте исходники JavaCV:
Теперь вы можете собрать android-x86 версию JavaCV, установив свойство android-x86 в JavaCPP:
Вы найдете собранные пакеты в папке target/:
Библиотека имеет открытый исходный код (лицензия Apache), изначально она создана в Qualcomm Innovation Center. Проект присоединился к AllSeen Alliance и теперь хостится здесь.
Даже в том случае, если прекомпилированная х86 версия отсутствует на официальном вебсайте, компилирование из исходников прекрасно поддерживается.
Когда вы скачаете пакет под Android, то увидите следующее:
Если вы используете Java обвязку alljoyn.jar, то обнаружите liballjoyn_java.so в каталоге lib/armeabi/. Бинарники (файлы .so/.a) из этого пакета предназначены только для ARMv5, но отлично собираются из исходников под другие платформы.
По этой ссылке вы можете скачать х86 версию, которую я скомпилировал для вас. Она имеет ту же архитектуру, что и версия для ARMv5.
Если вы просто используете AllJoyn .jar под Android, вы можете взять liballjoyn_java.so и поместить его в каталог lib/x86 вашего Android приложения.
Если же вы желаете сами скомпилировать бинарник и узнать больше об этом процессе, вот описание того, что я сделал.
Затем возьмите libcrypto.so и libssl.so с реального x86 устройства или x86 эмулятора и поместите их в папку build/android/x86/release/dist/cpp/lib/:
Теперь вы можете собрать библиотеку для х86, как описано в документации; самое скучное в этом процессе – необходимость иметь копию исходников AOSP:
Оригиналы статей:
Получение х86 версии JavaCV под Android
JavaCV представляет собой обертку (wrapper) для библиотек OpenCV и ffmpeg. В то время как эти библиотеки отлично совместимы с х86 версией Android, JavaCV не имеет соответствующих скриптов сборки и не интегрирован в бинарники х86.Хотя компиляция подходящих х86 версий пакетов JavaCV и не займет много времени, для самых торопливых сразу же приведем ссылки:
Теперь давайте посмотрим, что нам потребовалось для сборки. Вам понадобятся традиционные средства сборки (gcc, make, …), а также maven.
Для начала необходимо перекомпилировать cppjars
Перекомпилирование cppjars (OpenCV и ffmpeg)
Этого легко достичь, используя скрипты сборки, прилагаемые к пакету cppjars:wget https://javacv.googlecode.com/files/javacv-0.7-cppjars.zip
unzip javacv-0.7-cppjars.zip
cd javacv-cppjars
Скрипты сборки для Android: build_opencv-android-arm.sh и build_ffmpeg-android-arm.sh. Нам нужно создать эквивалентные build_opencv-android-x86.sh и build_ffmpeg-android-x86.sh. Для этого в -х86 копиях заменим:
- arm-linux-androideabi- на i686-linux-android- (префикс бинарника toolchain)
- arm-linux-androideabi- на x86- (toolchain)
- -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mfpu=neon… на -mtune=atom -mssse3 -mfpmath=sse (флаги компилятора)
- arm-linux на i686-linux
- прочие суффиксы -arm на -x86
Не делайте этого вслепую – все будет работать лучше, если вы понимаете, что делаете :)
Вот что в результате у меня получилось в файле build_ffmpeg-android-x86.sh:
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 ../
Здесь ffmpeg-$FFMPEG_VERSION-android-x86.patch точно тот же самый, что и в arm версии, можете его просто скопировать.
А вот файл 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 ../../
Здесь я удалил вызов -arm патча, который генерировал другой android.mk файл и положился на platforms/android/android.toolchain.cmake, предоставляемый OpenCV, а также добавил некоторые специфичные флаги для большей оптимизации:
-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"
Теперь если вы выполните:
sh ./build_all.sh android-x86
cd ..
То получите ffmpeg-2.1.1-android-x86.jar и opencv-2.4.8-android-x86.jar.
Теперь мы, наконец, можем собрать пакет JavaCV.
Сборка х86 версии JavaCV
Сначала скачайте и установите JavaCPP:git clone https://code.google.com/p/javacpp/
cd javacpp/
git checkout 0.6
mvn install
cd ..
После скачайте исходники JavaCV:
git clone https://code.google.com/p/javacv/
cd javacv
git checkout 0.7
Теперь вы можете собрать android-x86 версию JavaCV, установив свойство android-x86 в 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"
Вы найдете собранные пакеты в папке target/:
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
Добавление х86 версии в ваше приложение
Из пакетов, скачанных по ссылкам в начале статьи или из тех, что вы только что собрали, вы можете скопировать сгенерированные файлы .so, находящиеся внутри javacv-android-x86.jar, ffmpeg-2.1.1-android-x86.jar и opencv-2.4.8-android-x86.jar в папку /lib/x86/ вашего Android пакета, точно так же, как и arm версии в папку /lib/armeabi-v7a/.х86 версия Alljoyn для Android
Alljoyn – это кросс-платформенная библиотека для peer-to-peer связи между различными устройствами с использованием различных транспортов.Библиотека имеет открытый исходный код (лицензия Apache), изначально она создана в Qualcomm Innovation Center. Проект присоединился к AllSeen Alliance и теперь хостится здесь.
Даже в том случае, если прекомпилированная х86 версия отсутствует на официальном вебсайте, компилирование из исходников прекрасно поддерживается.
Когда вы скачаете пакет под Android, то увидите следующее:
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))
Если вы используете Java обвязку alljoyn.jar, то обнаружите liballjoyn_java.so в каталоге lib/armeabi/. Бинарники (файлы .so/.a) из этого пакета предназначены только для ARMv5, но отлично собираются из исходников под другие платформы.
По этой ссылке вы можете скачать х86 версию, которую я скомпилировал для вас. Она имеет ту же архитектуру, что и версия для ARMv5.
Если вы просто используете AllJoyn .jar под Android, вы можете взять liballjoyn_java.so и поместить его в каталог lib/x86 вашего Android приложения.
Если же вы желаете сами скомпилировать бинарник и узнать больше об этом процессе, вот описание того, что я сделал.
Компиляция Alljoyn для x86 платформы под Android
Первым делом скачайте исходники:git clone https://git.allseenalliance.org/gerrit/core/alljoyn
cd alljoyn
Затем возьмите libcrypto.so и libssl.so с реального x86 устройства или x86 эмулятора и поместите их в папку build/android/x86/release/dist/cpp/lib/:
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/
Теперь вы можете собрать библиотеку для х86, как описано в документации; самое скучное в этом процессе – необходимость иметь копию исходников AOSP:
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
Оригиналы статей: