21

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})
Roman Nazarevych
  • 7,513
  • 4
  • 62
  • 67
  • 3
    opened a bug here: https://issuetracker.google.com/issues/157901344 – AndrewBloom Jun 01 '20 at 18:48
  • Sorry about the doc issue. For some reason that got dropped from the 4.0 release notes. Getting that fixed atm. – Dan Albert Jun 10 '20 at 20:51
  • I can reproduce the issue right up until I add the `packagingOptions` block. That makes the problem go away. Is that something that you added to fix the problem? – Dan Albert Jun 10 '20 at 22:04
  • 1
    Unfortunately that google cache link is now 404. This link works today: https://developer.android.com/studio/releases/gradle-plugin#cmake-imported-targets – Edward Falk Sep 16 '21 at 23:16

7 Answers7

16

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 )
Roman Nazarevych
  • 7,513
  • 4
  • 62
  • 67
  • I think it's due the "add_library(dlib SHARED IMPORTED)". But don't know how to properly solve that. I have the same issue. – Peterdk May 30 '20 at 12:34
  • It's because you have the `IMPORTED` target _and_ have the library in`jniLibs`. Those both cause it to get packaged and the packaging task isn't smart enough to dedup them. – Dan Albert Jun 10 '20 at 19:49
  • pickFirst apparently is working for me! I couldn't yet understand what is causing this – Tiago Santos Jul 09 '20 at 10:24
  • actually in my case I deleted `jniLibs` folder (because I imported from local dir on my PC). And in addition I have another lib (arcore) that also provided such error, so here I was needed to add `pickFirst` as you mentioned in first part of your answer. So, thanks:) – Sirop4ik Oct 22 '20 at 11:06
  • I have to give up upgrading my project with more than ten modules, where each module has some .so libs imported... – Summer Sun Mar 11 '21 at 12:45
10

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.

Joshua
  • 356
  • 2
  • 9
8

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 )
Gavin Andre
  • 391
  • 3
  • 4
4

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

andrid{
packagingOptions {
        pickFirst "**/lib/**"
    }
}
MohamedHarmoush
  • 1,033
  • 11
  • 17
2

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)

AndrewBloom
  • 2,171
  • 20
  • 30
  • so for every "set_target_properties" that states the 'libs' folder, we should change 'libs' for 'libraries'? – Tiago Santos Jul 09 '20 at 10:15
  • i had `jniLibs` and I changed with `libraries`, you could change it with something else like `iwannabeoriginalandnotuselibraries`. both on the cmakelists file and the file system. Good Luck. – AndrewBloom Jul 09 '20 at 11:57
0

According to https://developer.android.com/studio/releases/gradle-plugin#cmake-imported-targets, I fix More than one file was found with OS independent path 'lib/armeabi-v7a/libfreetype.so' in my npm package @flyskywhy/react-native-gcanvas when >= com.android.tools.build:gradle:4.0.0 (means react-native >= 0.64) in /androidbuild.gradle

Li Zheng
  • 685
  • 7
  • 11
0

If you have two modules(such as SDKWrapper SDK), SDKWrapper building depends on SDK, you cannot implementation SDK in gradle.

eg.

asks.whenTaskAdded { task ->
if (task.name == 'externalNativeBuildRelease') {
    task.dependsOn ":SDK:externalNativeBuildRelease"
} else if (task.name == 'externalNativeBuildDebug') {
    task.dependsOn ":SDK:externalNativeBuildDebug"
}}

remove implementation

implementation Project(path:'SDK') 
mono
  • 81
  • 1
  • 4