2012-06-11 64 views
2

编译对C++标准库我有一个非常简单的helloworld.cpp程序在Android工具链

#include <iostream> 
using namespace std; 
int main() 
{ 
    cout << "Hello World!"; 
    return 0; 
} 

我试图从工具链的交叉编译器来编译它为Android x86的:

/Users/me/android-ndk-r8/toolchains/x86-4.4.3/prebuilt/darwin-x86/bin/i686-android-linux-g++ helloworld.cpp -L "/Users/me/android-ndk-r8/sources/cxx-stl/stlport/libs/x86/" -lstlport_static 

但是,我得到的错误:

helloworld.cpp:2:20: error: iostream: No such file or directory 

任何想法,为什么?

+0

我已经编辑你的问题上显示的信息,因为这不是一个链接问题。 –

+1

听起来像你需要设置你的包含路径。另外,构建android项目的另一种方式是'ndk-build',并且更好的支持。 – jedwards

+0

如何设置包含路径? – MEURSAULT

回答

6

在“独立工具链”下检查NDK附带的documentation.html文件。它说如果你用这种方式调用编译器,你将不能“使用任何C++ STL”。然而,它是可能的,因为文档解释,如果先创建一个“自定义”安装工具链,使用类似下面的命令:

$NDK/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=/tmp/my-android-toolchain --arch=x86 

其中$ NDK是路径到您的NDK目录。请注意--arch = x86,这意味着该工具链专为x86 Android准备。这可以在一个目录中准备你需要的东西,包括STL头文件和文件夹。然后,您应该能够使用-lstdC++来对STL(静态版),即类似链接:

/tmp/my-android-toolchain/bin/i686-android-linux-g++ helloworld.cpp -lstdc++ 

有关更完整的说明,请参见NDK文档。

2

NDK文档不完全准确,至少目前不是。实际上,它使用预编译工具链时指出:“您将无法使用任何C++ STL(STLport或GNU libstdC++)”,但这已过时。我使用包含相同错误的程序创建了一个小型hello世界程序。无需创建自己的工具链即可解决问题,如果您不想再为您的配置过程再添加一个步骤,并且允许您始终使用最新的SDK平台而无需每次创建新的工具链,那么这很好。

NDK附带多个标准C++库版本的源代码:GAbi ++,STLport和GNU STL。每种口味都带有预建共享和静态库。我下面的例子将使用stlport。

要使用单独的工具链,在其安装位置,你可以做这样的事情: 出口CXX ='$ NDK_ROOT /工具链/ ARM-Linux的androideabi-4.8 /预建/达尔文-x86_64的/ bin中/ ARM -linux-androideabi -g ++ --sysroot =“$ NDK_ROOT/platforms/android-19/arch-arm”'

例如,这将设置您的CXX编译器使用SDK平台在OS X系统上编译ARM 19级。你可能已经知道这一点。另外,如果你使用它,你会希望导出你的CC,CPP,LD,AR和RANLIB。我也亲自为READELF创建了一个envar。

要添加支持C++库,你可以做类似如下: $ CXX helloworld.cpp -I $ NDK_ROOT /来源/ CXX-STL/stlport的/ stlport的-L $ NDK_ROOT /来源/ CXX-STL/stlport的/ libs/armeabi -lstlport_shared

请注意,这将链接现在在运行时需要的libstlport_shared.so,因此您可能需要在上面的命令中添加相对路径以支持该路径,具体取决于您的APK结构。如果你想只测试这个简单的例子,你可以在模拟器上运行此如下:

adb push a.out /data 
adb push $NDK_ROOT/sources/cxx-stl/stlport/libs/armeabi/libstlport_shared.so /data 
adb shell 
# su 
# cd /data 
# chmod 777 a.out 
# ./a.out 

为了摆脱处理共享库路径的头痛,你也可以静态地链接C++库通过将“-lstlport_shared”更改为“-lstlport_static”。这样做有一些后果,如NDK开发指南中所解释的。最大的问题是由于在多个地方连接了静态库,导致: - 在一个库中分配内存,在另一个库中释放内存会泄漏甚至损坏堆。 - 在libfoo.so中引发的异常无法在libbar.so中捕获(并且可能只是使程序崩溃)。 - std :: cout的缓冲不能正常工作

还包括一个有用的工具,以查看程序具有哪些依赖关系,readelf工具。

要查看你的程序需要什么其他的共享库,你可以运行以下命令: $ NDK_ROOT /工具链/ ARM-Linux的androideabi-4.8 /预建/达尔文-x86_64的/ bin中/ ARM-Linux的androideabi-readelf - a.out | grep的NEEDED

其他不错的标准工具: addr2line - 转换堆栈跟踪地址一行代码 纳米 - 显示符号表 objdump的 - 一个对象