NDK构建仅限C ++的应用程序

时间:2012-04-22 08:09:06

标签: android android-ndk

我正在尝试在Android上构建本机守护程序。控制某些特定硬件的目的,Java应用程序将能够使用套接字与此守护进程通信。

我一直在使用cmake编译我的库,演示和真正的守护进程(工作正常BTW)。我现在正尝试做两件不同的事情:

  1. 使用ndk-build构建相同的应用。
  2. 通过使JNI调用与c ++守护程序的工作方式非常相似,将C ++守护程序移植到Android服务。
  3. 据我所知,ndk-build无法生成本机应用程序,只能生成本机库,而Java库可以加载它们......我是否正确?对于step1,我并不真正需要java(我已经证明了它),但我找到了ndk-build吐出精灵应用程序的方法。

    供参考 - 我正在使用cmake,如下所述:http://opekar.blogspot.com/2011/06/android-cmake-is-much-easier-in-ndk-r5b.html

    这样我可以为“普通”linux构建,也可以使用源代码构建的android。如果你问我,那就太好了。

3 个答案:

答案 0 :(得分:2)

另一种方法是使用与NDK捆绑在一起的脚本make-standalone-toolchain.sh来创建独立的工具链,然后使用它来编译项目。下面的shell代码说明了如何使用它:

# Assumed path to the NDK, change it to suit your environment.
NDK_HOME=$HOME/bin/android-ndk-r8e

# Desired API and NDK versions and destination folder of
# the stand-alone toolchain, change them to suit your needs.
api=14
ver=4.7
folder=$HOME/bin/android-$api-ndk-$ver

mkdir $folder
cd $folder

$NDK_HOME/build/tools/make-standalone-toolchain.sh \
    --toolchain=arm-linux-androideabi-$ver \
    --platform=android-$api --install-dir=$(pwd)

运行上面的行将在$HOME/bin/android-14-ndk-4.7生成一个新的独立工具链,然后您可以将其用作任何常规的C / C ++交叉编译工具链。

使用独立工具链的优势在于它使Android交叉编译Linux项目变得轻而易举;例如,请参阅我的port of Valgrind to Android ARMv7

答案 1 :(得分:1)

正如@MārtiņšMožeik在其中一条评论中提到的那样,Android.mk的这个方面会起作用:

LOCAL_PATH       := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE     := my_daemon
LOCAL_C_INCLUDES := src
LOCAL_SRC_FILES  := src/daemon.c
include $(BUILD_EXECUTABLE)

我注意到的一件事是这个“makefile”生成的二进制文件是130k,而cmake生成的二进制文件是~40 kb。这是因为我使用-s作为C_FLAG然后gcc将动态地剥离生成的对象。这可以稍后通过调用$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip或您的拱门的相应条带来完成。

由于我没有在互联网上找到此功能的文档,还有更多的话:

  • 这个效果很好,这里没问题:)
  • 必须将其保存在名为jni/Android.mk的文件中。
  • 代码必须保存在JNI目录
  • 如果您的代码位于jni目录之外,则会变得难看,但并非不可能。您只需要在代码前加上相应的前缀,不要忘记修改包含路径。这留给读者作为练习。
  • 仍然不确定为什么Android构建系统生成的代码比cmake生成的代码大。我之前说过strip没有被调用 - 但是在将* .so复制到lib目录之前调用它。
  • 仍然不知道如何将该二进制文件打包到android包中,甚至不知道如何在不修改Android代码的情况下运行它(例如在系统启动时)。我假设我可以编写一个在启动时启动的Java服务,然后编写守护进程execvp

答案 2 :(得分:0)

您的选项2是AFAIK的唯一方法。