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 
    
  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)