Android MySql (QMysql) драйвер для Qt5.6 на Windows и Linux компиляция

В общем понадобилось портировать одну прогу под Андроид arm7, но она плотненько работает с базой данных, а так как я человек впринципе ленивый, то обёртку для REST API сервера было лень писать, решился на компилирование MySQL плагина, но если бы я знал тогда, что это займёт у меня 20 часов…

В общем вот вам готовый рецепт из 12 шагов для компиляции на Ubuntu и на Windows

Установим инструменты:

  1. Качаем и устанавливаем CMake, у меня 3.5.2
  2. Разумеется Android NDK у вас уже должен быть установлен.
  3. WIN ONLY Качаем и ставим MSYS (отмечаем всё, что можно)
  4. При установке Qt нужно было поставить и исходники (папка qt/5.6/src/qtbase), если нет её, то качаем и ставим через UpdateManager из папки Qt
  5. WIN ONLY Открываем консольку MSYS (c:\mingw\msys\1.0\msys.bat), в дальнейшем все действия будут вестись в ней
  6. 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 запускаем и радуемся =)

Вот как-то так =)

Related posts

QML Сделать задержку перед началом анимации

QtCreator не открывает диалог выбора файлов, проектов, не открывает проект

Сборка Qt 6.8 (Dev) из исходников в Docker контейнере (Linux)

4 комментария

Тимофей 23 февраля 2023 - 11:57
Здравствуйте! При сборке 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' .... Подскажите, пожалуйста, в чём может быть дело?
Лев 29 апреля 2021 - 1:50
Добрый вечер, возникли такие ошибки при сборке 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 Буду очень рад помощи)
Pavelk 29 апреля 2021 - 2:28
Здравствуйте. К сожалению, не сталкивался с такими.
alex_lip 18 мая 2017 - 16:19
Спасибо конечно. Но я бьюсь уже неделю, чтобы скомпилять QOCI под Андроид. Вот где гиммор!!! Может быть у Вас получится? Напишите please!
Add Comment