Android JNI编译语法总结

Posted Nipuream

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android JNI编译语法总结相关的知识,希望对你有一定的参考价值。

android现在JNI相关的代码编译成so主要有两种方式,一种是传统的ndk-build,还有就是CMakeLists.txt,接下来总结下Android.mk、Application.mk、CMakeLists.txt文件的语法。

Android.mk

  1. 配置环境变量,定义当前模块的相对路径

    LOCAL_PATH := $(call my-dir)
    
  2. 清空当前环境变量,除 LOCAL_PATH外的所有环境变量

    include $(CLEAR_VARS)
    
  3. 编译生成的目标文件的文件名

    LOCAL_MODULE := test
    
  4. 编译该模块所需的源文件,多个源文件使用连接符 “” 连接

    LOCAL_SRC_FILES := test.c
    
  5. 编译所生成的目标文件的格式

     include $(BUILD_EXECUTABLE)   二进制可执行文件
     include $(SHARED_LIBRARIES)  动态库文件
     include $(STATIC_LIBRARY) 静态库文件
     include $(JAVA_LIBRARIES) jar包
     include $(PACKAGE) apk
    
  6. 外部头文件路径申明

    LOCAL_C_INCLUDES += ../../depend/  
    
  7. 源文件路径声明

    LOCAL_SRC_ROOT =  ../../src
    LOCAL_SRC_DIR += global general helper
    
  8. 查找cpp源文件

       LOCAL_SRC_PATH := $(patsubst %, $(LOCAL_SRC_ROOT)/%, $(LOCAL_SRC_DIR))
       LOCAL_SRC_PATH += ../../src
       LOCAL_SRC_FILES += $(foreach dir, $LOCAL_SRC_PATH, $(wildcard $(dir)/*.cpp))
    
  9. 在工程中引入系统库

    #system lib
    LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
    
  10. 引入第三方so库

     #这种一般是编译好的so去链接,不需要去重新编译
     LOCAL_LDFLAGS += -L../../depend/platformsdk
     LOCAL_LDLIBS += -lplatformsdk
    
  11. 引入第三方源码库

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= libtest3
    LOCAL_C_ALL_FILES := src/test1.cpp
    LOCAL_SRC_FILES := $(LOCAL_C_ALL_FILES)
    LOCAL_MODULE_PATH := $(LOCAL_PATH)/lib
    include $(BUILD_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= test3
    LOCAL_C_ALL_FILES := src/main.cpp
    LOCAL_SHARED_LIBRARIES += liblog
    LOCAL_SRC_FILES := $(LOCAL_C_ALL_FILES)
    LOCAL_MODULE_PATH := $(LOCAL_PATH)/bin
    include $(BUILD_EXECUTABLE)
    
  12. 代码中如何引入第三方头文件

    #include "/inc/base/test.h"   //这种引入头文件写起来比较麻烦
    //可以在Android.mk文件修改下头文件路径
    LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc/base
    //然后代码中可以这样引入
    include <test.h>
    
  13. 引入第三方静态库

    LOCAL_LDFLAGS := $(LOCAL_PATH)/lib/libtest2.a 
    

Application.mk

  
# 编译成什么类型的cpu的so文件
APP_ABI := armeabi
# 如何连接c++标准库
# stlport_static 静态链接
# stlport_shared 动态链接
# system 系统默认
# gnustl_static gnustl_shared Android上的GNU c++库,对应 GNU/LINUX 系统中的 libstdc++
# 这个库和gcc 仅仅绑定,但是后期不在更新,最新NDK不再支持,逐渐要废弃
APP_STL := gnustl_shared
#优化选项 此变量是可选的, release/debug  debug 便于调试未被优化的二进制机器码
APP_OPTIM := release
APP_CPPFLAGS := frtti
APP_CPPFLAGS := -std=c++11
APP_CPPFLAGS := fpermissive
APP_CPPFLAGS := fexceptions
# SDK 使用的最低版本
APP_PLATFORM := android-11

CMakeLists.txt

  1. set 设置路径

    # set 可以设置单个文件路径或几个文件路径 以及设置路径
    set(SRC_LIST hello.cpp)
    set(SRC_LIST hello.cpp add.cpp sub.cpp)
    set(SRC_LIST include/dsp)
    
  2. 日志打印

    message("cmake path : $CMAKE_SOURCE_DIR")
    
  3. 设置头文件路径

    include_directories(src/include src/include/depend)
    
  4. 设置链接库搜索目录

    #添加共享库搜索路径
    link_directories(src/depend src/platform)
    
  5. 批量添加cpp文件

    set(CPP_SRC src/dsp)
    # 将目录下所有的cpp文件全都赋予 ALL_CPP
    file (GLOB ALL_CPP $(CPP_SRC)/*.cpp $(CPP_SRC)/alarm/*.cpp $(CPP_SRC)/android/*.cpp)
    
  6. 生成共享库文件

    add_library(
         #生成共享库文件名字
         mysdk   
         # 共享库还是静态库 SHARED/STATIC
         SHARED
         #源码路径
         $ALL_CPP
    )
    
  7. 为生成的库/可执行文件生成共享库链接

    target_link_libraries(
       mysdk
       android
       log
       dsl
       platform
    )
    
  8. 生成可执行文件

    add_executable(hello hello.cpp)
    
  9. 指定 .so 动态库的目录位置

    set(LIBRARY_OUTPUT_PATH $PROJECT_SOURCE_DIR/lib)
    
  10. 指定生成版本号 VERSION 指动态库版本,SOVERSION指API版本

    set_target_properties(math PROPERITIES VERSION 1.2 SOVERSION 1)
    
  11. 指定 cmake 最低编译版本

    CMAKE_MINIMUM_REQUIRED(VERSION 3.14)
    
  12. 指定cpu架构

    # 需要在build.gradle 中指定
    android 
        defaultConfig 
                ...
                ndk 
                abiFilters "arm64-v8a", "armeabi-v7a", "x86", "x86_64"
                
        
        externalNativeBuild 
            cmake 
                path "src/main/cpp/CMakeLists.txt"
                version "3.10.2"
            
        
    
    

以上是关于Android JNI编译语法总结的主要内容,如果未能解决你的问题,请参考以下文章

Android JNI之编译

Android JNI 使用总结

Android-JNI开发系列《八》CMakeLists.txt语法&使用

超全Android JNI&NDK编程总结

深入了解android平台的jni

关于JNI调用从eclipse转到Android Studio遇到的问题(总结)