如何为安卓构建 boost 作为支持 c++11 的共享库

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

本文关键字:c++11 支持 共享 boost 构建      更新时间:2023-10-16

我正在尝试为支持 c++11 的 android 构建 boost_1.60.0(作为共享库)。我正在使用最新的ndk(目前是android-ndk-r10e)。生成主机是 Windows-10。

这适用于非开源项目。所以据我了解,我不能使用gnustl_shared,我需要使用 c++_shared 作为 android c++ 运行时。

我的project-config.jam看起来像这样:

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
        ;        

构建命令为:

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 

为了确定project-config.jam中的参数,我使用ndk-build构建了一个示例共享库,获取其调试消息,并提取了它使用的编译和链接命令。

编译:

C:android-ndk-r10etoolchainsarm-linux-androideabi-4.8prebuiltwindows-x86_64binarm-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,...)

链接:

C:android-ndk-r10etoolchainsarm-linux-androideabi-4.8prebuiltwindows-x86_64binarm-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,...)

为了简洁起见,我只为这次试验构建了文件系统,但最终我计划至少构建线程、文件系统、date_time、asio 和日志库。
最后我得到的错误如下。

...patience...
...found 660 targets...
...updating 13 targets...
gcc.compile.c++ bin.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multierror_code.o
gcc.link.dll bin.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multilibboost_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.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multierror_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.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multierror_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.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multierror_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.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multilibboost_system-gcc-mt-1_60.so.1.60.0"  -shared -Wl,--start-group "bin.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multierror_code.o"  -Wl,-Bstatic  -Wl,-Bdynamic -lrt -Wl,--end-group -lc++_shared -pthread
...failed gcc.link.dll bin.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multilibboost_system-gcc-mt-1_60.so.1.60.0...
...skipped <pstagelib>libboost_system-gcc-mt-1_60.so.1.60.0 for lack of <pbin.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multi>libboost_system-gcc-mt-1_60.so.1.60.0...
gcc.compile.c++ bin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multicodecvt_error_category.o
gcc.compile.c++ bin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multioperations.o
gcc.compile.c++ bin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multipath.o
gcc.compile.c++ bin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multipath_traits.o
gcc.compile.c++ bin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multiportability.o
gcc.compile.c++ bin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multiunique_path.o
gcc.compile.c++ bin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multiutf8_codecvt_facet.o
gcc.compile.c++ bin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multiwindows_file_codecvt.o
...skipped <pbin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multi>libboost_filesystem-gcc-mt-1_60.so.1.60.0 for lack of <pbin.v2libssystembuildgcc-androidreleasetarget-os-linuxthreading-multi>libboost_system-gcc-mt-1_60.so.1.60.0...
...skipped <pstagelib>libboost_filesystem-gcc-mt-1_60.so.1.60.0 for lack of <pbin.v2libsfilesystembuildgcc-androidreleasetarget-os-linuxthreading-multi>libboost_filesystem-gcc-mt-1_60.so.1.60.0...
...failed updating 1 target...
...skipped 3 targets...
...updated 9 targets...

该错误告诉它需要目录来查找必要的库,但问题是在 android ndk 下有几个文件名为 rt 和 crtbegin_so.o 等的文件。我想我需要让编译器确定正确的目录本身。

综上所述,我实际上需要的是构建支持 c++11 的 android 增强共享库。因此,我可能会接受您的帮助,方法是使用上述构建参数为我指明正确的方向,或者为我提供一个工作示例,以便我自己制定细节。

哦,还有一件事:如果我在构建命令中使用link=static而不是link=shared,则构建成功。但我还没有尝试过生成的静态库。

使用 NDK 在 Linux 上构建提升

我知道你在问Windows,但我想在macOS上这样做,它失败了,几乎完全错误。我终于崩溃了,在我的 linode 服务器上做了它,它工作没有问题。这告诉我,他们在测试其他平台方面并没有做得很好。仅在macOS上编译静态的工作方式与您在Windows上发现的那样。

参考点

  • NDK R13
  • 提升 1.62.0
  • 用 clang++ 测试;g++ 也可以工作

如果您想知道我为什么使用 clang,发行说明中有以下消息:

不再支持 GCC。它不会从 NDK 中删除,只是 尚未,但不再接收向后移植。在以下之前无法将其删除 在libc ++变得足够稳定成为默认值之后,因为某些部分 的 gnustl 仍然与 Clang 不兼容。它可能会被删除 在那之后。

user-config.jam

我把这个文件放在我的主目录中。呸。

androidNDKRoot = /path/to/ndk-R13-standalone ;
using clang : android
:
$(androidNDKRoot)/bin/arm-linux-androideabi-clang++
:
;

在 boost 中修改 libtool.m4 以避免库的版本控制

libtool.m4在提升源中tools/build/src/engine/boehm_gc/libtool.m4下没有对 Android 的引用,您需要将第 linux*) 部分中的version_type=linux更改为 version_type=none 。这将导致符号链接显示,而末尾没有附加到版本化共享库的版本号,链接到输出中的版本共享库。

建筑

目标操作系统必须是 android 以避免传递 -lrt 标志,这将导致共享链接失败。

./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
相关信息

在这里(Boost for Android),他们已经能够成功构建共享库,但似乎生成的文件具有Android无法处理的版本后缀。此外,不能只是重命名二进制文件,因为文件名在其中是硬编码的。根据上一篇文章,一种方法是在文件的 linux 部分中将变量 version_type 设置为 none (version_type=none)。在您的情况下,构建设置可能略有不同,但可能值得看看他们在讨论中所做的更改。

user-config.jam

如果你想从cmake(find_package)中找到boost,你必须使用编译器的版本,而不是像顶部答案那样的android,在你的user-config.jam中

,如下所示。
androidNDKRoot = /path/to/ndk-R13-standalone ;
using clang : 8.0.1
:
$(androidNDKRoot)/bin/arm-linux-androideabi-clang++
:
;

我以后对我的回答。如何在 Windows PC for Android 上使用最新的 NDK(24.0) 构建最新的 Boost(1.79.0)。

  1. 转到下载的boost_1_79_0解压缩目录并构建 b2 工具:
.bootstrap.bat
  1. 检查 b2 工具是否已准备就绪:
b2 --version
B2 4.8-git   <-- possible output
  1. 在 %HOME% 目录中创建文件 user-config.jam,内容如下(示例):
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. 转到 boost root 并尝试为每个 Android 架构(arm、arm64、x86、x86_64)构建示例:
c:Usersl_chaykaDownloadsboost_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:Usersl_chaykaDownloadsboost_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:Usersl_chaykaDownloadsboost_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:Usersl_chaykaDownloadsboost_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. 现在检查您的安装前缀路径。