如何为安卓构建 boost 作为支持 c++11 的共享库
How to build boost for android as shared library with c++11 support
我正在尝试为支持 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)。
- 转到下载的boost_1_79_0解压缩目录并构建 b2 工具:
.bootstrap.bat
- 检查 b2 工具是否已准备就绪:
b2 --version
B2 4.8-git <-- possible output
- 在 %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 ;
- 转到 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
- 现在检查您的安装前缀路径。
- MSVC是否支持C++11样式的属性而不是__declspec
- 如何检测VS C++编译器是否支持C++11?
- 在 c++ 中连接字符串和整数,以便在 C++ 11 不支持计算机的情况下读取多个文件
- C++11 NVCC 不支持函数 iota()?
- 编译具有Contrib和C++11支持的OpenCV?
- OpenCV 4.x+ 需要启用 C++11 支持编译暗网致命错误
- 为什么 GCC 6.3 在没有显式 C++11 支持的情况下编译此大括号初始化列表代码
- 如何在 Eclipse 中启用 C++11 支持
- 在Apple llvm 4.1上使用libc++与libstc++时,c++11支持的确切区别是什么
- 升级到G 4.7(带有C 11支持):任何ABI不兼容
- 如何使用 CMake 检测编译器的 C++11 支持
- clang 的 c++11 支持可靠吗?
- Clang 3.1 和 C++11 支持状态
- 在每个Qt Creator项目中添加C++11支持
- 未在具有c++11支持的scopet中声明nullptr
- 通过cmake在VS 2013中启用c++ 11支持
- Android上启用c++ 11支持
- 将 C++11 支持添加到 Makefile
- 'for each'不是 std 的成员。 已启用 C++11 支持
- 在xcode 4.5.2中编译带有c++ 11支持的混合objective-C/ c++项目时出现链接错误