В общем понадобилось портировать одну прогу под Андроид arm7, но она плотненько работает с базой данных, а так как я человек впринципе ленивый, то обёртку для REST API сервера было лень писать, решился на компилирование MySQL плагина, но если бы я знал тогда, что это займёт у меня 20 часов…
В общем вот вам готовый рецепт из 12 шагов для компиляции на Ubuntu и на Windows
Установим инструменты:
- Качаем и устанавливаем CMake, у меня 3.5.2
- Разумеется Android NDK у вас уже должен быть установлен.
- WIN ONLY Качаем и ставим MSYS (отмечаем всё, что можно)
- При установке Qt нужно было поставить и исходники (папка qt/5.6/src/qtbase), если нет её, то качаем и ставим через UpdateManager из папки Qt
- WIN ONLY Открываем консольку MSYS (c:\mingw\msys\1.0\msys.bat), в дальнейшем все действия будут вестись в ней
- WIN ONLY для удобства выкачивания установим wget: install msys-wget-bin
1. Создадим отдельную директорию, где будем развлекаться и перейдём в неё:
mkdir /d/Projects/AndroidMySQL
cd /d/Projects/AndroidMySQL
2. Выкачиваем саму MariaDB, а именно коннектор
wget https://downloads.mariadb.org/interstitial/connector-c-3.0.0/mariadb-connector-c-3.0.0-alpha-src.tar.gz
tar -xzvf mariadb-connector-c-3.0.0-alpha-src.tar.gz
3. Выкачиваем и распаковываем исходники icon
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
tar -xvzf libiconv-1.14.tar.gz
4. Выкачиваем и распаковываем OpenSSL
wget -c http://www.openssl.org/source/openssl-1.0.1h.tar.gz --no-check-certificate
tar -xvzf openssl-1.0.1h.tar.gz
5. WIN ONLY: Задаём общие глобальные переменные
export PATH="$PATH:/c/mingw/bin:/c/Program Files (x86)/CMake/bin"
export ANDROID_NDK_ROOT=/d/Android/android-ndk-r10e
export SR="$ANDROID_NDK_ROOT"/platforms/android-19/arch-arm/usr # Укажите платформу, под которую собираете ваши проекты (Лучше, 19)
export BR="$ANDROID_NDK_ROOT"/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-
export CPP="$BR"cpp
export AR="$BR"ar
export STRIP="$BR"strip
export RANLIB="$BR"ranlib
export LINKER="$BR"ld
export OBJDUMP="$BR"objdump
export CC="$BR"gcc
export CFLAGS="--sysroot=$SR"
export CPPFLAGS="$CFLAGS"
export C_INCLUDE_PATH=$SR/include
export ANDROID_DEV=$SR/usr
export MAKEDEPPROG="$CC -M"
6. Собираем сначала iconv
cd libiconv-1.14
./configure --host=arm --prefix=$SR/usr --with-sysroot=$SR
make
make install
7. Собираем OpenSSL
cd ../openssl-1.0.1h
CC="$CC -march=armv7-a -mfloat-abi=softfp"
./Configure android-armv7 --prefix=$SR/usr no-asm
make
make install
make install_sw
[tip]Если заматериться error: undefined reference to ‘__ctype_get_mb_cur_max’,то в файл libcharset/lib/localcharset.c после дефайнов добавляем
size_t __ctype_get_mb_cur_max(void){ return 1; }[/tip]
8. Нус, начинаем подготовку к сборке MariaDB
В файл include/my_global.h необходимо добавить определение типа ushort
#ifndef ushort
#define ushort uint16
#endif
9. Подготавливаем сборку
cd ../mariadb-connector-c-3.0.0-alpha-src
mkdir build
cd build
cmake -G "Unix Makefiles"
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_AR="$BR"ar.exe \
-DCMAKE_C_COMPILER="$BR"gcc.exe \
-DCMAKE_C_FLAGS=--sysroot=$SR \
-DCMAKE_LINKER="$BR"ld.exe \
-DCMAKE_RANLIB="$BR"ranlib.exe \
-DCMAKE_STRIP="$BR"strip.exe \
-DCMAKE_SYSTEM_NAME=Linux \
-DICONV_INCLUDE_DIR="$SR/usr/include" \
-DICONV_LIBRARIES="$SR/usr/lib/libiconv.a" \
-DOPENSSL_ROOT_DIR="$SR/usr/lib/" \
../
10. Зажмуриваемся и собираем
make
[tip]
ага, фиг то там, failed to create symbolic link ‘libmysqlclient.a’: No errorвнезапно… тут, похоже, баг самого CMake, поэтому в файле
\AndroidMySQL\mariadb-connector-c-3.0.0-alpha-src\build\libmariadb\CMakeFiles\SYM_libmysqlclient.a.dir\build.make
находим строки (их по две) c -E create_symlink libmariadbclient.a libmysqlclient.a, удаляем её полностью
а так же -E create_symlink libmariadb.so libmysqlclient_r.so аналогично
и вручную копируем и продолжаем сборку
cp libmariadb/libmariadbclient.a libmariadb/libmysqlclient.a cp libmariadb/libmariadbclient.a libmariadb/libmysqlclient_r.a cp libmariadb/libmariadb.so libmariadb/libmysqlclient.so cp libmariadb/libmariadb.so libmariadb/libmysqlclient_r.so make[/tip] [tip] и ещё раз фиг error: unknown type name ‘pthread_mutex_t’
в файле ../unittest/libmariadb/thread.c
находим pthread_t threads[THREAD_NUM]; заменяем на void * threads[THREAD_NUM];
и там же заменяем pthread_mutex_t LOCK_test; на void * LOCK_test;
и опять
make
[/tip]
На этот раз должно всё ок пройти, ну и устанавливаем и копируем к нашему ndk
make install
mkdir "$SR/usr/lib/mariadb"
mkdir "$SR/usr/include/mariadb/"
cp libmariadb/*.{a,so} "$SR/usr/lib/mariadb/"
cp ../include/* "$SR/usr/include/mariadb/"
11. Собираем плагин QMySQL, открываем обычную консольку пути только на свои замените
cd /d/Qt/5.6/Src/qtbase/src/plugins/sqldrivers/mysql/
/d/Qt/5.6/android_armv7/bin/qmake.exe \
"INCLUDEPATH+=$SR/usr/include/mariadb" \
"LIBS+=-L$SR/usr/lib/mariadb -lmariadbclient -lssl -lcrypto -liconv" \
-o Makefile mysql.pro
make
make install
12. Разрабатываем тестовый проект Так как зависит от libmariadb.so, то его необходимо таскать с проектом, для этого в *.pro файле проекта добавить
contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
ANDROID_EXTRA_LIBS = \
d:/Projects/AndroidMySQL/mariadb-connector-c-3.0.0-alpha-src/build/libmariadb/libmariadb.so
}
Пересобираем проект, запускаем, и хуй то там =) QMYSQL driver not loaded
Посмотрим зависимости libqsqlmysql.so, которая в каталоге /home/pavelk/Qt/5.6/android_armv7/plugins/sqldrivers
ldd libqsqlmysql.so
и опять облом, нужна ldd для arm, ладно и с этим разберёмся, например так, тынц.
ldd-avr libqsqlmysql.so
Дело в том, что в зависимостях у libmysql.so есть libmariadb.so.3, а не libmariadb.so
почуяли разницу? =))
В общем, что бы побыстроляну пофиксить
в файле libmariadb/CMakeLists.txt
находим
SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
и заменяем на
SOVERSION "so")
ну а дальше удалить полностью build и заново, начиная с 9 шага
!пересобираем! проект, не забыть исправить в pro файле на libmariadb.so.so запускаем и радуемся =)
Вот как-то так =)
4 комментария
Здравствуйте! При сборке OpenSSL выдаёт целую пачку ошибок следующего вида:
( :; LIBDEPS=»${LIBDEPS:—L.. -lssl -L.. -lcrypto -ldl}»; LDCMD=»${LDCMD:-/c/Users/Knispel/AppData/Local/Android/android-ndk-r18b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-gcc -march=armv7-a -mfloat-abi=softfp}»; LDFLAGS=»${LDFLAGS:—DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -march=armv7-a -mandroid -I/c/Users/Knispel/AppData/Local/Android/android-ndk-r18b/platforms/android-19/arch-arm/usr/usr/include -B/c/Users/Knispel/AppData/Local/Android/android-ndk-r18b/platforms/android-19/arch-arm/usr/usr/lib -O3 -fomit-frame-pointer -Wall}»; LIBPATH=`for x in $LIBDEPS; do echo $x; done | sed -e ‘s/^ *-L//;t’ -e d | uniq`; LIBPATH=`echo $LIBPATH | sed -e ‘s/ /:/g’`; LD_LIBRARY_PATH=$LIBPATH:$LD_LIBRARY_PATH ${LDCMD} ${LDFLAGS} -o ${APPNAME:=openssl} openssl.o verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o ca.o pkcs7.o crl2p7.o crl.o rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o s_time.o apps.o s_cb.o s_socket.o app_rand.o version.o sess_id.o ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o ${LIBDEPS} )
c:/users/knispel/appdata/local/android/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot open crtbegin_dynamic.o: No such file or directory
c:/users/knispel/appdata/local/android/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot open crtend_android.o: No such file or directory
c:/users/knispel/appdata/local/android/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -ldl
c:/users/knispel/appdata/local/android/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -lc
c:/users/knispel/appdata/local/android/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -ldl
openssl.o:openssl.c:function lock_dbg_cb: error: undefined reference to ‘fprintf’
openssl.o:openssl.c:function lock_dbg_cb: error: undefined reference to ‘__sF’
openssl.o:openssl.c:function function_LHASH_COMP: error: undefined reference to ‘strncmp’
openssl.o:openssl.c:function do_cmd: error: undefined reference to ‘strncmp’
openssl.o:openssl.c:function do_cmd: error: undefined reference to ‘strcmp’
openssl.o:openssl.c:function do_cmd: error: undefined reference to ‘strcmp’
openssl.o:openssl.c:function do_cmd: error: undefined reference to ‘strcmp’
openssl.o:openssl.c:function do_cmd: error: undefined reference to ‘strcmp’
openssl.o:openssl.c:function do_cmd: error: undefined reference to ‘__sF’
openssl.o:openssl.c:function main: error: undefined reference to ‘getenv’
openssl.o:openssl.c:function main: error: undefined reference to ‘getenv’
openssl.o:openssl.c:function main: error: undefined reference to ‘getenv’
openssl.o:openssl.c:function main: error: undefined reference to ‘fwrite’
openssl.o:openssl.c:function main: error: undefined reference to ‘exit’
openssl.o:openssl.c:function main: error: undefined reference to ‘bsd_signal’
openssl.o:openssl.c:function main: error: undefined reference to ‘getenv’
openssl.o:openssl.c:function main: error: undefined reference to ‘exit’
openssl.o:openssl.c:function main: error: undefined reference to ‘qsort’
openssl.o:openssl.c:function main: error: undefined reference to ‘exit’
openssl.o:openssl.c:function main: error: undefined reference to ‘strlen’
openssl.o:openssl.c:function main: error: undefined reference to ‘fputs’
openssl.o:openssl.c:function main: error: undefined reference to ‘fflush’
openssl.o:openssl.c:function main: error: undefined reference to ‘fgets’
openssl.o:openssl.c:function main: error: undefined reference to ‘__sF’
openssl.o:openssl.c:function main: error: undefined reference to ‘free’
openssl.o:openssl.c:function main: error: undefined reference to ‘malloc’
openssl.o:openssl.c:function main: error: undefined reference to ‘realloc’
verify.o:verify.c:function cb: error: undefined reference to ‘putchar’
verify.o:verify.c:function cb: error: undefined reference to ‘printf’
verify.o:verify.c:function cb: error: undefined reference to ‘__sF’
verify.o:verify.c:function check: error: undefined reference to ‘fprintf’
verify.o:verify.c:function check: error: undefined reference to ‘fwrite’
verify.o:verify.c:function verify_main: error: undefined reference to ‘bsd_signal’
verify.o:verify.c:function verify_main: error: undefined reference to ‘abort’
asn1pars.o:asn1pars.c:function asn1parse_main: error: undefined reference to ‘bsd_signal’
asn1pars.o:asn1pars.c:function asn1parse_main: error: undefined reference to ‘atoi’
….
Подскажите, пожалуйста, в чём может быть дело?
Добрый вечер, возникли такие ошибки при сборке libiconv
$ ./configure —host=arm —prefix=$SR/usr —with-sysroot=$SR
./configure: line 442: sed: command not found
./configure: line 441: expr: command not found
./configure: line 442: sed: command not found
./configure: line 456: sed: command not found
: error: cannot create .lineno; rerun with a POSIX shell
Буду очень рад помощи)
Здравствуйте.
К сожалению, не сталкивался с такими.
Спасибо конечно.
Но я бьюсь уже неделю, чтобы скомпилять QOCI под Андроид.
Вот где гиммор!!! Может быть у Вас получится? Напишите please!