如何在 Android Studio 中使用我自己的 Android.mk 文件

Posted

技术标签:

【中文标题】如何在 Android Studio 中使用我自己的 Android.mk 文件【英文标题】:How to use my own Android.mk file with Android Studio 【发布时间】:2015-03-06 04:16:51 【问题描述】:

我在android.mk 文件中定义了一些变量(我为编译器传递了一些标志),但是每次构建我的项目时,Android.mk 都会被覆盖。我假设Gradle 负责,我应该去那里看看? 如何使用我自己的 Android.mk 文件?

背景信息:

Ubuntu 64 位,Android Studio 1.0.1,JDK7。 我已经用O-LLVM NDK 包装了我的NDK 版本,因此正在编辑位于app/build/intermediates/ndk/debugAndroid.mk 文件(它是我的项目目录中唯一的Android.mk 文件),与文档所在的位置不同O-LLVM 给出了例子。

另外,没有Application.mk 文件,所以我再次假设Gradle 负责调用编译器?


更新信息

build.gradle - (应用)

//The following code until the "----" line is the new build.gradle config file
// that disables automatic Android.mk file generation

import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application'

android 

    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig 
        applicationId "com.md.helloworld"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
        ndk 
            moduleName "MyLib"
        
    

    buildTypes 
        release 
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        
    

    sourceSets.main 
        jniLibs.srcDir 'src/main/libs' //set libs as .so's location instead of jni
        jni.srcDirs = [] //disable automatic ndk-build call with auto-generated Android.mk file
    

    // Call regular ndk-build (.cmd) script from the app directory
    task ndkBuild(type: Exec) 
        commandLine 'ndk-build', '-C', file('src/main/').absolutePath
    

    tasks.withType(JavaCompile) 
        compileTask -> compileTask.dependsOn ndkBuild
    


dependencies 
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'


/*
//The following code is the original Android.mk file

apply plugin: 'com.android.application'

android 
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig 
        applicationId "com.md.helloworld"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
        //The only modified line
        ndk 
            moduleName "MyLib"
        
    
    buildTypes 
        release 
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        
    


dependencies 
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'

*/

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := helloWorld
LOCAL_SRC_FILES := main.c

LOCAL_LDLIBS := -static

include $(BUILD_EXECUTABLE)

Application.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

APP_ABI := armeabi

NDK_TOOLCHAIN_VERSION := clang3.4-obfuscator

include $(BUILD_EXECUTABLE)

请注意:我还没有通过任何 cflags,我正在尝试让 Vanilla 构建首先工作

【问题讨论】:

【参考方案1】:

是的,默认情况下,gradle android 插件会重新生成并使用其自己的 Android.mk 文件来编译您的源代码。

您可以停用它并使用您自己的 Android.mk 文件,方法是在您的 build.gradle 配置文件中设置它:

import org.apache.tools.ant.taskdefs.condition.Os
...     
android 
    ...

    sourceSets.main 
        jniLibs.srcDir 'src/main/libs' //set libs as .so's location instead of jniLibs
        jni.srcDirs = [] //disable automatic ndk-build call with auto-generated Android.mk
    

    // call regular ndk-build(.cmd) script from app directory
    task ndkBuild(type: Exec) 
        if (Os.isFamily(Os.FAMILY_WINDOWS)) 
            commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
         else 
            commandLine 'ndk-build', '-C', file('src/main').absolutePath
        
    

    tasks.withType(JavaCompile) 
        compileTask -> compileTask.dependsOn ndkBuild
    

请注意,如果您只需要将自己的 cflags 传递给自动生成的 Makefile,您可以在 cFlags "" 属性中设置这些以在 android ndk 中设置

【讨论】:

谢谢 ph0b。我现在遇到的问题是 build.gradle 配置文件中对 ndk-build 的调用无法编译,因此我删除了该行并删除了 Java 编译器的依赖项,并从命令行运行 ndk-build。这可以很好地构建 ndk,但是我不再生成 .so 文件。有什么指示或提示吗? 我不明白为什么它不能编译,也许你忘记了 import org.apache.tools.ant.taskdefs.condition.Os ? .so 由 ndk-build 生成,默认在 libs/(armeabi|armeabi-v7a|x86|mips|...) 中。检查“src/main/libs”路径是否正确以及您的 .so 文件是否存在。 您好 ph0b,我已修复编译错误,ndk-build 无法作为命令使用,因此已排序。我现在遇到的问题是 .so 文件没有在任何地方生成。我已经在整个项目目录中搜索了它们,但是自从使用新的 gradle 文件构建项目后就没有运气了。该项目构建良好,但在尝试运行时,出现 UnsatisfiedLinkError 因为它找不到 libMyLib.so 文件。我已经用我的 gradle.build 文件以及 Android.mk 文件和 Application.mk 文件更新了我的问题。非常感谢 ph0b 您必须将BUILD_EXECUTABLE 替换为BUILD_SHARED_LIBRARY。 Application.mk 在您的情况下应该只有 APP_ABINDK_TOOLCHAIN_VERSION 声明。您还应该将 APP_ABI 设置为 all 以便为所有受支持的 cpu 架构生成您的库。 感谢 ph0b,现在一切正常。对于尝试此操作的其他人,我还必须将 LOCAL_LDLIBS 设置为 -shared 并且必须将 LOCAL_MODULE 设置为 MyLib 以匹配我的 Java 文件声明。如果有人需要我上传最终文件以允许使用新的 Android Studio 混淆本机代码,我很乐意这样做。我只是在为非 arm 架构调试构建,以便我们可以在 x86 模拟器上运行它!

以上是关于如何在 Android Studio 中使用我自己的 Android.mk 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何将谷歌键盘(Gboard)添加到我自己的 android studio 项目中?

Android Studio使用之前如何进行配置

如何使用android studio把自己的android library分享到jcenter和maven central

如何在visual studio开发android程序

如何在 android studio 中禁用 OTP Captcha

Android studio 如何启动