本文将演示如何编译生成直接运行在Android系统的可执行文件。

开发环境:Eclipse + NDK + CDT(脱离eclipse + cdt的编译在文末介绍)

1.在Eclipse的Java视图中,新建一个工程名为”Execute”
2.右击工程-> Android Tools -> Add Native Support…
在弹出的“Add Android Native Support”中填写“library name”为”Execute”。点击“确定”。
Eclipse会自动切换到”C/C++”视图,其工程目录下新增”jni”及”Execute.cpp”文件如下图。
jni.folder

3.编写c++代码如下(实际代码其实是c代码,c++代码将会碰到一些编译问题将会在下文中介绍):

1
2
3
4
5
6
#include <stdio.h>

int main() {
printf("Hello world.\n");
return 0;
}

4.编写Android.mk如下:

1
2
3
4
5
6
7
8
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := Execute
LOCAL_SRC_FILES := Execute.cpp
# BUILD_EXECUTABLE指明生成可执行的二进制文件
include $(BUILD_EXECUTABLE)

5.右击工程 -> Build Project,可见直接在libs下生成二进制文件“Execute”
output.execute

6.将该文件拷贝出,push到手机的/data/local下(在SDCard是不可运行的,文件系统的权限限制)
并执行“./execute”运行输出日志“Hello World”.见下图。
preview

以上是生成一个可在Android系统中直接运行的可执行文件过程。

#C++编译问题补充

在示例代码中,如果想把c语言的实现改为c++,则步骤和碰到的问题如下:
1.使用c++代码详情如下:

1
2
3
4
5
6
#include <iostream>
using namespace std;
int main() {
cout << "Hello World" << endl;
return 0;
}

2.执行”Build Project”后,会出现“fatal error: iostream: No such file or directory”问题。见下图。
iostream.no.such.file

解决:在jni文件夹下新建Application.mk文件,并在其中写入:

1
2
3
#以下两行二选一
APP_STL:=stlport_static
#APP_STL:=gnustl_static

继续编译,则正常。

原因:
在使用C++的标准库进行NDK开发时,必须设置APP_STL,该属性值的可取范围见下图:
app_stl.range

上图中不同的标准库的能力也各有差异,见下表。

             C++       C++   Standard
          Exceptions  RTTI    Library
system       no       no        no
gabi++       no       yes       no
stlport      no       yes       yes
gnustl       yes      yes       yes

要特别注意的是,引用的类库越全面,最后生成的可执行文件execute体积也就越大。以下是使用c语言、c++ stlport及c++ gnustl三种情形所编译生成的可执行文件体积对比:

execute.comparison

#直接使用ndk-build编译
还记得在linux上只要执行gcc/g++就可以直接生成一个可执行文件吗?
在进行ndk开发时,也可以脱离eclipse+cdt,只用命令ndk-build来编译。
进入Execute工程目录下,建立了jni文件夹后,编写好Execute.cpp及Android.mk文件,在Terminal终端命令工具下进入Execute目录,直接执行ndk-build,即可!!so easy..