zoukankan      html  css  js  c++  java
  • android学习-ndk-build(androidstudio编译cocos2d-x库的cpp为so文件的解释)

    本文不作为ndk初学使用,只是对cpp等c++文件编译成so文件的过程中,参数含义,及ndk配置的解释。使用的技术比较旧。

    androidStudio使用gradle调用ndk-build工具编译c++代码, 使用ndk-build来进行编译,而不是使用最新版本的cmake工具

     在gradle配置的参数最后都是调用ndk-build命令去执行Android.mk和Application.mk文件

    Android.mk文件指定需要编译的c或c++文件

    Application.mk文件用来描述应用程序需要的模块,需要生成的.so文件

    commandLine "$ndkDir/ndk-build.cmd", "NDK_PROJECT_PATH=$projectDir.absolutePath\build", 
          "APP_BUILD_SCRIPT=$projectDir.absolutePath\src\main\jni\Android.mk",
           "NDK_APPLICATION_MK=$projectDir.absolutePath\src\main\jni\Application.mk"

    build.gradle配置参数

    也就是在执行jni/Android.mk文件进行编译时需要用到的环境变量

    build.gradle

    defaultConfig {
        。。。
        externalNativeBuild {
                ndkBuild {
                    targets 'cocos2djs'
                    arguments 'NDK_TOOLCHAIN_VERSION=4.9'
                    arguments 'APP_PLATFORM=android-19'
                    arguments 'NDK_MODULE_PATH=cocos2d-x;cocos2d-x/cocos;cocos2d-x/external'
                    arguments '-j' + Runtime.runtime.availableProcessors()
                    abiFilters.addAll(['armeabi-v7a'])
                }
        }
    }
    
    externalNativeBuild {
        ndkBuild {
            if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
                // skip the NDK Build step if PROP_NDK_MODE is none
                path "jni/Android.mk"
            }
        }
    }

    使用targets指定我们编译的模块,其实就是指定只执行哪个Android.mk文件,这个是跟path 指定的路径jni/Android.mk相匹配的

    jni/Android.mk文件中已经定义的模块名

    LOCAL_MODULE := cocos2djs_shared
    LOCAL_MODULE_FILENAME := libcocos2djs

    最后输出的so文件是libcocos2djs.so   也可以不加lib前缀,ndk会自动添加前缀。这个模块名就是cocos2djs,也就是上面我们指定的targets:cocos2djs

    如果修改了这个targets 'zwhcocos2djs',则会报错。Valid values are:这句后面的都是查找到的所有模块名

    > Unexpected native build target zwhcocos2djs. Valid values are: extension, creator, audioengine, cpufeatures, cocos2dandroid, spine, vorbisidec, network, cocos2djs, dragonbones, jscocos2d, ui, cocos2dxinternal, 

    使用arguments来定义ndk的运行时用到的环境变量值

    arguments 'NDK_TOOLCHAIN_VERSION=4.9'

    NDK_TOOLCHAIN_VERSION=4.9 配置ndk使用的gcc编译工具版本
    APP_PLATFORM=android-19 设置android平台版本
    NDK_MODULE_PATH=cocos2d-x;cocos2d-x/cocos;cocos2d-x/external 
    arguments '-j' + Runtime.runtime.availableProcessors()
    这个-j参数后面是得到处理器的数量。指定使用多少个处理器进行ndk的编译
    abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64'])
    用来设置ndk需要编译的cpu架构,一般来说只需要armeabi-v7a,arm64-v8a,x86这三个cpu架构
    path "jni/Android.mk"
    设置要运行的mk文件路径

    NDK_MODULE_PATH是用来设置模块的路径,在windows系统上使用分号;在非windows系统上使用冒号:分隔不同的ndk模块路径

    会在Android.mk中调用执行其他模块的android.mk文件时使用

    $(call import-module, scripting/js-bindings/proj.android)

    执行上面代码时,会查找上面的模块路径,如果存在这个$modulePath/scripting/js-bindings/proj.android/Android.mk文件,则会执行这个文件。

    所有模块路径下都找不到文件时,则会报错Are you sure your NDK_MODULE_PATH variable is properly defined。

    jni/ Android.mk代码

    如果需要查看Android.mk语法可以查看下这个https://www.cnblogs.com/gne-hwz/p/9996641.html 

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := cocos2djs_shared
    LOCAL_MODULE_FILENAME := libcocos2djs
    
    ifeq ($(USE_ARM_MODE),1)
    LOCAL_ARM_MODE := arm
    endif
    
    LOCAL_SRC_FILES := hellojavascript/main.cpp 
                       ../../../Classes/AppDelegate.cpp 
                       ../../../Classes/jsb_module_register.cpp 
    
    LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../Classes
    
    ifeq ($(USE_ANY_SDK),1)                   
    LOCAL_SRC_FILES += ../../../Classes/anysdk/SDKManager.cpp 
                       ../../../Classes/anysdk/jsb_anysdk_basic_conversions.cpp 
                       ../../../Classes/anysdk/manualanysdkbindings.cpp 
                       ../../../Classes/anysdk/jsb_anysdk_protocols_auto.cpp
    
    LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../Classes/anysdk
    
    LOCAL_WHOLE_STATIC_LIBRARIES := PluginProtocolStatic
    endif
    
    
    LOCAL_STATIC_LIBRARIES := cocos2d_js_static
    
    LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 -DCOCOS2D_JAVASCRIPT
    
    include $(BUILD_SHARED_LIBRARY)
    
    
    $(call import-module, scripting/js-bindings/proj.android)
    View Code

     上面代码的意思是使用LOCAL_SRC_FILES指定的cpp文件 作为编译模块的源文件,也就是说ndk会编译这些cpp文件,然后聚合到一个模块中。

    最后一行是查找在gradle中定义NDK_MODULE_PATH路径中查找相对路径为scripting/js-bindings/proj.android/Android.mk文件,并执行这个Android.mk文件

    然后这个proj.android下的文件mk文件会继续调用cocos文件夹下的mk文件,调用,调用,调用!。最后c++或c代码就编译完成了。

    Application.mk目的是描述在你的应用程序中所需要的模块,这是一个可选文件,规定怎么编译so文件

    比如,设置编译的模式debug或者release

      使用这个变量设置编译模式APP_OPTIM := release  默认是release模式

    --------------- 越长大越无知

  • 相关阅读:
    咖啡里的梦
    杨元庆精彩演讲
    鲍尔默演讲
    买房子的涉及到的一些费用说明
    未来是通胀的十年
    百名经济学家企业家88%认为当前通胀情况严重
    给陌生人写一封信
    晌午时的休憩
    34个实用确很多人不知道的偏方
    思念
  • 原文地址:https://www.cnblogs.com/gne-hwz/p/9989746.html
Copyright © 2011-2022 走看看