美文网首页Android JNIAndroid知识Android开发
Android JNI之执杖生涯 .a -> .so(mk

Android JNI之执杖生涯 .a -> .so(mk

作者: 流浪的乌托邦 | 来源:发表于2017-06-10 08:22 被阅读178次

    缘由

    曾梦想仗剑走天涯,看一看世界的繁华。岂料一入 JNI 深似海,从此女神是路人。生成so文件,是每个 JNI 人的终极梦想。前段日子,公司人少,扔过来的是cpp实现文件,呵呵,以为要往c渣渣方向发展,吓得我赶紧拿起那本红皮书,c++从入门到放弃。几个月过去,书还没人捧热,cpp不见了,取而代之是.a文件,什么玩意儿?掏出度娘,怒刷binggo。一手Shadowsocks,谷狗汪汪汪。静态库,简单来说,编译器认识,而linux不认识。故事,从这里开始。

    .a 怎么用

    想用就用,用得响亮。我就静静的,静静的看着。一巴掌一个脚印,啪啪啪,痛吗?不痛,轻轻松松三步走。

    啪. 定位

    下药要对口,位置不能随心。来来来,jni (JNI Floder)目录下。又回到最初的起点,记忆中你cpp文件的位置(打个广告,参考我前边写的关于JNI文章)。对,没错,又是jni目录。进阶的.a,还是老地方,熟悉的味道,不一样的配方。然,no pic no bb。呐~*@……#!#!神圣召唤术 --- 图图图。


    JNI目录图

    上边的sources目录是瞎写的,归个类。这里有东西解释下,比如说 arm64-v8a之类的, 这个是指cpu类型。目前而言,armeabi 这个是基类,所有手机都支持的类型。芸芸众手机,天涯cpu类型what?no,no,nobody I want nobody nobody But You,一个字:懒。so armeabi,你值得拥有。x86/x86-64这个一般是电脑cpu类型,模拟器用得上。如果能够每个类型都build出来,自然是好的,毕竟每个类型cpu都有各自的优化。

    啪啪. 链接

    重点来了。使用.a的过程,就是链接。当然不仅仅是,整个打包成so过程,都是链接过程,这里主讲如何链接.a。
    mk,从 jni 诞生那一刻起,随之诞生。这里暂且先讲mk方式实现链接,其它暂且不提。悠久的历史,脚本性质的配置,承载着老一辈人的远方与诗。左手,右手,一个慢动作。一步两步三四步,带你走个过场。记住了,固然可喜,若是没有,就再看一遍吧。


    mk版结构图
    # Android.mk文件,稍作修改,即可食用
    LOCAL_PATH := $(call my-dir)
    
    //链接.a块
    include $(CLEAR_VARS)
    LOCAL_MODULE := libHello
    LOCAL_C_INCLUDES := $(LOCAL_PATH)/sources
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/sources
    LOCAL_SRC_FILES := sources/$(TARGET_ARCH_ABI)/libHello.a
    include $(PREBUILT_STATIC_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_CPPFLAGS  := -std=c++14
    LDFLAGS := -shared
    LOCAL_LDFLAGS += -fuse-ld=bfd
    LOCAL_MODULE           := JniDemo
    LOCAL_SRC_FILES        :=   jni_dynamic.cpp
    LOCAL_STATIC_LIBRARIES := libHello
    include $(BUILD_SHARED_LIBRARY)
    
    # Application.mk 这个基本不需要改
    APP_STL := gnustl_static//使用 STL 静态库
    NDK_TOOLCHAIN_VERSION := 4.9//链接器tool版本
    /**
     *fexceptions 允许异常功能
     *frtti 运行时类型识别
     *fpermissive 此项有效时表示宽松的编译形式,比如没有用到的代码中有错误也可以通过
     * std=c++14 允许使用c++14的函数等功能
     */
    APP_CPPFLAGS := -fexceptions -frtti -fpermissive -std=c++14
    APP_ABI := armeabi armeabi-v7a arm64-v8a mips mips64
    APP_PLATFORM := android-14
    APP_OPTIM := debug
    

    这2个固定搭配,没什么需要特别解释的地方,照搬砖头即可。如果你砸到了自己的脚,火速120,你来找我也没用。mk文件已经就位,当然还需要build.gradle的支持。

    android{
        ....
        task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
            commandLine "E:/adt-bundle-windows-x86_64-20140321/android-ndk-r10/ndk-build.cmd",//ndk.build位置
                    'NDK_PROJECT_PATH=build/intermediates/ndk',//ndk位置
                    'NDK_LIBS_OUT=src/main/jniLibs',//输出目录
                    'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
                    'NDK_APPLICATION_MK=src/main/jni/Application.mk'
        }
        tasks.withType(JavaCompile) {
            compileTask -> compileTask.dependsOn ndkBuild
        }
    }
    

    这段,不解释呢,说不过去。解释呢,一句话,自定义ndkbuild命令(生成so的利器)。到这里本想着已经告一段路了,是时候见证奇迹的时刻了。然而还不料,一个error让我沉醉,毫无保留,没有余力悲伤:

    D:\Study_Code\JniDemo\app\src\main\jni\sources\hello.h
    Error:(1, 18) string: No such file or directory
    Error:Execution failed for task ':app:compileDebugNdk'.
    > com.android.ide.common.process.ProcessException: Error while executing 'E:\adt-bundle-windows-x86_64-20140321\android-ndk-r10\ndk-build.cmd' with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=D:\Study_Code\JniDemo\app\build\intermediates\ndk\debug\Android.mk APP_PLATFORM=android-25 NDK_OUT=D:\Study_Code\JniDemo\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=D:\Study_Code\JniDemo\app\build\intermediates\ndk\debug\lib APP_ABI=all}
    

    显然,c++中string找不到。哟哟哟,切克闹。bug,bug,bug,惊起一滩苦水。既然开启了自定义,那么就需要做点限制,比如说禁用自动执行ndk-build。如果自动执行ndk-build的话,那么我的Application.mk配置将失效,默认是c环境,缘来如此。

    android{
        ...
        sourceSets {
            main {
                jni.srcDirs = []//禁用自动执行ndk-build 
            }
        }
    }
    

    .mk 这艘小船,到这儿,已经上岸了。

    啪啪啪.见证奇迹的时刻

    上边的已然做到,那么这一刻,属于你的奇迹终究还是到来了。biu,biu,build。接下来,或许更精彩。
    附送一张机票,带你领略世界的浩瀚

    相关文章

      网友评论

      本文标题:Android JNI之执杖生涯 .a -> .so(mk

      本文链接:https://www.haomeiwen.com/subject/arfefxtx.html