android NDK 环境搭建及基础文件

开发环境

搭建

  1. 下载后解压NDK
  2. 设置环境变量: 添加环境变量 NDKROOT 为:C:\Users\w\Documents\app\android-ndk-r9d,在环境变量 PATH 下追加 :%NDKROOT%;
  3. eclipse中的配置:Window > Preferences > Android > NDK,选择NDK目录到对应解压文件夹

验证是否搭建成功

  1. 导入NDK解压目录下 "/samples/"下的某一个项目
  2. 右键" Android Tools > Add Native Support",
  3. 默认, finish, 正常运行

ndk-build命令

项目右击 > Properties > C/C++ Build > Use default build command > ??

  • clean 删除以前生成的二进制文件。
  • V=1 bulid,并在命令行里显示过程(Launch build, and display build commands)
  • -b 强制全部重新build(Force a complete rebuild)
  • -B V=1 强制全部重新build并显示build信息
  • NDK_LOG=1 显示内部NDK日志信息
  • NDK_DEBUG=1 Force a debuggable build
  • NDK_DEBUG=0 Force a release build
  • NDKAPPLICATIONMK=Build, using a specific Application.mk file pointed to by the NDKAPPLICATIONMK variable.
  • -C Build the native code for the project path located at . Useful if you don't want to cd to it in your terminal.

基本结构

Android.mk

基本语法

  • LOCAL_PATH := $(call my-dir)

    已该变量开头,用于在开发tree中查找源文件。宏my-dir 则由Build System提供。返回包含Android.mk的目录路径。
  • include $(CLEAR_VARS)

    CLEARVARS 变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCALxxx.
  • LOCAL_MODULE := hello-jni
    LOCAL_MODULE模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。Build System会自动添加适当的前缀和后缀。例如,foo,要产生动态库,则生成libfoo.so. 但请注意:如果模块名被定为:libfoo.则生成libfoo.so. 不再加前缀。
  • LOCAL_SRC_FILES := hello-jni.c

    LOCALSRCFILES变量必须包含将要打包如模块的C/C++ 源码。不必列出头文件,build System 会自动帮我们找出依赖文件。缺省的C++源码的扩展名为.cpp. 也可以修改,通过LOCAL_CPP_EXTENSION。
  • include $(BUILDSHAREDLIBRARY)

    BUILDSHAREDLIBRARY:是Build System提供的一个变量,指向一个GNU Makefile Script。
    它负责收集自从上次调用 include $(CLEARVARS) 后的所有LOCAL_XXX信息。并决定编译为什么。

    BUILD_STATIC_LIBRARY:编译为静态库。

    BUILD_SHARED_LIBRARY :编译为动态库

    BUILD
    EXECUTABLE:编译为Native C可执行程序

变量和宏

NDK Build System 保留以下变量名:

  • 以LOCAL_为开头的
  • 以PRIVATE,NDK或者APP_开头的名字。
  • 小写字母名字:如my-dir,因为系统内部会使用
  • 如果想要定义自己在Android.mk中使用的变量名,建议添加 MY_前缀。

NDK中定义的变量

  • CLEAR_VARS
    指向一个编译脚本。必须在新模块前包含,include $(CLEAR_VARS)
  • BUILD_SHARED_LIBRARY
    指向一个编译脚本,它收集自从上次调用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定如何将你列出的Source编译成一个动态库。 注意,在包含此文件前,至少应该包含:LOCAL_MODULE and LOCAL_SRC_FILES
    例如: include $(BUILD_SHARED_LIBRARY)
  • BUILD_STATIC_LIBRARY
    收集自从上次调用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定如何将你列出的Source编译成一个静态库。 静态库不能够加入到Project 或者APK中。但它可以用来生成动态库。LOCAL_STATIC_LIBRARIES and LOCAL_WHOLE_STATIC_LIBRARIES将描述之。
    include $(BUILD_STATIC_LIBRARY)
  • BUILD_EXECUTABLE
    收集自从上次调用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定如何将你列出的Source编译成一个可执行Native程序。
    include $(BUILD_EXECUTABLE)
  • PREBUILT_SHARED_LIBRARY
    把这个共享库声明为 “一个” 独立的模块。指向一个build 脚本,用来指定一个预先编译好多动态库。 与BUILD_SHARED_LIBRARY and BUILD_STATIC_LIBRARY不同,此时模块的LOCAL_SRC_FILES应该被指定为一个预先编译好的动态库,而非source file. LOCAL_PATH := $(call my-dir)

这个共享库将被拷贝到 $PROJECT/obj/local 和 $PROJECT/libs/ (stripped) 主要是用在将已经编译好的第三方库
使用在本Android Project中。为什么不直接将其COPY到libs/armabi目录呢?因为这样做缺陷很多。下一节再详细说明。

模块描述变量

  • LOCAL_PATH
  • LOCAL_MODULE
    存放模块名, 自动转换为lib开头,'.so'结尾
  • LOCAL_MODULE_FILENAME
    自定义模块名
    LOCALMODULEFILENAME := libnewfoo //重命名为libnewfoo.so
  • LOCAL_SRC_FILES
    要编译的源码列表, 可以采用相对于LOCAL_PATH的相对路径(/),
  • LOCAL_CPP_EXTENSION
    表示某一类文件
    LOCALCPPEXTENSION := .cxx;
    LOCALCPPEXTENSION := .cxx .cpp .cc
  • LOCAL_CPP_FEATURES
    表示代码依赖某些C++特性

    LOCAL_CPP_FEATURES := rtti 运行时类型检查

    LOCAL_CPP_FEATURES := exceptions C++异常信息

    LOCAL_CPP_FEATURES := rtti features 可以同时添加多个
  • LOCAL_C_INCLUDES

    添加一个相对于NDK根目录的路径, 在编译时用于搜索
    LOCALCINCLUDES := sources/foo
NDK提供的功能的宏
  • my-dir
    这个宏返回最后一个包括生成文件的路径,通常是当前Android.mk的目录。
  • all-subdir-makefiles
  • this-makefile
    返回当前文件的路径(通过编译系统的调用)
  • parent-makefile
    返回父文件路径
  • grand-parent-makefile
    返回祖父文件路径
  • import-module
    允许通过module名查找并包含module的Android.mk
    $(call import-module,)
    上例子中查找NDK_MODULE_PATH 环境指定的资料,自动包含找到的Android.mk

Application.mk

描述应用运行需要的模块, 每一个模块可以是一个静态库, 分享库或者一个可执行文件; 工具链, 应用系统

变量

  • APP_PROJECT_PATH

    存储项目根目录的绝对路径, 如果Application.mk文件在$PROJECT/jni/目录下,该变量是可选的, 否则必须设置
  • APP_OPTIM

    可选"release"或"debug",发布模式高度优化, 调试模式更适用于调试,默认是"release"

    标签下的android:debuggable可能使默认模式变成"debug",此时需要显示指定模式为release;
  • APP_CFLAGS
  • APP_BUILD_SCRIPT

    NDK build system默认在jni/ 目录下的 Android.mk,如果想自己指定,可以使用这个变量
  • APP_ABI

    默认生成的机器码是 armeabi接口的, 可以使用该变量指定

    可多选APP_ABI := armeabi armeabi-v7a x86 mips
指令集
Hardware FPU instructions on ARMv7 based devices APP_ABI := armeabi-v7a
ARMv8 AArch64 APP_ABI := arm64-v8a
IA-32 APP_ABI := x86
Intel64 APP_ABI := x86_64
MIPS32 APP_ABI := mips
MIPS64 (r6) APP_ABI := mips64
All supported instruction sets APP_ABI := all
  • APP_PLATFORM
    目标android平台版本
  • APP_STL
    默认情况下 NDK编译系统使用android系统提供的最小化的C++运行库(system/lib/libstdc++.so) 可以更改为其它的运行库
0 Comments
Leave a Reply