Android进阶NDKAndroid技术知识

Android NDK 知识大全

2017-08-18  本文已影响150人  赵海洋

引用

基本概念

NDK安装配置

编译选项

资料整理

无论是用Android Studio集成NDK,还是手动使用NDK命令行,有两个文件是必须的

Android.mk

示例:

LOCAL_PATH := $(call my-dir) # 必须要使用这个开头
include $(CLEAR_VARS)  # 必须,清除编译环境中所有的LOCAL变量,否则同时编译多个Module时不同的Android.mk里的LOCAL变量会相互影响

LOCAL_MODULE    := mcpelauncher # 必须,定义模块名称
# 必须,源文件文件列表
LOCAL_SRC_FILES := nativepatch.c modscript.c modscript_nextgen.cpp modscript_ScriptLevelListener.cpp utf8proc_slim.c dobby.cpp

LOCAL_C_INCLUDES += E:\C_Shared\sdk\ndk-bundle\platforms\android-14\arch-arm\usr\include\

LOCAL_LDLIBS := -llog   # 需要链接的NDK库
LOCAL_SHARED_LIBRARIES := tinysubstrate-bin

# 必须,包含定义好的一个文件,获取抽有LOCAL变量并决定构建信息
include $(BUILD_SHARED_LIBRARY)

$(call import-add-path, prebuilts) # 其它导入模块
$(call import-module, tinysubstrate-bin)

变量和宏

命名规则:

NDK预定义变量

模块定义变量

这些变量是每个模块单独设置的,每个模块都需要做以下事情:

  1. 初使化模块变量或者用CLEAR_VARS清除
  2. 给一些变量赋值来描述模块的功能
  3. 使用NDK预定义变量中的BUILD_XXX来定义模块的格式(动态库、静态库等)

变量列表(粗体为必须):

预定义函数

Application.mk

示例:

APP_ABI := x86 #只生成x86架构的CPU用的lib,要生成所有平台的可以改为all    
#APP_STL := stlport_static  
NDK_TOOLCHAIN_VERSION=4.7 #使用GCC4.7  
APP_STL := gnustl_static #GNU STL  
APP_CPPFLAGS := -fexceptions -frtti #允许异常功能,及运行时类型识别  
APP_CPPFLAGS +=-std=c++11 #允许使用c++11的函数等功能  
APP_CPPFLAGS +=-fpermissive  #此项有效时表示宽松的编译形式,比如没有用到的代码中有错误也可以通过编译;使用GNU STL时不用此项std::string 居然编译不通过!! 

变量

gradle配置

如果不用android studio集成编译,而是使用ndk-build手动编译,则不需要配置gradle。

nkd的配置也分散在grale中android节点下面的各个节点中,主要在ndk,defaultConfig.externalNativeBuild.ndkBuildexternalNativeBuild.ndkBuild中,同时在sourceSets中对文件包含进行一些修改,flavor和build-types在不同的编译选项下打不同的包。

必须节点 android.externalNativeBuild

这里至少要包括cmake和ndkbuild结节之一,来表明ndk的编译系统。
然后子结点中,只能设置路径(path参数),只有当Android.mk或CMakeLists.txt不在默认目录上时使用此选项指定目录。

android {
  ...
  defaultConfig {...}
  buildTypes {...}

  // 这里至少要包括cmake和ndkbuild结节之一,来表明ndk的编译系统
  externalNativeBuild {
     // AndroidStudio2.2以上就添加了Cmake方式来编译NDK代码,但还是可以使用老方法
     ndkBuild {
 
           path "src/main/jni/Android.mk"

          //path "prebuilts/tinysubstrate-bin/Android.mk"
 
    }

    // Encapsulates your CMake build configurations.
    cmake {

      // Provides a relative path to your CMake build script.
      path "CMakeLists.txt"
    }
  }

  // If you want Gradle to package prebuilt native libraries
  // with your APK, modify the default source set configuration
  // to include the directory of your prebuilt .so files as follows.
  sourceSets {
      main {
          jniLibs.srcDirs 'imported-lib/src/', 'more-imported-libs/src/'
      }
  }
}

android.defaultConfig.ndk

接口原型

public interface CoreNdkOptions {
    String getModuleName();
    String getcFlags();
    List<String> getLdLibs();
    Set<String> getAbiFilters();
    String getStl();
    Integer getJobs();
}

注意这里也有cFlags和AbiFilters,这两项和下面的android.defaultConfig.externalNativeBuild重复,原因暂时我还不知道。

使用示例:

ndk {//在android节点下面
   // 生成so的名字,是必须的

   moduleName ="JNITest"

  toolchain = 'clang'
  CFlags.add('-std=c99')

 // 添加依赖库
 ldLibs.addAll(['android','OpenSLES', 'log'])

 // 生成不同abi体系的so库

  abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a',                                   'x86', 'x86_64',
'mips', 'mips64'])


}  

android.defaultConfig.externalNativeBuild

构建参数,可以在每个Flavor里特殊定义。
文档,接口原型为:

public interface CoreExternalNativeNdkBuildOptions {
    List<String> getArguments();
    List<String> getcFlags();
    List<String> getCppFlags();
    Set<String> getAbiFilters();
    Set<String> getTargets();
}

在gradle里的使用方法见这里

buildTypes

buildTypes {
    release {
        minifyEnabled = false
        proguardFiles.add(file('proguard-rules.pro'))
    }
    debug {
        jniDebuggable true //有这个才会支持调试native 代码,这个放到release里一样能用
    }
}
上一篇 下一篇

猜你喜欢

热点阅读