【问题标题】:Error when building project with NDK support after updating to Android Studio 4.0 from 3.6从 3.6 更新到 Android Studio 4.0 后构建具有 NDK 支持的项目时出错
【发布时间】:2020-09-17 03:33:31
【问题描述】:

将 Android Studio 更新到 4.0 后,项目构建完成并出现错误

找到多个文件,其独立于操作系统的路径为“lib/armeabi-v7a/libdlib.so”。如果您使用 jniLibs 和 CMake IMPORTED 目标,请参阅https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake

链接指向带有Android Studio Preview 中的新功能的页面,即 4.1

编辑 实际上,您可以在 Google 缓存中找到链接的信息: Automatic packaging of prebuilt dependencies used by CMake 里面写的是:

Android Gradle 插件的早期版本要求您使用 jniLibs 显式打包 CMake 外部原生构建使用的任何预构建库。使用 Android Gradle Plugin 4.0,上述配置不再需要,会导致构建失败:

但对我来说不是这样

这里是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"
}

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})

【问题讨论】:

  • 在这里打开了一个错误:issuetracker.google.com/issues/157901344
  • 抱歉文档问题。出于某种原因,它已从 4.0 发行说明中删除。得到那个固定的atm。
  • 在添加 packagingOptions 块之前,我可以重现该问题。这使问题消失了。这是您为解决问题而添加的内容吗?
  • 不幸的是,谷歌缓存链接现在是 404。这个链接今天有效:developer.android.com/studio/releases/…

标签: android android-studio android-ndk android-studio-4.0


【解决方案1】:

好的,所以我找到了解决方案,我已将其添加到带有我的本机库的模块中:

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

我不喜欢它,因为它解决了后果,而不是根本原因。 如果有人有更好的解决方案,请在此处发布。

另一个有效的解决方案指向@GavinAndre answer 重点是,如果您使用的是 Cmake,请不要将您的 .so 存储在 jniLibs 文件夹中。

将它们移动到另一个文件夹,例如cmakeLibs
例如:

set_target_properties( dlib
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../cmakeLibs/${ANDROID_ABI}/libdlib.so )

【讨论】:

  • 我认为这是由于“add_library(dlib SHARED IMPORTED)”。但不知道如何正确解决这个问题。我有同样的问题。
  • 这是因为您有IMPORTED 目标并且jniLibs 中有库。这两者都会导致它被打包,并且打包任务不够聪明,无法对它们进行重复数据删除。
  • pickFirst 显然对我有用!我还不明白是什么原因造成的
  • 实际上在我的情况下我删除了jniLibs 文件夹(因为我是从我的电脑上的本地目录导入的)。此外,我还有另一个库(arcore)也提供了此类错误,因此在这里我需要添加pickFirst,正如您在答案的第一部分中提到的那样。所以,谢谢:)
  • 我不得不放弃用十多个模块升级我的项目,其中每个模块都导入了一些.so库...
【解决方案2】:

我遇到了同样的问题。

我的 gradle 文件就是这样写的:

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

实际上文件夹中有两个 .so 文件,因为链接 see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake 似乎显示了信息Andrioid Stuido 将自动为您打包库

所以我只是在我的 gradle 文件中删除此内容,一切正常。

【讨论】:

  • 这应该被标记为正确答案,因为 Gradle 插件是引入此更改的第一个答案是 hack 方式
【解决方案3】:

根据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.

所以你只需要将${ANDROID_ABI}/libdlib.so文件夹移动到另一个地方比如新建一个目录名cmakeLibs

例如:

set_target_properties( dlib
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../cmakeLibs/${ANDROID_ABI}/libdlib.so )

【讨论】:

    【解决方案4】:

    在我看来,作为文件夹名称的 jniLibs 错误地触发了错误。在文件系统的路径和 cmakelists.txt 中将文件夹的名称更改为其他名称(我使用了“库”)解决了这个问题。

    cmakelists.txt 片段

    # 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"
            )
    

    不需要对 gradle 文件做任何事情,它会自动找到库并将它们放入 aar 文件中。您可以解压缩 aar 文件以进行检查。 (库位于 {nameofaar}/jni/{arch_type}/{nameoflib}.so)

    【讨论】:

    • 所以对于每个声明“libs”文件夹的“set_target_properties”,我们应该将“libs”更改为“libraries”?
    • 我有jniLibs,我改用libraries,你可以改用iwannabeoriginalandnotuselibraries之类的其他东西。在 cmakelists 文件和文件系统上。祝你好运。
    【解决方案5】:

    好的,所以我找到了解决方案,我已将其添加到带有我的本机库的模块中:

    andrid{
    packagingOptions {
            pickFirst "**/lib/**"
        }
    }
    

    【讨论】:

      【解决方案6】:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-28
        • 1970-01-01
        • 1970-01-01
        • 2018-02-17
        • 1970-01-01
        • 2017-07-23
        • 2019-01-02
        • 1970-01-01
        相关资源
        最近更新 更多