2

I have created a shared library using Qt Creator and I have added the Android SDK, Android NDK and Android Qt kit. Then I compiled my library for Android successfully. I even tested it in an Android application successfully.

As I am not using the Qt libraries, my library does not depend on huge Qt libraries. But unexpectedly, here is my dependencies:

[matin@Lenovo-X1-Fedora ~]$ ndk-depends libMatinChess.so 
WARNING: Could not find library: libgnustl_shared.so
libMatinChess.so
libz.so
libstdc++.so
libm.so
liblog.so
libgnustl_shared.so
libdl.so
libc.so

And when I checked the libgnustl_shared.so it has more than 5 MBs size. So I have to place this huge library next to my tiny library in every project.

Another option is to link it statically. I previously asked the question about how is it possible to link a dependency statically and I figured out that it is possible by adding the QMAKE_LFLAGS += -static in my .pro file:

This flags works perfect and removes the dependency of stdc++ on Windows compilation. But in android I get the following errors:

error: cannot find -lgnustl_shared
error: cannot find -llog
error: cannot find -lz
error: cannot find -ldl

I searched my android-ndk folder and I realized that there is no liblog.a, libz.a and libdl.a files located in it but there is a libgnustl_static.a file.

I tried to add it using LIBS += -Lpath/to/libdir -lgnustl_static but the result was the same.

There is a solution in CMake that was mentioned in the previous question as a comment that there is the option to set APP_STL := gnustl_static in the makefile. But there seems to be no equivalent in QMake.

And a complicated issue is that when I use CONFIG += static, it compiles successfully but my library is not shared anymore. it becomes a static library.

How can I link gnustl statically so that my library works with no other dependencies?

Edit

I read the compile output and found the following line:

/home/matin/Applications/android-ndk-r13b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ --sysroot=/home/matin/Applications/android-ndk-r13b/platforms/android-9/arch-arm/ -static -Wl,--no-undefined -Wl,-z,noexecstack -shared -Wl,-soname,libMatinChess.so -o libMatinChess.so matinchessdll.o bishop.o piece.o board.o king.o memorymanager.o pawn.o queen.o blackpawn.o knight.o rook.o whitepawn.o squarelist.o game.o boardhistory.o -L/home/matin/Applications/android-ndk-r13b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a -L/home/matin/Applications/android-ndk-r13b/platforms/android-9/arch-arm//usr/lib -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc

And I was not able to remove gnustl_shared using LIB -= -lgnustl_shared

Community
  • 1
  • 1
Matin Lotfaliee
  • 1,745
  • 2
  • 21
  • 43

2 Answers2

0

By reading the compile output, I executed the following command manually and created my library with 1 MB size. And it works correctly.

/home/matin/Applications/android-ndk-r13b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ --sysroot=/home/matin/Applications/android-ndk-r13b/platforms/android-9/arch-arm/ -Wl,--no-undefined -Wl,-z,noexecstack -shared -Wl,-soname,libMatinChess.so -o libMatinChess.so matinchessdll.o bishop.o piece.o board.o king.o memorymanager.o pawn.o queen.o blackpawn.o knight.o rook.o whitepawn.o squarelist.o game.o boardhistory.o -L/home/matin/Applications/android-ndk-r13b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a -L/home/matin/Applications/android-ndk-r13b/platforms/android-9/arch-arm//usr/lib -lgnustl_static

But still I don't know how to automate this command in QMake

Matin Lotfaliee
  • 1,745
  • 2
  • 21
  • 43
0

Below script android.pri did help for me which I include in my projects to get rid of some QtCreator related bugs:

## this file changes many values set by "Qt/mkspec/android-g++/qmake.conf"
## since the failed to work with newest Android SDK and/or NDK
##
## use below lines before including this file
##
#ANDROID_API = 21
#ANDROID_ARCH = armeabi-v7a

#do you after using this have still problems?
#there is an bug inside "QtCreator" (not inside "Gradle")
#   that leads to .o and .so files get not found
#solved: not required to change "QMAKE_LIBDIR" just open "AndroidManifest.xml"
#   and change "Minimum required SDK" to "not set" save then restore to last
#   value and save agian to force "QtCreator" update

isEmpty(ANDROID_API): ANDROID_API = 21
isEmpty(ANDROID_ARCH): ANDROID_ARCH = armeabi-v7a #ANDROID_TARGET_ARCH=armeabi-v7a

#remove old values
CONFIG         -= $$ANDROID_PLATFORM
QMAKE_CFLAGS   -= --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
QMAKE_CXXFLAGS -= --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
QMAKE_LFLAGS   -= --sysroot=$$ANDROID_PLATFORM_ROOT_PATH

#NDK Root directory
ANDROID_NDK_ROOT = $$(ANDROID_NDK_ROOT) #first try Environment variable
isEmpty(ANDROID_NDK_ROOT) | !exists($$ANDROID_NDK_ROOT) {
    ANDROID_NDK_ROOT = D:/android/sdk/ndk-bundle }
NDK_ROOT = $$ANDROID_NDK_ROOT

#API Level
ANDROID_NDK_PLATFORM = android-$$ANDROID_API
ANDROID_PLATFORM = $$ANDROID_NDK_PLATFORM
CONFIG  += $$ANDROID_PLATFORM
DEFINES += __ANDROID_API__=$$ANDROID_API

#Architecture
ANDROID_TARGET_ARCH = $$ANDROID_ARCH
equals(ANDROID_TARGET_ARCH, x86): ANDROID_ARCHITECTURE = x86
else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_ARCHITECTURE = x86_64
else: equals(ANDROID_TARGET_ARCH, mips): ANDROID_ARCHITECTURE = mips
else: equals(ANDROID_TARGET_ARCH, mips64): ANDROID_ARCHITECTURE = mips64
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_ARCHITECTURE = arm64
else: ANDROID_ARCHITECTURE = arm

#API Path
ANDROID_PLATFORM_ROOT_PATH  = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/
ANDROID_PLATFORM_PATH  = $$ANDROID_PLATFORM_ROOT_PATH/usr
QMAKE_CFLAGS   += --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
QMAKE_CXXFLAGS += --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
QMAKE_LFLAGS   += --sysroot=$$ANDROID_PLATFORM_ROOT_PATH

# used to compile platform plugins for android-4 and android-5
QMAKE_ANDROID_PLATFORM_INCDIR = $$NDK_ROOT/sysroot/usr/include #headers bundled
QMAKE_ANDROID_PLATFORM_LIBDIR = $$ANDROID_PLATFORM_PATH/lib #same as before

ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH
ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include

equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \
    QMAKE_ANDROID_PLATFORM_LIBDIR = $${QMAKE_ANDROID_PLATFORM_LIBDIR}64

#additionl fix

QMAKE_CFLAGS += -Wno-attributes #ignore Android Macros
QMAKE_CFLAGS += \
    -Wno-unused-parameter \
    -Wno-unused-variable \
    -Wno-unused-but-set-variable \
    -Wno-unused-value \
    -Wno-unused-function

INCLUDEPATH += $$ANDROID_NDK_ROOT/sysroot/usr/include
INCLUDEPATH += $$ANDROID_NDK_ROOT/sysroot/usr/include/arm-linux-androideabi

## you most times need set "ANDROID_PACKAGE_SOURCE_DIR" manualys
isEmpty(ANDROID_PACKAGE_SOURCE_DIR) {
    DISTFILES += \
        $$PWD/res/android/AndroidManifest.xml \
        $$PWD/res/android/gradle/wrapper/gradle-wrapper.jar \
        $$PWD/res/android/gradlew \
        $$PWD/res/android/res/values/libs.xml \
        $$PWD/res/android/build.gradle \
        $$PWD/res/android/gradle/wrapper/gradle-wrapper.properties \
        $$PWD/res/android/gradlew.bat

    ANDROID_PACKAGE_SOURCE_DIR = $$PWD/res/android

    !build_pass:warning(no ANDROID_PACKAGE_SOURCE_DIR defaulted to $$ANDROID_PACKAGE_SOURCE_DIR)
}
#ANDROID_EXTRA_LIBS = $$PWD/libTest.so ## you may need
#ANDROID_DEPLOYMENT_SETTINGS_FILE = $$PWD/android-settings.json ## no need ever

#QML_IMPORT_PATH
#QML_DESIGNER_IMPORT_PATH
#QMAKE_PROJECT_NAME

#isEmpty(ANDROID_PACKAGE_SOURCE_DIR) {
#    # note that $$PWD/android/assets directory is "QFile::ReadOnly" on android
#    android: varDirInstall.path =/assets
#    else: varDirInstall.path =$$OUT_PWD
#
#    varDirInstall.files = $$files($$PWD/android/assets)
#    win32: varDirInstall.files ~= s|\\\\|/|g
#    varDirInstall.depends += FORCE
#    INSTALLS += varDirInstall
#}

usage sample:

ANDROID_API = 21
ANDROID_ARCH = armeabi-v7a
include($$PWD/android.pri)

but I do get below error some times any way for TEMPLATE = app:

No Android arch set by the .pro file. Error while building/deploying project vpnAndroid (kit: Qt5_android_armeabi-v7a) When executing step "Deploy to Android device"

This special QtCreator related bug costs time to fix:

  1. Close IDE and delete all the QtCreator setting files (in windows "C:\Users\Admin\UserName\Roaming\QtProject")
  2. Start IDE again and reconfigure Android Paths, Compilers, Debugers and Kits in this order
  3. Close IDE to save changes
  4. Backup the folder mentioned before to save time see below:

the QtCreator plugins related to Android do store there failure in settings and so you need to backup since the plugins may do that again

Top-Master
  • 7,611
  • 5
  • 39
  • 71