Run c++ program with boost on Android
2013-10-20 16:06
281 查看
http://nick.luckygarden.org/
Android 很早就支持 NDK, 官方教程上说你可以把 native 代码编译成一个 .so, 在 java 代码中通过 jni 调用这个 .so.
现在在做一个 C++ 跨平台的库. 需要支持 Android. 为了在 Android 上测试, 自然可以按照教程里写 java, jni. 但其实也可以抛开 java. 直接将 c++ 代码编译成可执行文件. 下面将整个过程记录下来, 备忘, 也希望能帮助用这样的需求的人.
先下载 sdk, ndk. 解压缩就好, 然后设置好环境变量 ANDROID_SDKROOT, NDKROOT 指向这两个目录. 并将 $NDKROOT, $ANDROID_SDKROOT/platform-tools, $ANDROID_SDKROOT/tools 加入 PATH. 下面的操作使用的环境是 NDK r8, OS X 10.8.
开始啦:
把这个文件保存为 /tmp/hello.cpp. 要编译这个程序, 需要写一个 Android.mk
貌似还只能把这个 .mk 文件放到一个 jni 的文件夹里. 然后在 /tmp 目录执行 ndk-build. 如果环境都设置好了, 这个能够编译成功. 放到模拟器上试试吧.
执行
打开 Android Virtual Device Manager (注意 – avd 之间有一个空格), 创建一个虚拟机, 然后启动它. 确保一切 ok. 然后执行
push 到模拟器, 然后执行 hello-world.
继续. 修改一下代码, 试试 c++ 的库文件.
用 ndk-build 编译会发现有错误. 因为没有 stl 的支持.
在 /tmp/jni 下建立 Application.mk, 加上下面一句:
链接 gnustl. 再编译就 ok 了.
因为项目要链接 boost, 加上 boost header 试试吧.
首先是找不到 boost 头文件. 这里要做一些准备工作. 将需要编译的 boost 库在 android 编译好. 这里就不赘述了. 得到 libboost_thread.a, libboost_system.a, 将这些文件这样组织
其中的 Android.mk 的内容是这样的:
include $(CLEAR_VARS)
LOCAL_MODULE:= boost_thread
LOCAL_SRC_FILES:= lib/android/lib$(LOCAL_MODULE).a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) # 导出头文件, 因为有这句, 在我们的程序中的 Android.mk 文件中就不需要 LOCAL_C_INCLUDES 来指定 boost 头文件所在位置了.
include $(PREBUILT_STATIC_LIBRARY) # 所谓的编译好的静态库
include $(CLEAR_VARS)
LOCAL_MODULE:= boost_system
LOCAL_SRC_FILES:= lib/android/lib$(LOCAL_MODULE).a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
boost 库就准备好了. 现在修改程序的 Android.mk 文件:
LOCAL_MODULE := hello-world
LOCAL_SRC_FILES := ../hello.cpp
LOCAL_CPP_FEATURES := exceptions rtti # boost thread 库需要 exceptions 的支持. rtti 后面也会用到
LOCAL_STATIC_LIBRARIES := boost_thread boost_system # 要的就是这两个库.
include $(BUILD_EXECUTABLE)
再次编译会提示 import-module 找不到 boost, 需要定义 NDK_MODULE_PATH
到这里差不多了.
文中提到的 .mk 文件中的宏 (LOCAL_..) 的具体含义参见 $NDKROOT/documentation.html
Android 很早就支持 NDK, 官方教程上说你可以把 native 代码编译成一个 .so, 在 java 代码中通过 jni 调用这个 .so.
现在在做一个 C++ 跨平台的库. 需要支持 Android. 为了在 Android 上测试, 自然可以按照教程里写 java, jni. 但其实也可以抛开 java. 直接将 c++ 代码编译成可执行文件. 下面将整个过程记录下来, 备忘, 也希望能帮助用这样的需求的人.
先下载 sdk, ndk. 解压缩就好, 然后设置好环境变量 ANDROID_SDKROOT, NDKROOT 指向这两个目录. 并将 $NDKROOT, $ANDROID_SDKROOT/platform-tools, $ANDROID_SDKROOT/tools 加入 PATH. 下面的操作使用的环境是 NDK r8, OS X 10.8.
开始啦:
#include <stdio.h> int main(){printf("hello world.\n");return 0;}
把这个文件保存为 /tmp/hello.cpp. 要编译这个程序, 需要写一个 Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # mk 文件前面两句都这样, 不解释
LOCAL_MODULE := hello-world # 模块名, 必须唯一 LOCAL_SRC_FILES := ../hello.cpp # 要编译的源文件 include $(BUILD_EXECUTABLE) # 编译成可执行文件. 这个是关键. # 其他的选项是 BUILD_SHARED_LIBRARY, BUILD_STATIC_LIBRARY 编译成 .so, .a
貌似还只能把这个 .mk 文件放到一个 jni 的文件夹里. 然后在 /tmp 目录执行 ndk-build. 如果环境都设置好了, 这个能够编译成功. 放到模拟器上试试吧.
执行
android - avd
打开 Android Virtual Device Manager (注意 – avd 之间有一个空格), 创建一个虚拟机, 然后启动它. 确保一切 ok. 然后执行
adb push libs/armeabi/hello-world /data/ && adb shell /data/hello-world 1372 KB/s (299852 bytes in 0.213s) hello world.
push 到模拟器, 然后执行 hello-world.
继续. 修改一下代码, 试试 c++ 的库文件.
#include <iostream> int main(){std::cout<<"hello world"; return 0;}
用 ndk-build 编译会发现有错误. 因为没有 stl 的支持.
nickx:/tmp $ ndk-build Compile++ thumb : hello-world <= hello.cpp jni/../hello.cpp:1:20: error: iostream: No such file or directory jni/../hello.cpp: In function 'int main()': jni/../hello.cpp:4: error: 'cout' is not a member of 'std' make: *** [obj/local/armeabi/objs/hello-world/__/hello.o] Error 1
在 /tmp/jni 下建立 Application.mk, 加上下面一句:
APP_STL := gnustl_static # 另一个选项是 gnustl_shared
链接 gnustl. 再编译就 ok 了.
因为项目要链接 boost, 加上 boost header 试试吧.
#include <iostream> #include <boost/thread.hpp> void proc(){std::cout << "hello world\n";} int main() { boost::thread thrd(proc); thrd.join(); return 0; }
首先是找不到 boost 头文件. 这里要做一些准备工作. 将需要编译的 boost 库在 android 编译好. 这里就不赘述了. 得到 libboost_thread.a, libboost_system.a, 将这些文件这样组织
/vendor /boost Android.mk /boost thread.hpp .. /lib libboost_thread.a libboost_system.a
其中的 Android.mk 的内容是这样的:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= boost_thread
LOCAL_SRC_FILES:= lib/android/lib$(LOCAL_MODULE).a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) # 导出头文件, 因为有这句, 在我们的程序中的 Android.mk 文件中就不需要 LOCAL_C_INCLUDES 来指定 boost 头文件所在位置了.
include $(PREBUILT_STATIC_LIBRARY) # 所谓的编译好的静态库
include $(CLEAR_VARS)
LOCAL_MODULE:= boost_system
LOCAL_SRC_FILES:= lib/android/lib$(LOCAL_MODULE).a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
boost 库就准备好了. 现在修改程序的 Android.mk 文件:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_MODULE := hello-world
LOCAL_SRC_FILES := ../hello.cpp
LOCAL_CPP_FEATURES := exceptions rtti # boost thread 库需要 exceptions 的支持. rtti 后面也会用到
LOCAL_STATIC_LIBRARIES := boost_thread boost_system # 要的就是这两个库.
include $(BUILD_EXECUTABLE)
$(call import-module,boost) # 导入 boost 库.
再次编译会提示 import-module 找不到 boost, 需要定义 NDK_MODULE_PATH
nickx:/tmp $ export NDK_MODULE_PATH=/vendor nickx:/tmp $ ndk-build Compile++ thumb : hello-world <= hello.cpp Prebuilt : libboost_thread.a <= /vendor/boost/lib/android/ Prebuilt : libboost_system.a <= /vendor/boost/lib/android/ Executable : hello-world Install : hello-world => libs/armeabi/hello-world
到这里差不多了.
文中提到的 .mk 文件中的宏 (LOCAL_..) 的具体含义参见 $NDKROOT/documentation.html
相关文章推荐
- Run c++ program with boost on Android
- boost c++ lib on linux (1) - regex example with binary boost lib Regex
- Android CTS - Cannot run program "aapt"/ Fail to run aapt on .../apk installed but AaptParser failed
- Step by Step - How to create a c++ library with NDK on Android Studio 1.5 (not experimental way)
- How to Compile and Run C/C++ program on Ubuntu 11.10
- Program for Android in C/C++ with the Native Development Kit (if you dare)
- Using Android Studio to build applications with NDK and Boost C++ libraries
- Error: Cannot run program "/home/xxx/android_developer_tools/android-ndk-r8/ndk-build.cmd": Unknown reason
- Choose a destination with a supported architecture in order to run on this device
- Choose a destination with a supported architecture in order to run on this device.
- Choose a destination with a supported architecture in order to run on this device.
- Useful code snippets with C++ boost
- Programming 3D games on Android with Irrlicht and Bullet
- Install C++ Boost on Ubuntu
- boost c++ lib on linux(2) - lexical_cast字符串数值转换
- Choose a destination with a supported architecture in order to run on this device.
- How to run a Java Program as a daemon (service) on Linux (openSUSE) using a shell script
- Run rbgirshick/py-faster-rcnn on ubuntu with gpu
- question 002: dev c++ 当中如何调整字体大小?How to get the first program with C++? c++属于什么软件?
- Displaying Charts on Android with WebView