Sunday, October 26, 2014

How to build LibIconv for Android on Windows

Prerequisites:

MSYS
MinGW
Android NDK
LibIconv source code


Download and extract LibIconv.

Let's assume that we have the following directory structure:
LibIconv in: D:\temp\android\libiconv-1.14
Android NDK in: D:\tools\android\android-ndk-r10b-win
MinGW in: D:\tools\mingw482_32

Start a MSYS console.

Add MinGW to PATH:
 export PATH=$PATH:/d/mingw482_32/bin  

Set Android NDK environment variables:
 export ANDROID_NDK_ROOT=/d/tools/android/android-ndk-r10b-win  
 export SR="$ANDROID_NDK_ROOT"/platforms/android-12/arch-arm/usr  
 export BR="$ANDROID_NDK_ROOT"/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/arm-linux-androideabi-  
 export CC="$BR"gcc  
 export AR="$BR"ar  
 export STRIP="$BR"strip  
 export RANLIB="$BR"ranlib  
 export OBJDUMP="$BR"objdump  
 export CC="$BR"gcc CFLAGS=--sysroot=$SR CPP="$BR"cpp CPPFLAGS=$CFLAGS  

Go to libiconv directory:
 cd /d/temp/android/libiconv-1.14   

Configure:
 ./configure --host=arm --with-sysroot=$SR  

Make:
 make  


You can also download a prebuild version from here (libiconv-1.14_android.7z).

Thursday, October 2, 2014

How to build Boost for Android

What we need:
Boost (http://switch.dl.sourceforge.net/project/boost/boost/1.56.0/boost_1_56_0.7z)
A compiler (Visual C++ 2010)
Android NDK (http://dl.google.com/android/ndk/android-ndk32-r10b-windows-x86.zip)

Download and extract Boost (ex: D:\boost; you can extract only boost, libs, tools subdirs and the files in the main dir).


Download and unzip Android NDK (ex: D:\android-ndk-r10b).



Go to  Boost_dir\tools\build\src and create a new file,
 user-config.jam  

Open that file with a text editor and add:

 import os ;  
 androidNDKRoot = D:/android-ndk-r10 ;
  using gcc : android :  
    $(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/arm-linux-androideabi-g++ :  
    <compileflags>--sysroot=$(androidNDKRoot)/platforms/android-9/arch-arm  
    <compileflags>-mthumb  
    <compileflags>-Os  
    <compileflags>-fno-strict-aliasing  
    <compileflags>-O2  
    <compileflags>-DNDEBUG  
    <compileflags>-g  
    <compileflags>-lstdc++  
    <compileflags>-I$(androidNDKRoot)/sources/cxx-stl/gnu-libstdc++/4.8/include  
    <compileflags>-I$(androidNDKRoot)/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/include  
    <compileflags>-D__GLIBC__   
    <compileflags>-D__arm__  
    <archiver>$(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/arm-linux-androideabi-ar  
    <ranlib>$(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/arm-linux-androideabi-ranlib  
      ;  

Save and close that file.

Open Visual Studio Command Prompt.

Go to boost dir (cd  D:\boost).

Execute:
 bootstrap  



Execute:
 b2 ^  
 --without-python ^  
 --prefix=.\out\ ^
 --build-dir=.\build ^  
 variant=release ^  
 link=static runtime-link=static ^  
 toolset=gcc-android target-os=linux ^  
 threading=multi --stagedir=android stage


If everything went well, you will have the libs in "android" folder.


Monday, September 29, 2014

How to solve: defaultServiceProvider::requestService(): no service found for - "org.qt-project.qt.mediaplayer"

When we try to run a Qt application that uses QMediaPlayer on Windows XP, we get:

defaultServiceProvider::requestService(): no service found for - "org.qt-project.qt.mediaplayer"

From: https://bugreports.qt-project.org/browse/QTBUG-28881
"On Windows XP, Qt Multimedia uses DirectShow (and WMF for Windows Vista and later). The DirectShow plugin binary is not included in the Qt 5.0 package (only the WMF plugin is)."

So prebuild binaries from qt-project.org does not contain the DirectShow plugin, so we need to build one ourself.
For that, we need a compiler and Qt Multimedia source code.
The source code can be obtained from qt-project.org, http://download.qt-project.org/official_releases/qt/5.3/5.3.2/submodules/qtmultimedia-opensource-src-5.3.2.7z ,
or from https://gitorious.org/qt/qtmultimedia.git (in that case we also need PERL in path).

 mkdir BuildDirectShowPlugin  
 cd BuildDirectShowPlugin  
 /path/to/qt/bin/qmake /path/to/multimedia/source/src/plugins/directshow/directshow.pro  
 nmake (make, mingw32-make)  


Copy dsengine.dll, dsengined.dll and dsengined.pdb over the old files in /path/to/qt/plugins/mediaservice .

Thursday, September 25, 2014

How to build MySQL plugin for QtAndroid on Windows (step by step tutorial, with sample app)

Prerequisites:

MSYS
MinGW
Android NDK
Cmake
Qt source code
Qt for Android
LibIconv source code
MariaDB Client Library source code


First, you need to download and build LibIconv (details here), or you can download a prebuild version from here.

Download and extract MariaDB Client Library.

Let's assume that we have the following directory structure:
Android NDK in: D:\tools\android\android-ndk-r10b-win
MinGW in: D:\tools\mingw482_32
Cmake in: D:\tools\cmake-2.8
Qt source code in: D:\tools\qtbase-opensource-src-5.3.2
Qt for Android in: D:\tools\Qt5.3.2\android_armv5
LibIconv header files in: D:\temp\android\libiconv-1.14_android\include
LibIconv lib file (libiconv.a) in: D:\temp\android\libiconv-1.14_android\lib
MariaDB Client Library in: D:\temp\android\mariadb_client-2.0.0-src


Go to  MariaDB include subdirectory, D:\temp\android\mariadb_client-2.0.0-src\include .

Open my_global.h with a text editor and add:
 #ifndef ushort  
 #define ushort uint16  
 #endif  

Now open mariadb_client-2.0.0-src\libmariadb\CMakeLists.txt
Change:
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include   
           ${ZLIB_INC}  
           ${CMAKE_SOURCE_DIR}/libmariadb)  
to:
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include   
           ${ZLIB_INC}  
           ${CMAKE_SOURCE_DIR}/libmariadb  
           "/d/temp/android/libiconv-1.14_android/include")  
On line 175, change:
 SET_TARGET_PROPERTIES(libmariadb PROPERTIES VERSION   
   ${CPACK_PACKAGE_VERSION_MAJOR}  
   SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})  
to:
 #SET_TARGET_PROPERTIES(libmariadb PROPERTIES VERSION   
 #  ${CPACK_PACKAGE_VERSION_MAJOR}  
 #  SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})  



Open a MSYS console.

Add MinGW and Cmake to PATH:
 export PATH=$PATH:/d/tools/mingw482_32/bin  
 export PATH=$PATH:/d/tools/cmake-2.8/bin  

Set the enviroment variables:
 export ICONV_LIB=/d/temp/android/libiconv-1.14_android/lib/libiconv.a   
 export ANDROID_NDK_ROOT=/d/tools/android/android-ndk-r10b-win   
 export SR="$ANDROID_NDK_ROOT"/platforms/android-12/arch-arm/usr   
 export BR="$ANDROID_NDK_ROOT"/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/arm-linux-androideabi-  

Go to MariaDB directory:
 cd /d/temp/android/mariadb_client-2.0.0-src   

 mkdir build && cd build  

Run cmake:
 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 \  
 -DWITH_EXTERNAL_ZLIB=ON \  
 -DZLIB_INCLUDE_DIR=$SR/usr/include \  
 -DZLIB_LIBRARY=$SR/usr/lib/libz.so \  
 -DICONV_LIBRARIES=$ICONV_LIB \  
 -DCMAKE_SYSTEM_NAME=Linux  

Build:
 make  

Rename the lib:
 mv libmariadb/libmariadbclient.a libmariadb/libmysqlclient.a  


Now, let's build the plugin

 mkdir QtMySqlDriver && cd QtMySqlDriver  

 /d/tools/Qt5.3.2/android_armv5/bin/qmake.exe \  
 /d/tools/qtbase-opensource-src-5.3.2/src/plugins/sqldrivers/mysql/mysql.pro \  
 INCLUDEPATH+="../include ../../include" \  
 LIBPATH+="/d/temp/android/libiconv-1.14_android/lib ../libmariadb" \  
 LIBS+="-lmysqlclient -liconv"  

 make  

Move libqsqlmysql.so into QtInstallDir/plugins/sqldrivers (D:\tools\Qt5.3.2\android_armv5\plugins\sqldrivers).
Now androiddeployqt tool will bundle the plugin with the app.

You can download the prebuild plugin here (libqsqlmysql.7z 544 KB).


Here is a sample app running on Android 2.3:
Downloads:
Sample Android app (TestMYSQL.apk) 6,95 MB
Sample app source code (TestMYSQL-src.7z) 2,36 KB