JNI在编译时的源文件和生成文件的层次结构详解

来源:互联网 发布:基恩士视觉软件 编辑:程序博客网 时间:2024/05/17 02:39
  • Android.mk文件的配置介绍
  • 源文件和生成文件的层次结构
  • 结合程序的具体介绍

Android.mk文件的相关配置简介

之前如果你对JNI还不是很了解,建议你去看一下我之前写的两篇有关JNI的博客,脑补一下JNI。在这里我当你是了解的。主要围绕生成.so文件时的相关文件层次结构来介绍,当你把自己的程序的这方面的文件夹层次结构分析清楚了之后,你才会有进一步的提高。脚踏实地,一步一步来吧!

LOCAL_PATH 编译时的目录,具体怎么用我会在后面将代码贴出来
include $(CLEAR_VARS) 清除之前的一些系统变量,一般都是放在目录配置的下面(因为这些变量是静态全局的,如果清除,下次编译时又会用到这些变量造成出错)
LOCAL_MODULE 编译生成的目标对象,就是生成的文件名
LOCAL_SRC_FILES 编译的源文件
LOCAL_C_INCLUDES 需要包含的头文件目录
LOCAL_SHARED_LIBRARIES 链接时需要的外部库
LOCAL_PRELINK_MODULE 是否需要prelink处理(Prelink利用事先链接代替运行时链接的方法来加速共享库的加载,它不仅可以加快起动速度,还可以减少部分内存开销。当然啦有利就会有弊。具体的可以百度一下)
include$(BUILD_SHARED_LIBRARY) 指明要编译成动态库
include$(BUILD_STATIC_LIBRARY) 指明要编译成静态库

LOCAL_MODULE_TAGS :=user eng tests optional
user: 指该模块只在user版本下才编译
eng: 指该模块只在eng版本下才编译
tests:指该模块只在tests版本下才编译
optional:指该模块在所有版本下都编译

LOCAL_CFLAGS-D,增加全局宏定义。
LOCAL_CFLAGS := -DUSE_JSC相当于在所有源文件中增加一个#define USE_JSC
LOCAL_CFLAGS := -DUSE_COPY_BIT=1相当于在所有源文件中增加一个#define USE_COPY_BIT 1
还有其它的像-W等,都是传递给编译使用的。

LOCAL_LDLIBS :链接的库不产生依赖关系,一般用于不需要重新编译的库,如库不存在,则会报错找不到。且貌似只能链接那些存在于系统目录下本模块需要连接的库。如果某一个库既有动态库又有静态库,那么在默认情况下是链接的动态库而非静态库。

如:LOCAL_LDLIBS += -lm –lz –lc -lcutils –lutils –llog …

LOCAL_LDFLAGS:这个编译变量传递给链接器一个一些额外的参数,比如想传递而外的库和库路径给ld,或者传递给ld linker的一些链接参数,-On,-EL{B}(大小端字节序),那么就要加到这个上面,如:
LOCAL_LDFLAGS += -L$(LOCAL_PATH)/lib/ -lHWrecog –EB{EL} –O{n} …
或者直接加上绝对路径库的全名:
LOCAL_LDFLAGS += $(LOCAL_PATH)/lib/libHWrecog.a –EB{EL} –O{n}

LOCAL_DISABLE_FORMAT_STRING_CHECKS := true 本地禁用格式字符串检查

也许你可以不要把每个细节都弄明白,因为毕竟我们不是做正规开发类库的。所以了解它是如何开发的就已经足够了,起码以后看到了,可以知道怎么入手。

源文件和生成文件的层次结构

这里主要说明一下,相关文件的存放文件夹以及生成文件的存放文件夹。

程序的目录结果里lib文件夹一般是存放一些类库的可以使自动生成的(如果生成的文件不在这个文件夹就需要拷到这个文件夹下),也可以是从别的地方引入的。lib文件夹下也是分好几个文件夹的例如有 armeabi-v7a 和 armeabi(他们表示的是CPU的类型,所以相应的类库放在相应的文件夹也是十分重要的。)

有一个存放的底层文件的文件夹,取名一般与jni相关或者与你的实现的功能相关,在该文件夹的里面包括.c和.h文件。一般来说他们是成对出现的。还有相关的Android.mk文件,用于对生成.so文件进行配置。

obj文件夹,按照我的理解。一般在C语言编译的时候,都会生成.obj文件。所以这里的obj文件夹应该是存放编译时候的一下临时文件,如果类库在重新编译的遇到错误了,可以尝试着将该文件夹清空之后在重新编译一下,说不定就可以解决问题了。

结合程序的具体介绍

这里先把程序的jni结构图贴一下:然后在慢慢分析
JNI结构图
armeabi-v7a里面存放着我需要的两个类库,由于程序是关于视频直播的,所以一个是YUV数据的libyuv.so转换,一个是libx264.so实现将视频数据编码封装起来。该文件夹不是我程序编译时生成.so文件存放的默认目录,默认目录是libenc下的libs文件夹,我是从libs文件夹拷过来的;

libenc是JNI编译的主要文件了,它包括jni、libs、obj三个文件夹:

jni文件夹里面实现了两个功能:一是编译生成libx264.a静态类库(可以用于程序开发的编码H.264的类库),而是编译生成libyuv.so动态类库jni下的lib是存放libx264.a和libyuv.so类库的;libx264则是用于生成libx264.a所用到的全部底层文件以及头文件,Libyuv文件夹也是一样。在生成好libx264.a和libyuv.so类库后,我们Android.mk是如下配置的

配置文件

在这里主要是编译生成libenc.so文件。但编译这个需要引入libx264.a静态类库和libyuv.so动态库,其他的设置在上面都有介绍。最在生成了libenc.so和libyuv.so动态库(我看了大小没有改变可能是设置的时候要求生成动态库所以动态库就被完整地保存了下来,但是不是这样我还不清楚。只是我的猜想)

libs文件夹是默认的存放生成的类库文件夹,我所有生成的类库都在这里。当然需要用的时候拷贝到相应的文件夹就可以了。

obj文件时存放一些编译的时候存放的一下临时文件。

总结

程序所有代码不是本人独立完成,是引入别人的开源项目,但 ,是经过我的分析将自己的所有心得在这里做一个分享,就当是自己的学习笔记。欢迎大家支出批评,我一定虚心接受,不断改进。源代码就像是鸡肋,最没用的是他,最有用的也是他。如果每次仅仅是ctrl+c,ctrl+v,想进步是很难的。如果你仔细分析了代码,并得出了自己的理解,可以举一反三。这样才是真正的进步,不是吗?
忙,要有头绪。要脚踏实地,心中有爱,放飞梦想。向着自己的目标前进。 我是Mr.小艾

0 0