在Android NDK r8b下编译STXXL

9

我正在尝试在Android NDK r8b(我也在更新的r8c下遇到了同样的问题)下编译STXXL。

我正在使用gnustl_static进行编译。

我需要C++11支持,所以最初我尝试设置

LOCAL_CPPFLAGS := -std=c++11

但是这引发了一个有关uint64_t的错误。

所以我将标志更改为

LOCAL_CPPFLAGS :=-std=gnu++11

这有一定帮助,但当编译开始时,我会遇到与gnu stl相关的错误。
Users/Gozzeh/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++ -MMD -MP -MF ./obj/local/armeabi/objs/stxxl/STXXL/algo/copy_and_sort_file.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__  -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -fno-rtti -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -I/Users/Gozzeh/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include -I/Users/Gozzeh/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/include -Ijni -DANDROID  -Wa,--noexecstack -fexceptions -frtti -Dnullptr=0 -D_ANDROID -std=gnu++11 -Ijni/STXXL/include -fexceptions  -O2 -DNDEBUG -g   -I/Users/Gozzeh/android-ndk-r8b/platforms/android-8/arch-arm/usr/include -c  jni/STXXL/algo/copy_and_sort_file.cpp -o ./obj/local/armeabi/objs/stxxl/STXXL/algo/copy_and_sort_file.o 
In file included from /Users/Gozzeh/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include/set:60:0,
                 from jni/STXXL/include/stxxl/bits/io/simdisk_file.h:33,
                 from jni/STXXL/include/stxxl/bits/io/io.h:20,
                 from jni/STXXL/include/stxxl/io:13,
                 from jni/STXXL/algo/copy_and_sort_file.cpp:18:
/Users/Gozzeh/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include/bits/stl_tree.h: In member function 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Base_ptr, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Base_ptr, const _Val&)':
/Users/Gozzeh/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include/bits/stl_tree.h:1011:39: error: '_Arg' was not declared in this scope

我也收到了更多与此_Arg参数相关的错误。
因此,看看第一个函数是这样的:
template<typename _Key, typename _Val, typename _KeyOfValue,
           typename _Compare, typename _Alloc>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
    template<typename _Arg>
#endif
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
#ifdef __GXX_EXPERIMENTAL_CXX0X__
    _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __p, _Arg&& __v)
#else
    _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v)
#endif
    {
      bool __insert_left = (__x != 0 || __p == _M_end()
                || _M_impl._M_key_compare(_KeyOfValue()(__v), 
                              _S_key(__p)));

      // This line is the error location.
      _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v)); 

      _Rb_tree_insert_and_rebalance(__insert_left, __z,
                    const_cast<_Base_ptr>(__p),  
                    this->_M_impl._M_header);
      ++_M_impl._M_node_count;
      return iterator(__z);
    }

我实在无法理解问题出在哪里。是gnu++11没有定义__GXX_EXPERIMENTAL_CXX0X__吗?还是问题出在它没有被正确地使用?我很困惑,不知道是什么导致了这个问题?我已经在iphone上使用clang将STXXL编译为gnu++11,但我猜iphone可能使用了不同的STL实现。有人有任何想法如何解决这个问题吗?
如果您需要更多信息,请随时询问!
编辑:根据这里的一条评论,这是我的application.mk。
APP_PLATFORM := android-8 
APP_STL      := gnustl_static
APP_GNUSTL_FORCE_CPP_FEATURES := exceptions rtti 
APP_OPTIM    := release APP_ABI      := all

这是我的 android.mk 文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
rwildcard       = $(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))

LOCAL_MODULE    := stxxl
LOCAL_CPP_FEATURES += exceptions
FILE_LIST       := $(call rwildcard, $(LOCAL_PATH)/STXXL/,*.cpp)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_CPPFLAGS  := -Dnullptr=0 -D_ANDROID -D__STDC_INT64__ -std=gnu++11 -I$(LOCAL_PATH)/STXXL/include
include $(BUILD_SHARED_LIBRARY)
< p > < em > < strong >编辑: 有趣的是,我刚刚尝试在我发布的stl_tree.h函数中的#ifdef __GXX_EXPERIMENTAL_CXX0X__块内放置了一个#error temp。编译器并没有在那部分抛出错误...所以定义从未被设置,这可能是我的问题的原因。我还专门添加了一个-D__GXX_EXPERIMENTAL_CXX0X__,但没有任何区别(好像它被取消定义了)。


你的g++版本可能不支持std=c++11,你尝试过使用-std=c++0x吗? - juanchopanza
@juanchopanza:我已经尝试过gnu++0x(因为在c++0x/11中未定义uint64_t),但我遇到了完全相同的问题。如果我设置gnu++03,则可以编译通过,但是我会失去c++11支持:( - Goz
@AlexCohn:已发布Application.mk和Android.mk。 - Goz
通过Eclipse...但是是使用ndk-build... - Goz
@auselen:我正在做Eclipse默认情况下执行的操作,当你选择项目->全部构建时...就我所知...是的...它会在jni目录内调用ndk-build... - Goz
显示剩余3条评论
1个回答

4
我认为你的构建方法过于乐观。我不了解STXXL,但是任何复杂的项目都有很多细节需要在其自己的make文件中处理,所以仅仅通过添加自己的Android.mk文件并尝试包含所有可能的源代码文件来进行构建是行不通的。
如果你想使用ndk-build,你应该仔细研究该项目并了解其详细信息,并将这些信息融入到你的新Android.mk文件中。例如,如果你查看Android存储库下的external目录(在github上它们列为几个子项目),你可以看到许多开源项目以及它们如何被引入到Android构建系统中。
在长篇乏味的信息之后,我建议使用NDK作为独立的工具链。你可以阅读关于此的文档$NDK/docs/STANDALONE-TOOLCHAIN.html。简而言之,我能够通过以下命令将STLXX编译为静态库(我的ndk安装在~/bin下)。
NDK=~/bin/android-ndk-r8c PTHREAD_FLAG= COMPILER="$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-g++ --sysroot=$NDK/platforms/android-14/arch-arm -I$NDK/sources/cxx-stl/gnu-libstdc++/4.6/include -I$NDK/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/include -L$NDK/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/ -lgnustl_shared" make library_g++
一开始编译失败是因为文件“./io/ufs_file_base.cpp”中有一些过时的使用“S_IREAD”和“S_IWRITE”的内容,这在Android / Bionic上不受支持。请参见错误报告参考资料
您应该将第88行更新如下
const int perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;

那么

<same build command again>

现在您应该在lib下获得libstxxl.a。我不知道这是否有效,但既然这是一个构建问题,我希望它能回答或给您一些方向。

最后需要注意的是关于ARM EABIs。上述命令使用armeabi,如您在指定目录中所见,如果适用于您的目标,您可能想使用armeabi-v7a,因为那是较新的版本。从您的错误消息中可以看出,特定的构建是针对xscale的,如果这不是有意的,那么熟悉ARM架构/产品系列可能是个好主意。


你是用C++11构建它吗?因为我可以使用上面的.mk文件作为C++03构建它而没有任何问题。问题可能出在C++11上...但是在iPhone上使用C++11构建很好... - Goz
如果你的意思是这个,我可以在COMPILER="..."中添加"-std=gnu++11",然后就能够构建了。但是使用你的.mk文件我无法构建成功。 - auselen
好的,有趣...我会检查一些东西。 - Goz
好的...该死。我在STXXL代码中发现了一个#undef __GXX_EXPERIMENTAL_CXX0X__,不知道为什么我要放进去:(现在编译非常顺利。谢谢。确认它可以编译为C++11就值得这些分数了。 - Goz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接