Mert
Mert

Reputation: 635

How to build boost for android as shared library with c++11 support

I am trying to build boost_1.60.0 (as shared library) for android with c++11 support. I am using the latest ndk (currently android-ndk-r10e). The build host is Windows-10.

This is for a non-opensource project. So as far as I understand I cannot use gnustl_shared, and I need to use c++_shared as the android c++ runtime.

my project-config.jam looks like this:

androidNDKRoot = c:/android-ndk-r10e ;
 using gcc : android :
     $(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ :
      <root>$(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/
      <compileflags>-MMD
      <compileflags>-MP
      <compileflags>-MF
      <compileflags>-fpic 
      <compileflags>-ffunction-sections 
      <compileflags>-funwind-tables 
      <compileflags>-fstack-protector 
      <compileflags>-no-canonical-prefixes 
      <compileflags>-march=armv5te 
      <compileflags>-mtune=xscale 
      <compileflags>-msoft-float 
      <compileflags>-fno-rtti 
      <compileflags>-mthumb 
      <compileflags>-Os 
      <compileflags>-g 
      <compileflags>-DNDEBUG 
      <compileflags>-fomit-frame-pointer 
      <compileflags>-fno-strict-aliasing 
      <compileflags>-finline-limit=64
      <compileflags>-IC:/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include
      <compileflags>-IC:/android-ndk-r10e/sources/cxx-stl/llvm-libc++/../llvm-libc++abi/libcxxabi/include
      <compileflags>-IC:/android-ndk-r10e/sources/cxx-stl/llvm-libc++/../../android/support/include
      <compileflags>-IC:/android-ndk-r10e/platforms/android-9/arch-arm/usr/include
      <compileflags>-Wa,--noexecstack 
      <compileflags>-Wformat 
      <compileflags>-Werror=format-security
      <compileflags>-DUNIX 
      <compileflags>-DANDROID 
      <compileflags>-Wl,--no-undefined
      <cxxflags>-fexceptions 
      <linkflags>-lc++_shared
      <archiver>$(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-ar
      <ranlib>$(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-ranlib
        ;        

the build command is:

b2 --toolset=gcc-android cxxflags="-std=c++11 " --prefix=..\boost_android_arm --builddir=./boost_android_arm/builddir target-os=linux --with-filesystem define=BOOST_FILESYSTEM_VERSION=3 link=shared runtime-link=shared threading=multi 

In order to determine the parameters in the project-config.jam I've build a sample shared library using the ndk-build, get its debug messages, and extracted the compile and link commands it uses.

compile:

C:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin\arm-linux-androideabi-g++.exe,C:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ -MMD -MP -MF ./obj/local/armeabi/objs/someLib/./Unity1.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -fno-rtti -mthumb -Os -g -DNDEBUG -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Ijni/../../library/../../../../ -Ijni/../../library/../../../../src/ -IC:/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include -IC:/android-ndk-r10e/sources/cxx-stl/llvm-libc++/../llvm-libc++abi/libcxxabi/include -IC:/android-ndk-r10e/sources/cxx-stl/llvm-libc++/../../android/support/include -Ijni/../../library -DANDROID -DHAVE_CONFIG_H -DSESTEK_ANDROID_XERCES_HACK -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -fno-strict-aliasing -frtti -fexceptions -DUNIX -DANDROID -IC:/android-ndk-r10e/platforms/android-9/arch-arm/usr/include -c jni/../../library/./Unity1.cpp -o ./obj/local/armeabi/objs/someLib/./Unity1.o,...)

link:

C:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin\arm-linux-androideabi-g++.exe,C:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ -Wl,-soname,libsomeLib.so -shared --sysroot=C:/android-ndk-r10e/platforms/android-9/arch-arm ./obj/local/armeabi/objs/someLib/./Unity1.o -lgcc ./obj/local/armeabi/libc++_shared.so -no-canonical-prefixes -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -mthumb -lc -lm -o ./obj/local/armeabi/libsomeLib.so,...)

For brevity I've only build filesystem for this trial but in the end I plan to build at least thread, filesystem, date_time, asio and log libraries.
Finally the error I get is as follows.

...patience...
...found 660 targets...
...updating 13 targets...
gcc.compile.c++ bin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi\error_code.o
gcc.link.dll bin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi\libboost_system-gcc-mt-1_60.so.1.60.0
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot open crtbegin_so.o: No such file or directory
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -lrt
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot open crtend_so.o: No such file or directory
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -lc++_shared
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -lstdc++
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -lm
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -lc
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -ldl
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -lc
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: bin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi\error_code.o: requires unsupported dynamic reloc R_ARM_REL32; recompile with -fPIC
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: bin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi\error_code.o: requires unsupported dynamic reloc R_ARM_REL32; recompile with -fPIC
c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld.exe: error: bin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi\error_code.o: requires unsupported dynamic reloc R_ARM_REL32; recompile with -fPIC
    ./boost/system/detail/error_code.ipp:458: error: undefined reference to '__dso_handle'
    ./boost/system/detail/error_code.ipp:464: error: undefined reference to '__dso_handle'
    ./boost/system/detail/error_code.ipp:158: error: undefined reference to '__dso_handle'
collect2.exe: error: ld returned 1 exit status
    "c:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++"    -o "bin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi\libboost_system-gcc-mt-1_60.so.1.60.0"  -shared -Wl,--start-group "bin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi\error_code.o"  -Wl,-Bstatic  -Wl,-Bdynamic -lrt -Wl,--end-group -lc++_shared -pthread
...failed gcc.link.dll bin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi\libboost_system-gcc-mt-1_60.so.1.60.0...
...skipped <pstage\lib>libboost_system-gcc-mt-1_60.so.1.60.0 for lack of <pbin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi>libboost_system-gcc-mt-1_60.so.1.60.0...
gcc.compile.c++ bin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi\codecvt_error_category.o
gcc.compile.c++ bin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi\operations.o
gcc.compile.c++ bin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi\path.o
gcc.compile.c++ bin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi\path_traits.o
gcc.compile.c++ bin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi\portability.o
gcc.compile.c++ bin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi\unique_path.o
gcc.compile.c++ bin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi\utf8_codecvt_facet.o
gcc.compile.c++ bin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi\windows_file_codecvt.o
...skipped <pbin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi>libboost_filesystem-gcc-mt-1_60.so.1.60.0 for lack of <pbin.v2\libs\system\build\gcc-android\release\target-os-linux\threading-multi>libboost_system-gcc-mt-1_60.so.1.60.0...
...skipped <pstage\lib>libboost_filesystem-gcc-mt-1_60.so.1.60.0 for lack of <pbin.v2\libs\filesystem\build\gcc-android\release\target-os-linux\threading-multi>libboost_filesystem-gcc-mt-1_60.so.1.60.0...
...failed updating 1 target...
...skipped 3 targets...
...updated 9 targets...

The error tells that it needs the directory to find the necessary libraries, but the problem is that under android ndk there are several files with names rt and crtbegin_so.o and such. I guess I need to make the compiler determine the correct directory itself.

With all being said what I need actually is to build boost shared libraries for android with c++11 support. So I may accept your help either by pointing me in the right direction using the above build parameters or providing me a working sample so I can work out the details myself.

Oh also one more thing: if I use link=static instead of link=shared in the build command the build succeeds. But I have not tried the produced static libraries.

Upvotes: 17

Views: 12315

Answers (4)

leanid.chaika
leanid.chaika

Reputation: 2462

My answer for me in future. How to build latest Boost(1.79.0) with latest NDK(24.0) on Windows PC for Android.

  1. Go to your downloaded boost_1_79_0 unpacked directory and build b2 tool:
.\bootstrap.bat
  1. Check b2 tools is ready:
b2 --version
B2 4.8-git   <-- possible output
  1. create file user-config.jam in %HOME% directory with content like that(example):
using clang : arm64 : c\:/Users/l_chayka/Downloads/android-ndk-r24/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android21-clang++.cmd : <cxxflags>-std=c++20 ;

using clang : arm : c\:/Users/l_chayka/Downloads/android-ndk-r24/toolchains/llvm/prebuilt/windows-x86_64/bin/armv7a-linux-androideabi21-clang++.cmd : <cxxflags>-std=c++20 ;

using clang : x86 : c\:/Users/l_chayka/Downloads/android-ndk-r24/toolchains/llvm/prebuilt/windows-x86_64/bin/i686-linux-android21-clang++.cmd : <cxxflags>-std=c++20 ;

using clang : x86_64 : c\:/Users/l_chayka/Downloads/android-ndk-r24/toolchains/llvm/prebuilt/windows-x86_64/bin/x86_64-linux-android21-clang++.cmd : <cxxflags>-std=c++20 ;
  1. Go to boost root and try to build for every Android architecture (arm, arm64, x86, x86_64) example:
c:\Users\l_chayka\Downloads\boost_1_79_0>b2.exe toolset=clang-x86_64 target-os=android link=static variant=debug threading=multi --layout=versioned --prefix=c:/boost-x64_86/ install

c:\Users\l_chayka\Downloads\boost_1_79_0>b2.exe toolset=clang-x86 target-os=android link=static variant=debug threading=multi --layout=versioned --prefix=c:/boost-x86/ install 

c:\Users\l_chayka\Downloads\boost_1_79_0>b2.exe toolset=clang-arm target-os=android link=static variant=debug threading=multi --layout=versioned --prefix=c:/boost-arm/ install

c:\Users\l_chayka\Downloads\boost_1_79_0>b2.exe toolset=clang-arm64 target-os=android link=static variant=debug threading=multi --layout=versioned --prefix=c:/boost-arm64/ install
  1. Now check you instalation prefix path.

Upvotes: 0

Gurdil
Gurdil

Reputation: 33

user-config.jam

If you want to find boost from cmake(find_package) you must use the version of compiler, and not android like the top answer, in your user-config.jam like below according to boost doc.

androidNDKRoot = /path/to/ndk-R13-standalone ;

using clang : 8.0.1
:
$(androidNDKRoot)/bin/arm-linux-androideabi-clang++
:
;

Upvotes: 0

Cameron Lowell Palmer
Cameron Lowell Palmer

Reputation: 22245

Building Boost on Linux using the NDK

I know you're asking about Windows, but I wanted to do this on macOS and it failed with nearly the exact error. I finally broke down and did it on my linode server it worked without a problem. This says to me that they aren't really doing a good job of testing other platforms. Compiling static only on macOS works as you also discovered on Windows.

Point of reference

  • NDK R13
  • Boost 1.62.0
  • Tested with clang++; g++ also works

If you're wondering why I'm using clang, the Release Notes have the following message:

GCC is no longer supported. It will not be removed from the NDK just yet, but is no longer receiving backports. It cannot be removed until after libc++ has become stable enough to be the default, as some parts of gnustl are still incompatible with Clang. It will likely be removed after that point.

user-config.jam

I placed this file in my home directory. Yuck.

androidNDKRoot = /path/to/ndk-R13-standalone ;

using clang : android
:
$(androidNDKRoot)/bin/arm-linux-androideabi-clang++
:
;

Modifying libtool.m4 in boost to avoid versioning of the libraries

libtool.m4 under tools/build/src/engine/boehm_gc/libtool.m4 in the boost source has no reference to android and you'll need to change version_type=linux in the section linux*) to version_type=none. This will cause symbolic links to appear without the version number appended to the end linked to the versioned shared libraries in the output.

Building

Target OS MUST be android to avoid the -lrt flag being passed which will cause shared linking to fail.

./b2 \
   -d+2 \
   -j 4 \
   --reconfigure \
   target-os=android \
   toolset=clang-android \
   include=${ANDROID_NDK_STANDALONE}/include/c++/4.9.x \
   link=static,shared \
   variant=debug,release \
   threading=multi \
   --layout=versioned \
   --prefix=${BOOST_INSTALL_DIR} \
   install

Upvotes: 10

Patr
Patr

Reputation: 752

A relevant information is here (Boost for Android), where they have been able to successfully build the shared libraries, but it seems that the resulting files have a version suffix which android can't handle. Also one can't just rename the binary because the file name is hardcoded in it. One way out, as per the last post, is to set the variable version_type to none (version_type=none) in the linux section of file. In your case, the build setup could be a little different, but it may be worthwhile to take a look at the changes they made at that discussion.

Upvotes: 4

Related Questions