How to build an Android Gradle based app with NDK only for the ARM target?
Asked Answered
L

3

8

I have a .so file from vendor which only support "arm". Currently it works perfectly fine for my Android application. Somehow I want to separate the implementation using Android Studio module, so I can export the module as Jar following this tutorial https://www.youtube.com/watch?v=1i4I-Nph-Cw.

When I export the JAR, the build process returns an error

/Users/zoom/android-ndk-r9d/toolchains/mipsel-linux-android-4.8/prebuilt/darwin-x86_64/bin/../lib/gcc/mipsel-linux-android/4.8/../../../../mipsel-linux-android/bin/ld: skipping incompatible src/main/jniLibs/armeabi/libremote_client.so when searching for -lremote_client
/Users/zoom/android-ndk-r9d/toolchains/mipsel-linux-android-4.8/prebuilt/darwin-x86_64/bin/../lib/gcc/mipsel-linux-android/4.8/../../../../mipsel-linux-android/bin/ld: cannot find -lremote_client
collect2: error: ld returned 1 exit status

:app:linkMipsDebugRemoteDesktopSharedLibrary FAILED

FAILURE: Build failed with an exception.

The logs says that gradle was trying to build against mips but failed due the incompatible library, since I only have arm library. My question how to skip the build process against mips? Or is it possible to target ARM only architecture?

build.gradle

apply plugin: 'com.android.model.library'

model {
android {
    compileSdkVersion = 23
    buildToolsVersion = "22.0.1"

    defaultConfig.with {
        //applicationId = "com.test.remote"
        minSdkVersion.apiLevel = 19
        targetSdkVersion.apiLevel = 21
        //versionCode = 1
        //versionName = "1.0"
    }

}

android.ndk {
    moduleName = "remote_client"
    //CFlags += "-DANDROID_NDK"
    CFlags += ['-std=c99', '-fstrict-aliasing']
    ldLibs += ["log", "remoted_client"]
}

android.buildTypes {
    release {

        minifyEnabled = false
        proguardFiles += file('proguard-rules.pro')
    }
}

android.sources {
    main {
        jni {
            source {
                srcDir 'src/main/jni'
            }
        }
        jniLibs {
            source {
                srcDir 'src/main/jniLibs'
            }
        }
    }
}

android.productFlavors {
    create("arm") {
        ndk.with {
            abiFilters += "armeabi"
            ldFlags += "-Lsrc/main/jniLibs/armeabi"
        }
    }
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
}


task clearJar(type: Delete) {
delete 'mylib.jar'
}

task makeJar(type: Copy) {
   from('build/intermediates/bundles/release/')
   into('release/')
   include('classes.jar')
   rename ('classes.jar', 'mylib.jar')
}

makeJar.dependsOn(clearJar, build)
Ladylike answered 22/10, 2015 at 9:51 Comment(1)
According to grokbase.com/t/gg/android-ndk/125v31e6wy/… you can simply create empty files at jnilibs/mips/libremote_client.so and jnilibs/x86/libremote_client.so to fool the tools into thinking lib versions for the non-arm architectures exist. Just be sure to never do the loadLibrary when on non-arm device.Bungle
L
0

Finally I made it. Here's an example to disable specific task. Add this line on your build.gradle

tasks.getByPath(":app:linkMipsDebugRemoteDesktopSharedLibrary").enabled = false
Ladylike answered 27/10, 2015 at 22:46 Comment(0)
H
7

Tested on Android SDK 26, NDK 15.2

On the file app/build.gradle:

android {
    defaultConfig {
        ndk {
            abiFilters 'arm64-v8a'

will build only for arm64-v8a, or for all currently non-deprecated ARM targets:

abiFilters 'arm64-v8a', 'armeabi-v7a'

ABI list currently at: https://developer.android.com/ndk/guides/abis.html

Tested on Ubuntu 17.10 host, Android Studio 3, Android SDK 26, NDK 15.2, and an Android 6.0.1 device.

Sample project on GitHub.

Haupt answered 29/11, 2017 at 17:21 Comment(0)
P
0

Simply move abiFilters into the android.ndk section:

model {
    android.ndk {
        moduleName = "remote_client"
        CFlags += ['-std=c99', '-fstrict-aliasing']
        ldLibs += ["log", "remoted_client"]
        abiFilters = ['armeabi']
    }
}
Padishah answered 22/10, 2015 at 11:25 Comment(4)
It gives me error "Error:Cannot cast object 'armeabi' with class 'java.lang.String' to class 'java.util.Set'". it should be: abiFilters += ["armeabi"] Set the abiFilters like this fix the error build, but not fixing my issue. I still got the same error incompatible lib.Ladylike
Sorry for the mistake. Why do you need "remote_client" both as the native lib you build, and a library it looks for? Try ldLibs = ["log"]Padishah
I have a cpp for remoted_client, so I have to include it.Ladylike
Sorry, I am confused now. You build libremote_client.so for ARM which depends on libremoted_client.a and the linker cannot find libremote_client.so for MIPS? Maybe something is wrong in your app/build.gradle script?Padishah
L
0

Finally I made it. Here's an example to disable specific task. Add this line on your build.gradle

tasks.getByPath(":app:linkMipsDebugRemoteDesktopSharedLibrary").enabled = false
Ladylike answered 27/10, 2015 at 22:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.