Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Using external libraries like Thor in Android build  (Read 5546 times)

0 Members and 2 Guests are viewing this topic.

ast

  • Newbie
  • *
  • Posts: 20
    • View Profile
Using external libraries like Thor in Android build
« on: March 03, 2016, 09:23:13 pm »
Hi all,

I am trying to build my SFML project for android and having some problems there.  I have successfully complied SFML for armeabi-v7a and also compiled the SFML example project and installed that on my android device. Works fine thanks to nice example:

https://github.com/SFML/SFML/wiki/Tutorial:-Building-SFML-for-Android

There was a little bit of a hassle on how to install the Android SDK. The working solution was to use stand-alone SDK but to use ndk that came with android-studio. The standalone ndk somehow did not work. But anyway, the build system seems to be ok because I can build android binaries.

My project uses external libraries like Thor and sfml-tmxloader. Now the question is, how can I use these when building for android? I would think it is necessary to build these for armeabi-v7a target and install the libraries to ndk quite similar than in case of installing SFML to ndk. But how to do this?

I have googled around  and tried different things but no luck this far. Would be great if anyone could give some tips how to go forward.  :)

The other thing is how to set up an own android project. I have taken this as a starting point:
http://fr.sfml-dev.org/forums/index.php?topic=18211.msg131094#msg131094

The perfect solution would be to have the same source code in version control and build for PC or android but the android project setup seems to be quite different from normal cmake and this seems may become a problem. But I am not this far yet since I have not succeeded to build for android yet. Maybe the solution is to have the source files, resources etc in place where android wants them to be and try to have a cmake out of source build using the same resources. If anyone has experience on this, would love to hear as well :).

Best regards,
ast

ast

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Using external libraries like Thor in Android build
« Reply #1 on: March 05, 2016, 07:18:09 am »
Would it be possible to just use gcc for arm and build libraries similarly to normal x86 linux things and copy the  resulting library objecs somewhere where android build can find them? If existing cmakelists could be reused would be great.

Or another way just to put the external library source code to same project as the code that uses it and compile and link them all all together. Definetly not the right thing to do but could work also.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Using external libraries like Thor in Android build
« Reply #2 on: March 05, 2016, 12:37:35 pm »
I'm not familiar with C++ for that architecture, but I assume there's a clearly defined way how to link libraries. Have you read the compiler/linker's documentation, or searched for tutorials on the Internet?

Thor's only dependency is SFML (Aurora is shipped along with the source code), other than that it's a pure C++ library. When you're able to compile SFML, the same should be possible with Thor (unless your compiler doesn't support C++11).
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

ast

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Using external libraries like Thor in Android build
« Reply #3 on: March 05, 2016, 09:06:52 pm »
I am not familiar with android either. It seems the building of C++ is niche for android because it is all Java and also because the default build system is now gradle and android-studio it seems that I am trying to do some niche of niches and tutorials seem to concentrate on slightly different things.

Anyway, I have tried building Thor for android following the SFML guide. I first copied android.toolchain.cmake to Thor/cmake/toolchains. Attempt to generate makefiles results in notification that SFML is not found.

ast@lumo ~/src/Thor/build/armeabi-v7a $ cmake -DSFML_ROOT=/media/sf_C_DRIVE/Android/ndk-bundle/sources/sfml -DANDROID_ABI=armeabi-v7a -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchains/android.toolchain.cmake ../..
Could NOT find SFML (missing:  SFML_AUDIO_LIBRARY SFML_GRAPHICS_LIBRARY SFML_WINDOW_LIBRARY SFML_SYSTEM_LIBRARY)

-> SFML directory not found. Set SFML_ROOT to SFML's top-level path (containing "include" and "lib" directories).
-> Make sure the SFML libraries with the same configuration (Release/Debug, Static/Dynamic) exist.

-- Configuring done
-- Generating done
-- Build files have been written to: /home/ast/src/Thor/build/armeabi-v7a
ast@lumo ~/src/Thor/build/armeabi-v7a $
 

I also have defined SFML_ROOT as environment variable but that did not help either. The SFML_ROOT directory contains SFML stuff that to me seems correct.

ast@lumo /media/sf_C_DRIVE/Android/ndk-bundle/sources/sfml $ du -l
5320    ./extlibs/lib/armeabi-v7a
5320    ./extlibs/lib
5321    ./extlibs
128     ./include/SFML/Audio
311     ./include/SFML/Graphics
125     ./include/SFML/Network
197     ./include/SFML/System
106     ./include/SFML/Window
892     ./include/SFML
892     ./include
3307    ./lib/armeabi-v7a
3307    ./lib
9528    .
ast@lumo /media/sf_C_DRIVE/Android/ndk-bundle/sources/sfml $
 

I use g++ that ships with Linux Mint and it can compile C++11 with flag -std=c++11.
« Last Edit: March 05, 2016, 09:24:02 pm by ast »

ast

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Using external libraries like Thor in Android build
« Reply #4 on: March 05, 2016, 09:21:19 pm »
The SFML library objects are as follows:

ast@lumo /media/sf_C_DRIVE/Android/ndk-bundle/sources/sfml/lib/armeabi-v7a $ file *
libsfml-activity.so: ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
libsfml-audio.so:    ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
libsfml-graphics.so: ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
libsfml-main.a:      current ar archive
libsfml-network.so:  ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
libsfml-system.so:   ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
libsfml-window.so:   ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
ast@lumo /media/sf_C_DRIVE/Android/ndk-bundle/sources/sfml/lib/armeabi-v7a $
 

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Using external libraries like Thor in Android build
« Reply #5 on: March 06, 2016, 05:04:55 pm »
It seems the building of C++ is niche for android because it is all Java [...]
It's true that many "typical" apps are written in pure Java, and that the front-end is mostly Java, but there are enough apps that make heavy use of C++. The language has especially gained popularity since C++ is the common denominator for iOS, Android and Windows Phone development. I recall a video (i think it was Microsoft or Google) that claimed many of the most popular apps use C++ in their back-end, but I haven't found it again, so take that with a grain of salt.

Anyway, I have tried building Thor for android following the SFML guide. I first copied android.toolchain.cmake to Thor/cmake/toolchains. Attempt to generate makefiles results in notification that SFML is not found.
I'm not sure if FindSFML is configured properly to find the library on that platform. After double-checking that your configuration is correct, you might have to investigate how other CMake Find modules are written.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

ast

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Using external libraries like Thor in Android build
« Reply #6 on: March 06, 2016, 10:30:53 pm »
It seems that find_path in FindSFML.cmake does not work for some reason. It becomes SFML_INCLUDE_DIR-NOTFOUND

# find the SFML include directory
find_path(SFML_INCLUDE_DIR SFML/Config.hpp
          PATH_SUFFIXES include
          PATHS ${FIND_SFML_PATHS})
 

I overwrite it bluntly as

set(SFML_INCLUDE_DIR /media/sf_C_DRIVE/Android/ndk-bundle/sources/sfml/include/)
 

Then in Thor CMakeLists.txt SFML_FOUND is false and include directories are not set. If I set them anyway, as below, I get Thor compiled.

if(SFML_FOUND)
        include_directories(${SFML_INCLUDE_DIR})
else()
        set(SFML_ROOT "" CACHE PATH "SFML top-level directory")
        message("\n-> SFML directory not found. Set SFML_ROOT to SFML's top-level path (containing \"include\" and \"lib\" directories).")
        message("-> Make sure the SFML libraries with the same configuration (Release/Debug, Static/Dynamic) exist.\n")
endif()

include_directories(${SFML_INCLUDE_DIR}) # Force include directories anyway
 

The obect code is "ELF 32-bit LSB  relocatable, ARM, EABI5 version 1 (SYSV), not stripped", so looks good. However, the linking to the sfml libraries does not work. Probably it would if I knew cmake so well that I could pass the sfml-libraries to linker. Better yet, if I could figure out why find_path did not work, the same thing probably affects find_library as well. I am not very familiar with cmake and debugging is not terribly easy..  :)

ast

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Using external libraries like Thor in Android build
« Reply #7 on: March 07, 2016, 09:41:27 pm »
It seems that I more or less succeeded in build Thor for ARM:

ast@lumo /media/sf_C_DRIVE/Android/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/user/lib $ file libthor.so
libthor.so: ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
 

make install put the resulting .so to rather peculiar place -- hope its ok..

I needed to force SFML_INCLUDE_DIR in FindSFML.cmake

set(SFML_INCLUDE_DIR /media/sf_C_DRIVE/Android/ndk-bundle/sources/sfml/include/)
 

And in root CMakelists.txt set include directories and linked libraries by hand:

include_directories(${SFML_INCLUDE_DIR}) # Force include directories anyway
set(SFML_LIBRARIES  sfml-graphics sfml-window sfml-system sfml-audio sfml-activity sfml-main)
link_directories (/media/sf_C_DRIVE/Android/ndk-bundle/sources/sfml/lib/armeabi-v7a)
 

But still for some reason one function was not found by the linker:

ast@lumo ~/src/Thor/build/armeabi-v7a $ make
Scanning dependencies of target thor
[  3%] Building CXX object src/CMakeFiles/thor.dir/BigTexture.cpp.o
Linking CXX shared library libthor.so
CMakeFiles/thor.dir/BigTexture.cpp.o:BigTexture.cpp:function thor::BigTexture::loadFromFile(std::string const&): error: undefined reference to 'sf::Image::loadFromFile(std::string const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [src/libthor.so] Error 1
make[1]: *** [src/CMakeFiles/thor.dir/all] Error 2
make: *** [all] Error 2
ast@lumo ~/src/Thor/build/armeabi-v7a $
 

After commenting call to this mystery function I got the Thor linked, less this one particular function, maybe I do not need it.  :D

bool BigTexture::loadFromFile(const std::string& filename)
{
        sf::Image image;
        //return image.loadFromFile(filename) && loadFromImage(image);
}
 

ast@lumo ~/src/Thor/build/armeabi-v7a $ make
Scanning dependencies of target thor
[  3%] Building CXX object src/CMakeFiles/thor.dir/BigTexture.cpp.o
Linking CXX shared library libthor.so
[100%] Built target thor
ast@lumo ~/src/Thor/build/armeabi-v7a $
 

It would be nice to know why the automatic find commands of cmake failed and created all this hassle.

 

ast

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Using external libraries like Thor in Android build
« Reply #8 on: March 10, 2016, 10:40:11 pm »
I redid all of the above in native Linux machine. Previous was a virtual box Linux guest running on Windows host. The result was however exactly the same so it seems that virtual machine did not play any role here. I did not expected it to do so.

I am now trying to build sfml-tmxloader. FindSFML did not work but similar path forcing that in Thor case made it possible to generate make files. sfml-tmxloader has pugixml, which is compiled as a library.

ast@superstar ~/src/sfml-tmxloader/build/armeabi-v7a $ make
[  8%] Building CXX object CMakeFiles/pugi.dir/src/pugixml/pugixml.cpp.o
Linking CXX shared library libpugi.so
CMakeFiles/pugi.dir/src/pugixml/pugixml.cpp.o:pugixml.cpp:function pugi::impl::(anonymous namespace)::is_nan(double): error: undefined reference to '__fpclassifyd'
CMakeFiles/pugi.dir/src/pugixml/pugixml.cpp.o:pugixml.cpp:function pugi::impl::(anonymous namespace)::convert_number_to_string_special(double): error: undefined reference to '__fpclassifyd'
collect2: error: ld returned 1 exit status
make[2]: *** [libpugi.so] Error 1
make[1]: *** [CMakeFiles/pugi.dir/all] Error 2
make: *** [all] Error 2
ast@superstar ~/src/sfml-tmxloader/build/armeabi-v7a $
 

It seems that it does not know how to link against math library. What could be the reason that cmake things seems to be broken when cross compiling for android??

ast

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Using external libraries like Thor in Android build
« Reply #9 on: March 12, 2016, 09:19:27 pm »
ast@superstar ~/src/sfml-tmxloader/build/armeabi-v7a $ make VERBOSE=1 pugi

...

Linking CXX shared library libpugi.so
/usr/bin/cmake -E cmake_link_script CMakeFiles/pugi.dir/link.txt --verbose=1
/home/ast/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc  -fPIC -fexceptions -frtti -fpic -Wno-psabi --sysroot=/home/ast/Android/Sdk/ndk-bundle/platforms/android-8/arch-arm -funwind-tables -finline-limit=64 -fsigned-char -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fdata-sections -ffunction-sections -Wa,--noexecstack  -std=c++11  -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-allow-shlib-undefined -Wl,--gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now  -shared -Wl,-soname,libpugi.so -o libpugi.so CMakeFiles/pugi.dir/src/pugixml/pugixml.cpp.o  -L/home/ast/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/user/libs/armeabi-v7a /home/ast/Android/Sdk/ndk-bundle/platforms/android-8/arch-arm/usr/lib/libm.so /home/ast/Android/Sdk/ndk-bundle/platforms/android-8/arch-arm/usr/lib/libz.so  "/home/ast/Android/Sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a" "/home/ast/Android/Sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libsupc++.a" -lm
CMakeFiles/pugi.dir/src/pugixml/pugixml.cpp.o:pugixml.cpp:function pugi::impl::(anonymous namespace)::is_nan(double): error: undefined reference to '__fpclassifyd'
CMakeFiles/pugi.dir/src/pugixml/pugixml.cpp.o:pugixml.cpp:function pugi::impl::(anonymous namespace)::convert_number_to_string_special(double): error: undefined reference to '__fpclassifyd'
collect2: error: ld returned 1 exit status
make[3]: *** [libpugi.so] Error 1
make[3]: Leaving directory `/home/ast/src/sfml-tmxloader/build/armeabi-v7a'
make[2]: *** [CMakeFiles/pugi.dir/all] Error 2
make[2]: Leaving directory `/home/ast/src/sfml-tmxloader/build/armeabi-v7a'
make[1]: *** [CMakeFiles/pugi.dir/rule] Error 2
make[1]: Leaving directory `/home/ast/src/sfml-tmxloader/build/armeabi-v7a'
make: *** [pugi] Error 2
ast@superstar ~/src/sfml-tmxloader/build/armeabi-v7a $
 

There was libm.so with full path, which I added by hand:

-L ... /home/ast/Android/Sdk/ndk-bundle/platforms/android-8/arch-arm/usr/lib/libm.so
 

But still it did not found the '__fpclassifyd'. There was also -lm in the end, which I think links the math library normally (works perfectly when building for Linux desktop).

If I check what libm's are present in the referenced directory I find couple.
ast@superstar ~/Android/Sdk/ndk-bundle/platforms/android-8/arch-arm/usr/lib $ ls -lh libm*
-rw-r--r-- 1 ast ast 973K maali 10 15:56 libm.a
-rw-r--r-- 1 ast ast 1,3M maali 10 15:55 libm_hard.a
-rwxr-xr-x 1 ast ast  13K maali 10 15:57 libm.so
ast@superstar ~/Android/Sdk/ndk-bundle/platforms/android-8/arch-arm/usr/lib $
 

Grepping the missing function finds it in static libraries. The shared library does not match but it is only 13K so I guess the actual binary code is somewhere else. (where?)
ast@superstar ~/Android/Sdk/ndk-bundle/platforms/android-8/arch-arm/usr/lib $ grep  __fpclassifyd *
Binary file libm.a matches
Binary file libm_hard.a matches
ast@superstar ~/Android/Sdk/ndk-bundle/platforms/android-8/arch-arm/usr/lib $
 

Any of the tons of sfml android developers there ever stumbled on similar problems? ;) It seems likely that all these cmake woes are caused by some false configuration. Would just like to know what..