Android studio NDK-JNI 编译so文件

上篇我们编写了NDK代码了。也调用到了C/C++的方法,这篇我们来编译成动态库so文件, 在编译生成SO文件需要配下Android.mk文件 为什么需要这个文件Android.mk。当你需要使用JNI的时候,你需要创建一个native工程。Android.mk就是一个makefile配置文件,帮你把C/C++的代码编译成动态库so的。 我们来看下Android.mk文件内容

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hellojni
LOCAL_SRC_FILES := hajskdh.c
include $(BUILD_SHARED_LIBRARY)

解释下这几行代码:

LOCAL_PATH := $(call my-dir) 它用于在开发树中查找源文件。 在这个例子中,宏函数‘my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。

include $(CLEAR_VARS) CLEAR_VARS 由编译系统提供(可以在 android 安装目录下的/build/core/config.mk 文件看到其定义,为 CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk),指定让 GNU MAKEFILE为你清除许多 LOCAL_XXX 变量 ( 例如 LOCAL_MODULE , LOCAL_SRC_FILES ,LOCAL_STATIC_LIBRARIES,等等…),除 LOCAL_PATH。这是必要的,因为所有的编译控制文件都在同一个 GNU MAKE 执行环境中,所有的变量都是全局的。

LOCAL_MODULE := hellojni LOCAL_MODULE变量必须定义,以表示你在Android.mk文件中描述的每个模块名称必须是唯一的,通俗的说这个就是你最后生成so的名称,比如你填写的hellojni最后生成的就是libhellojni.so文件。注意:如果把库命名为‘libhellojni’,编译系统将不会添加任何的 lib 前缀,也会生成libhelloworld.so,这是为了支持来源于 Android平台的源代码的 Android.mk 文件。

LOCAL_SRC_FILES := hajskdh.c LOCAL_SRC_FILES变量必须包含将要编译的打包进模块中的C/C++文件源码。这里不需要引用头文件。

include $(BUILD_SHARED_LIBRARY) BUILD_SHARED_LIBRARY 是编译系统提供的变量,指向一个 GNU Makefile 脚本(应该就是在 build/core 目录下的 shared_library.mk) ,负责收集自从上次调用 'include $(CLEAR_VARS)'以来,定义在 LOCAL_XXX 变量中的所有信息,并且决定编译什么,如何正 确地去做。并根据其规则生成静态库。同理对于静态库。

Android.mk是必要文件,那么application.mk就是不是必要文件了。这个文件目的是描述在你的应用程序中所需要的模块(即静态库或动态库)。


APP_MODULES := hellojni

APP_ABI := all

这两行就相对简单, APP_MODULES这个变量是可选的,如果没有定义,NDK将由在Android.mk中声明的默认的模块编译,并且包含所有的子文件(makefile文件)如果APP_MODULES定义了,它不许是一个空格分隔的模块列表,这个模块名字被定义在Android.mk文件中的LOCAL_MODULE中。 APP_ABI默认情况下,NDK的编译系统"armeabi"ABI生成机器代码。 all就表示所有类型都生成, 如果不需要全部只需要部分就可以设置APP_ABI := armeabi armeabi-v7a x86 这样就ok。 以上介绍是的编译SO需要的两个配置文件。那么接下来就正式编译so文件,找到之前hellojni项目的jni目录,在目录上右键选择ndk-build(在前篇有介绍的,不知道的同学可以过去看下)。点击完成就可以看到控制台输出的结果如下,

输入图片说明 这里就会看到项目目录里面多生成了两个目录一个是libs,另一个是obj。libs下面就是编译生成的so对应的机器码,然后obj目录就没有什么用可以删除了。这里需要注意下obj这个目录在第二次编译之前请删除掉。不然二次编译就会收到影响。 删除的编译生成的文件可以使用ndk-build clear这个命令配置。这个命令就会清楚之前因编译生成的so相关文件,

我们在介绍另一种编译SO文件的办法,这种办法相对上面一种办法对依赖AS相对较少。 这里可以使用.sh脚本去执行编译SO文件操作。我们先介绍下.sh模板

#!/usr/bin/env bash

NDK_PROJECT_PATH=../

function build_so(){
    ANDROID_MK=Android.mk
    APPLICATION_MK=Application.mk
    XXX/xxx/xxx/android-ndk-r12b/ndk-build -j8 NDK_TOOLCHAIN_VERSION=clang NDK_DEBUG=$1
    #-platforms
}
#set_env
DEBUG=1
RELEASE=0;
build_so $RELEASE

以上就是build.sh的模板了。 直接将这段代码复制到文本后缀名改为.sh 然后将xxx/xxx/xxx/Android-ndk/ndk-build更改为你当前ndk的存放目录即可。 运行的话打开命令行进入到项目目录的jni目录下,然后执行sh build.sh文件即可得到同上面一样效果的文件目录结构。

以上还需要注意点内容就是: 通过AS编译出来的so文件配置是可以不需要依赖Aapplication.mk文件的。它对应的配置文件是build.gradle 中这个配置,所以在调整自己需要的so文件的时候注意下,

//定义使用ndk
        ndk{
            moduleName "hellojni"         //生成的so名字
            abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种abi体系结构下的so库。目前可有可无。
        }

而通过脚本编译出来以来的文件就是Aapplication.mk所以最后在使用的时候记得分清楚。以免搞混乱了。

转载于:https://my.oschina.net/u/1270405/blog/737699

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值