如何修复Android项目构建失败.so不是ABI

y0u0uwnf  于 2023-08-01  发布在  Android
关注(0)|答案(1)|浏览(661)

bounty还有6天到期。回答此问题可获得+50声望奖励。Burton2000正在寻找一个答案从一个有信誉的来源

我有一个使用Android Gradle Plugin 7.4.2的项目,我使用升级助手更新到8.0.2,但现在我的项目无法构建,并出现以下错误:
原因:从路径/Users/user 01/. gradle/caches/transforms-3/4445827 a66 e5 ef 9 b85054 fadb 96 c8209/transformed/jetified-armnn. delegate-23.05/jni/arm 64-v8.2-a/libarmnn_delegate_jni. so提取的jni不是ABI
有没有人知道是否有某种方法可以在Gradle中指定不使用此库的arm 64-v8.2-a ABI版本?我尝试添加以下内容:

ndk {
        // Specifies the ABI configurations of your native
        // libraries Gradle should build and package with your app.
        abiFilters 'arm64-v8a'
    }

字符串
而且

splits {
        abi {
            enable true
            reset()
            include "arm64-v8a"
        }
    }


但这些都没用如果我恢复升级,项目构建正常,但我想使用最新版本的Gradle插件。
编辑:有关额外信息,此依赖项以.AAR文件的形式出现,其中包含已编译的本机.so文件的arm 64-v8 a和arm 64-v8.2-a版本。看起来在较旧的Android Gradle插件版本中,v8.2只是被忽略,但现在它会自动拾取并导致此问题?

knsnq2tg

knsnq2tg1#

触发错误的代码位于MergeNativeLibsTask.kt中:

/**
     * [file] is one of these two kinds:
     *    (1) /path/to/{x86/lib.so}
     *    (2) /path/to/x86/{lib.so}
     * Where the value in {braces} is the [relativePath] from the file visitor.
     * The first (1) is from tasks that process all ABIs in a single task.
     * The second (2) is from tasks the where each task processes one ABI.
     *
     * This function distinguishes the two cases and returns a relative path that always
     * starts with an ABI. So, for example, both of the cases above would return:
     *
     *    x86/lib.so
     *
     */
    private fun toAbiRootedPath(file : File, relativePath: RelativePath) : String {
        return if (abiTags.any { it == relativePath.segments[0] }) {
            // Case (1) the relative path starts with an ABI name. Return it directly.
            relativePath.pathString
        } else {
            // Case (2) the relative path does not start with an ABI name. Prepend the
            // ABI name from the end of [file] after [relativePath] has been removed.
            var root = file
            repeat(relativePath.segments.size) { root = root.parentFile }
            val abi = root.name
            if (!abiTags.any { it == abi }) {
                error("$abi extracted from path $file is not an ABI")
            }
            abi + separatorChar + relativePath.pathString
        }
    }

字符串
基于错误以“jni”开头的事实,在您的情况下,它似乎选择了路径的“jni”部分作为提取的ABI。
这段代码看起来确实需要一个支持的ABI名称,要么是相对路径的第一段,要么是相对路径之外的目录名称。
在您的例子中,我推测您有一个文件值/Users/user01/.gradle/caches/transforms-3/4445827a66e5ef9b85054fadb96c8209/transformed/jetified-armnn.delegate-23.05/jni/arm64-v8.2-a/libarmnn_delegate_jni.so和一个relativePath arm64-v8.2-a/libarmnn_delegate_jni.so

  • 第一个(“case 1”)检查将尝试将“arm 64-v8.2-a”与已知ABI匹配,这显然失败了。
  • 在else路径中,我们通过向上跳两次(relativePath中的元素数)来找到根,最终得到/Users/user01/.gradle/caches/transforms-3/4445827a66e5ef9b85054fadb96c8209/transformed/jetified-armnn.delegate-23.05/jni。该目录的名称是“jni”,它也不匹配任何已知的ABI。因此,错误。

我没有看到任何方法使这个函数通过,除了确保它根本没有被调用这个文件。如果这是可能的,我不知道如何(但我肯定不是该领域的Maven)。另一个选择是从依赖项中删除“坏”ABI(如果您可以控制它)--接受的ABI列表应该是here
这以前是reported as a bug on the Google Issue Tracker,但似乎没有太多(公开)的进展。如果你没有什么新的东西要添加,请不要在这些评论中发帖;用星星图标或“+1”按钮标记问题。

相关问题