Skip to content

Instantly share code, notes, and snippets.

@donaldmunro
Last active January 18, 2023 22:25
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save donaldmunro/33393dbe3d4910dcf984ef0ed4608c63 to your computer and use it in GitHub Desktop.
Save donaldmunro/33393dbe3d4910dcf984ef0ed4608c63 to your computer and use it in GitHub Desktop.
Compile Boost for Android

Compiling Boost for Android

  1. Download Boost and cd to base directory.

  2. Create Android toolchains for desired architectures by running a script as below:

    NDK=/opt/android-sdk/ndk-bundle/
    TOOLCHAINS="$PWD/toolchains/"
    rm -rf $TOOLCHAINS
    mkdir $TOOLCHAINS
    
    $NDK/build/tools/make_standalone_toolchain.py --arch arm64 --stl=libc++ --install-dir $TOOLCHAINS/android-toolchain-arm64
    
    $NDK/build/tools/make_standalone_toolchain.py --arch arm --stl=libc++ --api=21 --install-dir $TOOLCHAINS/android-toolchain-arm
    
    $NDK/build/tools/make_standalone_toolchain.py --arch x86 --stl=libc++ --api=21 --install-dir $TOOLCHAINS/android-toolchain-x86
    
    $NDK/build/tools/make_standalone_toolchain.py --arch x86_64 --stl=libc++ --install-dir $TOOLCHAINS/android-toolchain-x86_64
  3. Create a user-config.jam file, run bootstrap.sh followed by the bootstrap created b2.sh script for each architecture as in the script below: (Remember to update the boost modules to build in the ./bootstrap.sh line near the bottom, remembering that header only libraries should not go in the list eg coroutine2). Also check that you don't have a user-config.jam in your home directory which would override the local one.

    ARM64=1
    ARM32_7A=1
    ARM32=1
    X86_64=1
    # Note I can't get context's asm to work for 32 bit x86 so context and
    # dependencies such as fiber and coroutine1/2 will probably not work.
    X86=1
    
    BUILD_DIR=android-build
    BUILD_TYPE=debug # or release
    LINK_TYPE=static # or shared
    #See http://www.boost.org/build/doc/html/bbv2/overview/invocation.html for other b2 properties
    
    #TODO: Some of the compiler options for gcc give warnings for clang.
    
    cat > tools/build/src/user-config.jam << 'EOF'
    # ------------------
    # Android configurations.
    # ------------------
    
    import os ;
    
    local NDK_ROOT = /opt/android-sdk/ndk-bundle/ ;
    
    #================================================================================
    
    local ANDROID_TOOLCHAIN_ARM64 = android-toolchain-arm64 ;
    
    using clang : arm64_v8a
    :
    toolchains/android-toolchain-arm64/bin/aarch64-linux-android-clang++
    :
    <archiver>toolchains/android-toolchain-arm64/bin/aarch64-linux-android-ar
    #<assembler>toolchains/android-toolchain-arm64/bin/aarch64-linux-android-as
    <compileflags>-fexceptions
    <compileflags>-frtti
    <compileflags>-fpic
    <compileflags>-ffunction-sections
    <compileflags>-funwind-tables
    <compileflags>-fstack-protector
    #<compileflags>-Wno-psabi
    <compileflags>-march=armv8-a
    <compileflags>-mtune=cortex-a53
    <linkflags>-march=armv8-a
    <compileflags>-Os
    <compileflags>-fno-short-enums
    <compileflags>-fomit-frame-pointer
    <compileflags>-fno-strict-aliasing
    #<compileflags>-finline-limit=64
    <compileflags>-DANDROID
    <compileflags>-D__ANDROID__
    <compileflags>-DNDEBUG
    <compileflags>-O2
    <compileflags>-g
    <root>toolchains/android-toolchain-arm64/sysroot
    # @Moss - Above are the 'official' android flags
    <architecture>arm
    <compileflags>-fvisibility=hidden
    <compileflags>-fvisibility-inlines-hidden
    <compileflags>-fdata-sections
    <cxxflags>-D_REENTRANT
    <cxxflags>-D_GLIBCXX__PTHREADS
    <compileflags>-Wno-long-long
    <compileflags>-Wno-missing-field-initializers
    <compileflags>-Wno-unused-variable
    ;
    
    #---------------------------------------------------------------------
    # --------------------------------------------------------------------
    
    local ANDROID_TOOLCHAIN_ARM = android-toolchain-arm ;
    using clang : armeabi
    :
    toolchains/android-toolchain-arm/bin/arm-linux-androideabi-clang++
    :
    <archiver>toolchains/android-toolchain-arm/bin/arm-linux-androideabi-ar
    <compileflags>-fexceptions
    <compileflags>-frtti
    <compileflags>-fpic
    <compileflags>-ffunction-sections
    <compileflags>-funwind-tables
    <compileflags>-D__ARM_ARCH_5__
    <compileflags>-D__ARM_ARCH_5T__
    <compileflags>-D__ARM_ARCH_5E__
    <compileflags>-D__ARM_ARCH_5TE__
    #<compileflags>-Wno-psabi
    <compileflags>-march=armv5te
    <compileflags>-mtune=xscale
    <compileflags>-msoft-float
    <compileflags>-mthumb
    <linkflags>-march=armv5te
    <compileflags>-Os
    <compileflags>-fomit-frame-pointer
    <compileflags>-fno-strict-aliasing
    #<compileflags>-finline-limit=64
    <compileflags>-Wa,--noexecstack
    <compileflags>-DANDROID
    <compileflags>-D__ANDROID__
    <compileflags>-DNDEBUG
    <compileflags>-O2
    <compileflags>-g
    <root>toolchains/android-toolchain-arm/sysroot
    # @Moss - Above are the 'official' android flags
    <architecture>arm
    <compileflags>-fvisibility=hidden
    <compileflags>-fvisibility-inlines-hidden
    <compileflags>-fdata-sections
    <cxxflags>-D_REENTRANT
    <cxxflags>-D_GLIBCXX__PTHREADS
    <compileflags>-Wno-long-long
    <compileflags>-Wno-missing-field-initializers
    <compileflags>-Wno-unused-variable
    ;
    
    #---------------------------------------------------------------------
    # --------------------------------------------------------------------
    using clang : armeabi_v7a
    :
    toolchains/android-toolchain-arm/bin/arm-linux-androideabi-clang++
    :
    <archiver>toolchains/android-toolchain-arm/bin/arm-linux-androideabi-ar
    <compileflags>-fexceptions
    <compileflags>-frtti
    <compileflags>-fpic
    <compileflags>-ffunction-sections
    <compileflags>-funwind-tables
    #<compileflags>-Wno-psabi
    <compileflags>-march=armv7-a
    <compileflags>-msoft-float
    <compileflags>-mfpu=neon
    <compileflags>-mthumb
    <linkflags>-march=armv7-a
    <linkflags>-Wl,--fix-cortex-a8
    <compileflags>-Os
    <compileflags>-fomit-frame-pointer
    <compileflag>-fno-strict-aliasing
    #<compileflags>-finline-limit=64
    <compileflags>-Wa,--noexecstack
    <compileflags>-DANDROID
    <compileflags>-D__ANDROID__
    <compileflags>-DNDEBUG
    <compileflags>-O2
    <compileflags>-g
    <root>toolchains/android-toolchain-arm/sysroot
    # @Moss - Above are the 'official' android flags
    <architecture>arm
    <compileflags>-fvisibility=hidden
    <compileflags>-fvisibility-inlines-hidden
    <compileflags>-fdata-sections
    <cxxflags>-D__arm__
    <cxxflags>-D_REENTRANT
    <cxxflags>-D_GLIBCXX__PTHREADS
    <compileflags>-Wno-long-long
    <compileflags>-Wno-missing-field-initializers
    <compileflags>-Wno-unused-variable
    ;
    
    # --------------------------------------------------------------------
    
    local ANDROID_TOOLCHAIN_x86_64 = android-toolchain-x86_64 ;
    
    using clang : x86_64
    :
    toolchains/android-toolchain-x86_64/bin/x86_64-linux-android-clang++
    :
    <archiver>toolchains/android-toolchain-x86_64/bin/x86_64-linux-android-ar
    <compileflags>-fexceptions
    <compileflags>-frtti
    <compileflags>-fpic
    <compileflags>-ffunction-sections
    <compileflags>-funwind-tables
    #<compileflags>-Wno-psabi
    <compileflags>-Wno-missing-field-initializers
    <compileflags>-no-canonical-prefixes
    <linkflags>-no-canonical-prefixes
    <compileflags>-Os
    <compileflags>-fomit-frame-pointer
    <compileflags>-fno-strict-aliasing
    #<compileflags>-funswitch-loops
    #<compileflags>-finline-limit=300
    <compileflags>-Wa,--noexecstack
    <compileflags>-DANDROID
    <compileflags>-D__ANDROID__
    <compileflags>-DNDEBUG
    <compileflags>-O2
    <compileflags>-g
    <root>toolchains/android-toolchain-x86_64/sysroot
    # @Moss - Above are the 'official' android flags
    <architecture>x86
    <compileflags>-fvisibility=hidden
    <compileflags>-fvisibility-inlines-hidden
    <compileflags>-fdata-sections
    <cxxflags>-D_REENTRANT
    <cxxflags>-D_GLIBCXX__PTHREADS
    <compileflags>-Wno-long-long
    <compileflags>-Wno-missing-field-initializers
    <compileflags>-Wno-unused-variable
    ;
    
    # --------------------------------------------------------------------
    
    local ANDROID_TOOLCHAIN_x86 = android-toolchain-x86 ;
    
    using clang : x86 : "toolchains/android-toolchain-x86/bin/i686-linux-android-clang++"
    :
    <archiver>toolchains/android-toolchain-x86/bin/i686-linux-android-ar
    <compileflags>-fexceptions
    <compileflags>-frtti
    <compileflags>-fpic
    <compileflags>-ffunction-sections
    <compileflags>-funwind-tables
    #<compileflags>-Wno-psabi
    <compileflags>-Wno-missing-field-initializers
    <compileflags>-no-canonical-prefixes
    <linkflags>-no-canonical-prefixes
    <compileflags>-Os
    <compileflags>-fomit-frame-pointer
    <compileflags>-fno-strict-aliasing
    #<compileflags>-funswitch-loops
    #<compileflags>-finline-limit=300
    <compileflags>-Wa,--noexecstack
    <compileflags>-DANDROID
    <compileflags>-D__ANDROID__
    <compileflags>-DNDEBUG
    <compileflags>-O2
    <compileflags>-g
    <root>toolchains/android-toolchain-x86/sysroot/
    # @Moss - Above are the 'official' android flags
    <architecture>x86
    <compileflags>-fvisibility=hidden
    <compileflags>-fvisibility-inlines-hidden
    <compileflags>-fdata-sections
    <cxxflags>-D_REENTRANT
    <cxxflags>-D_GLIBCXX__PTHREADS
    <compileflags>-Wno-long-long
    <compileflags>-Wno-missing-field-initializers
    <compileflags>-Wno-unused-variable
    ;
    
    EOF
    
    rm -f user-config.jam
    ln -s tools/build/src/user-config.jam
    
    # bootstrap
    # ./bootstrap.sh --with-libraries=atomic,chrono,date_time,exception,filesystem,graph,iostreams,math,program_options,random,regex,serialization,signals,system,test,thread,wave
    
    ./bootstrap.sh --with-libraries=system,filesystem,thread,context,coroutine,fiber,serialization,iostreams
    
    rm -rf $BUILD_DIR
    
    #abi "aapcs" "eabi" "ms" "n32" "n64" "o32" "o64" "sysv" "x32"
    #architecture "x86" "ia64" "sparc" "power" "mips1" "mips2" "mips3" "mips4" "mips32" "mips32r2" "mips64" "parisc" "arm" "combined" "combined-x86-power"
    
    if [ $ARM64 -eq 1 ]
       then
    ./b2 -j8 --build-dir=$BUILD_DIR --stagedir=$BUILD_DIR/arm64-v8a toolset=clang-arm64_v8a variant=$BUILD_TYPE \
     target-os=android architecture=arm abi=aapcs binary-format=elf address-model=64 threading=multi link=$LINK_TYPE stage
    fi
    
    if [ $ARM32_7A -eq 1 ]
       then
    ./b2 -j8 --build-dir=$BUILD_DIR --stagedir=$BUILD_DIR/armeabi-v7a toolset=clang-armeabi_v7a variant=$BUILD_TYPE \
    target-os=android architecture=arm abi=aapcs binary-format=elf address-model=32 threading=multi link=$LINK_TYPE stage
    fi
    
    if [ $ARM32 -eq 1 ]
       then
    ./b2 -j8 --build-dir=$BUILD_DIR --stagedir=$BUILD_DIR/armeabi toolset=clang-armeabi variant=$BUILD_TYPE \
    target-os=android architecture=arm abi=aapcs binary-format=elf address-model=32 threading=multi link=$LINK_TYPE stage
    fi
    
    if [ $X86_64 -eq 1 ]
    then
    ./b2 -j8 --build-dir=$BUILD_DIR --stagedir=$BUILD_DIR/x86_64 toolset=clang-x86_64 variant=$BUILD_TYPE \
    target-os=android architecture=x86 abi=x32 binary-format=elf address-model=64 threading=multi link=$LINK_TYPE stage
    fi
    
    if [ $X86 -eq 1 ]
    then
    ./b2 -j8 --build-dir=$BUILD_DIR --stagedir=$BUILD_DIR/x86 toolset=clang-x86 variant=$BUILD_TYPE \
    target-os=android architecture=x86 abi=x32 binary-format=elf address-model=32 threading=multi link=$LINK_TYPE stage
    fi
    
    # create link for include folder
    cd $BUILD_DIR
    mkdir -p include
    cd include
    ln -s ../../boost .
  4. After a successful build the libraries should be in android-build/{architecture}. To check the architecture:

    mkdir x
    cd  x
    ../toolchains/android-toolchain-arm64/bin/aarch64-linux-android-ar -x ../android-build/arm64-v8a/lib/libboost_system.a
    file error_code.o
    error_code.o: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), with debug_info, not stripped
  5. Boost filesystem seems to have (undocumented) dependencies on both system and threads, the latter of which is particularly tiresome as modern C++ (>= 11) have all the thread primitives. https://github.com/bin-build/filesystem (forked from https://github.com/wjakob/filesystem) are lightweight alternatives with similar functionality.

  6. Note the Android project should also link with the libc++ STL eg

    externalNativeBuild
    {
       cmake
       {   cppFlags "-std=c++14 -fexceptions"
           arguments "-DANDROID_STL=c++_shared"
       }
     }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment