Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error when building project with NDK support after updating to Android Studio 4.0 from 3.6

After updating Android Studio to 4.0 project build finishes with error

More than one file was found with OS independent path 'lib/armeabi-v7a/libdlib.so'. If you are using jniLibs and CMake IMPORTED targets, see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake

The link leads to the page with New features in Android Studio Preview which is 4.1

EDIT Actually you can find information that is linked in Google cache: Automatic packaging of prebuilt dependencies used by CMake What is stated there is:

Prior versions of the Android Gradle Plugin required that you explicitly package any prebuilt libraries used by your CMake external native build by using jniLibs. With Android Gradle Plugin 4.0, the above configuration is no longer necessary and will result in a build failure:

But it is not the case for me

Here are build.gradle

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"


defaultConfig {
    minSdkVersion 21
    targetSdkVersion 29
    versionCode 1
    versionName "1.0"

    externalNativeBuild {
        cmake {
            cFlags "-O3"
            cppFlags "-std=c++11 -frtti -fexceptions -mfpu=neon"
            arguments "-DANDROID_PLATFORM=android-16",
                    "-DANDROID_TOOLCHAIN=clang",
                    "-DANDROID_STL=c++_shared",
                    "-DANDROID_ARM_NEON=TRUE",
                    "-DANDROID_CPP_FEATURES=rtti exceptions"
        }
    }
}

buildTypes {
    debug {}
    stage {
        debuggable true
        minifyEnabled false
    }

    release {
        minifyEnabled false
    }
}

kotlinOptions {
    jvmTarget = "1.8"
}

externalNativeBuild {
    cmake {
        path "src/main/cpp/CMakeLists.txt"
        version "3.10.2"
    }
}

packagingOptions {
    pickFirst "**/libc++_shared.so"
    pickFirst "**/libdlib.so"
}

}

dependencies {
   implementation fileTree(dir: 'libs', include: ['*.jar'])

   implementation 'androidx.annotation:annotation:1.1.0'
   implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

and CMakeLists.txt

set(LIB_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs)

#
cmake_minimum_required(VERSION 3.4.1)

add_library(dlib SHARED IMPORTED)

# sets the location of the prebuilt dlib .so
set_target_properties( dlib
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libdlib.so )

# ------------------------------------------------------------------

add_library( # Sets the name of the library.
        face-lib

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        face-lib.cpp)

target_include_directories(
        face-lib PRIVATE
        ${CMAKE_SOURCE_DIR}/include
)

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)


target_link_libraries( # Specifies the target library.
        face-lib

        dlib

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})
like image 975
Roman Nazarevych Avatar asked May 29 '20 14:05

Roman Nazarevych


People also ask

How do I know if android NDK is installed?

You'll need to point to your NDK in your eclipse by adding the path of ndk-build to Window > preferences > android > NDK. Right click on your project folder. Choose android tools -> add native support (the bottom one) and click finish. Now it will ask for a name for your .

How do I downgrade NDK?

In order to downgrade your ndk, you will have to pull it from the internet with wget and move it into your Android SDK dir: wget https://dl.google.com/android/repository/android-ndk-r13b-darwin-x86_64.zip. unzip android-ndk-r13b-darwin-x86_64.

Is NDK necessary for Android Studio?

The Android Native Development Kit (NDK): a set of tools that allows you to use C and C++ code with Android. CMake: an external build tool that works alongside Gradle to build your native library. You do not need this component if you only plan to use ndk-build.

What version of NDK do I need for Android Studio?

When you install the NDK, Android Studio selects the latest available NDK. For most projects, installing this default version of the NDK is sufficient. If your project needs one or more specific versions of the NDK, though, you can download and configure specific versions.

How do I install CMake NDK on Android Studio?

Android Studio installs all versions of the NDK in the android-sdk /ndk/ directory. To install CMake and the default NDK in Android Studio, do the following: With a project open, click Tools > SDK Manager. Click the SDK Tools tab. Select the NDK (Side by side) and CMake checkboxes.

Why won't Android Studio start after upgrading to Android 11?

In the SDK Platforms tab, check the box labeled Show Package Details and select revision 9 or higher of the Android 11 emulator. If Studio doesn't start after an upgrade, the problem may be due to an invalid Android Studio configuration imported from a previous version of Android Studio or an incompatible plugin.

How do I configure the NDK of the Android Gradle plugin?

The steps vary according to the version of AGP used in the project. Find the Android Gradle Plugin version in either of the following locations: Select the version below: You have the following options to configure the NDK: (Recommended) Use the ndkVersion property to set the NDK version. Do not set any property.


4 Answers

Ok, So I have found the solution, I have added this to the module with my native libraries:

 packagingOptions {
        pickFirst "**/libdlib.so"
    }

I don't like it as it, as it fixes the consequences, not the root cause. If somebody has a better solution please post it here.

Another solution that worked is pointed in @GavinAndre answer The main point is that if you are using Cmake, then don't store your .so in jniLibs folder.

Move them to another folder for example cmakeLibs.
For example:

set_target_properties( dlib
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../cmakeLibs/${ANDROID_ABI}/libdlib.so )
like image 152
Roman Nazarevych Avatar answered Oct 28 '22 15:10

Roman Nazarevych


I faced the same problem.

That is how my gradle file written:

    sourceSets {
        main {
            jniLibs.srcDirs 'src/main/cpp/libs'
        }
    }

Actually there is two .so files in the folder and since the link see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake seems to show the infomation That Andrioid Stuido will automatic packaging libs for you.

So I just DELETE this content inner my gradle file and everything works fine.

like image 36
Joshua Avatar answered Oct 28 '22 14:10

Joshua


According to https://developer.android.com/studio/projects/gradle-external-native-builds#jniLibs

If you are using Android Gradle Plugin 4.0, move any libraries that are used by IMPORTED CMake targets out of your jniLibs directory to avoid this error.

So you only need to move the ${ANDROID_ABI}/libdlib.so folder to another place such as creating a new directory name cmakeLibs

eg:

set_target_properties( dlib
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../cmakeLibs/${ANDROID_ABI}/libdlib.so )
like image 7
Gavin Andre Avatar answered Oct 28 '22 14:10

Gavin Andre


On my side seemed that jniLibs as name of the folder was triggering erroneously the error. changing the name of the folder to something else (i used 'libraries') both in the path of filesystem and the cmakelists.txt solved the problem.

cmakelists.txt fragment

# import library and set path
add_library(ixxs-plugin SHARED IMPORTED) # or STATIC instead of SHARED
set_target_properties(ixxs-plugin PROPERTIES
        IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/../libraries/${CMAKE_ANDROID_ARCH_ABI}/libixxs-plugin.so"
        )

nothing had to be done on the gradle file, it will find automatically the libs and put them into the aar file. you can unzip the aar file to check that. (libs are in {nameofaar}/jni/{arch_type}/{nameoflib}.so)

like image 2
AndrewBloom Avatar answered Oct 28 '22 15:10

AndrewBloom