Search code examples
androidqtandroid-ndkqmakestatic-linking

How to create a single native shared library with no dependency for Android using Qt Creator


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


Solution

  • 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