【问题标题】:Undefined reference when calling a OpenCL function in Android在 Android 中调用 OpenCL 函数时未定义的引用
【发布时间】:2018-02-17 10:41:01
【问题描述】:

我正在尝试使用 OpenCL 在 Android Studio 中设置一个简单的项目。所以我创建了一个支持 NDK 的新项目和一个空活动。我已将 libOpenCL.so 从我的手机复制到文件夹 app\src\main\jniLibs\arm8 并从 Khronos 网页下载 OpenCL 标头并将它们复制到 app\src\main\jni\CL。此外,我对 build.gradle 文件进行了两次修改,我在 cppFlags 中添加了一个参数以包含 OpenCL 文件夹,并且我已经设置了一个 abi 过滤器来仅为 arm8 构建。我在这里复制我的 build.gradle 文件:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "es.um.mompes.testopencl"
        minSdkVersion 22
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11 -fexceptions -I${projectDir}/src/main/jni"
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
    productFlavors {
        arm8 {
            ndk {
                abiFilter "arm64-v8a"
            }
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
}

我还在生成的 native-lib.cpp 文件中添加了三行代码来测试 OpenCL 是否正常工作。这是我的 native-lib.cpp:

#include <jni.h>
#include <string>
#include <CL/cl.h>

extern "C"
JNIEXPORT jstring JNICALL
Java_es_um_mompes_testopencl_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    cl_int err;
// Find the number of OpenCL platforms
    cl_uint num_platforms;
    err = clGetPlatformIDs(0, NULL, &num_platforms);
    return env->NewStringUTF(hello.c_str());
}

但是,我一定遗漏了一些东西,因为在构建项目时我收到了关于 OpenCL 函数的未定义引用错误。这是完整的错误: 任务 ':app:externalNativeBuildArm8Debug' 执行失败。

构建命令失败。 使用参数执行进程 C:\Users\Juan\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe 时出错 {--build C:\Users\Juan\AndroidStudioProjects\TestOpenCL\app.externalNativeBuild \cmake\arm8Debug\arm64-v8a --target native-lib} [1/1] 链接 CXX 共享库 ........\build\intermediates\cmake\arm8\debug\obj\arm64-v8a\libnative-lib.so 失败:cmd.exe /C "cd . && C:\Users\Juan\AppData\Local\Android\sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64 -none-linux-android --gcc-toolchain=C:/Users/Juan/AppData/Local/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --sysroot= C:/Users/Juan/AppData/Local/Android/sdk/ndk-bundle/sysroot -fPIC -isystem C:/Users/Juan/AppData/Local/Android/sdk/ndk-bundle/sysroot/usr/include/aarch64 -linux-android -D__ANDROID_API__=22 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -std=c ++11 -fexceptions -IC:\Users\Juan\AndroidStudioProjects\TestOpenCL\app/src/main/jni -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a --sysroot C :/Users/Juan/AppData/Local/Android/sdk/ndk-bundle/platforms/android-22/arch-arm64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--致命警告 -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-argume nts -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ........\build\intermediates\cmake\arm8\debug\obj \arm64-v8a\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o -llog -lm "C:/Users/Juan/AppData/Local/Android/sdk /ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/libgnustl_static.a" && cd ." CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o:在函数Java_es_um_mompes_testopencl_MainActivity_stringFromJNI': C:\Users\Juan\AndroidStudioProjects\TestOpenCL\app\src\main\cpp/native-lib.cpp:14: undefined reference toclGetPlatformIDs' clang++.exe:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

你知道我错过了什么吗?在过去的两天里,我搜索了几个小时来了解如何在 Android Studio 中设置 OpenCL,但我发现的所有内容似乎都已过时,似乎对我的问题不起作用。

【问题讨论】:

  • 你是从哪里复制 libOpenCL.so 的?
  • 嗨 @Zindarod 我从 /system/vendor/lib64/libOpenCL.so 复制了它。
  • 发布您的安卓设备规格。我假设您没有在模拟器中运行 OpenCL 代码。
  • 这是一款小米红米 Note 3(高通版),搭载 Adreno 510 GPU。

标签: android android-studio android-ndk linker opencl


【解决方案1】:

jni 文件夹下查找Android.mk。然后添加:

LOCAL_PATH := $(call my-dir) // should already be there
.
.
LOCAL_LDLIBS := $(LOCAL_PATH)/libOpenCL.so

此示例从 jni 根目录获取 libOpenCL.so,但您可以根据需要进行更改。

参考:Getting Started with OpenCL on Android

【讨论】:

  • 我已经在 jni 下添加了 Android.mk 和 Application.mk 文件,如 Arrayfire 链接中所述,但我仍然遇到相同的错误。我不知道这些文件是否真的被使用了。我是否必须更改标志才能强制使用这些参数?
  • 尝试将 -OpenCL 添加到编译器 CFLAGS(如 -std=gnu11 -lOpenCL)
  • 如果我在 build.gradle 文件的参数“cppFlags”中添加标志,它甚至不会同步 gradle 文件,因为它找不到库。虽然如果我在 Android.mk 文件中添加标志,它不会抱怨,但我仍然收到“未定义的引用”错误。
【解决方案2】:

我建议您将自动构建的 Android Studio NDK 替换为您自己的,这样您就可以完全控制。 然后您可以使用@RonTLV 答案将库添加到 Android.mk 并进行正确的构建。

默认情况下,Android Studio 会忽略 Android.mk,并使用 jni 文件夹中的所有 .c/.cpp 文件生成自己的文件。

sourceSets {
    debug.jniLibs.srcDir 'src/main/obj/local' //debug builds have symbols
    release.jniLibs.srcDir 'src/main/libs' //release builds have cleaned libraries
    main.jni.srcDirs = [] //disable automatic ndk-build call with auto-generated Android.mk
}

// call regular ndk-build script manually
task ndkBuild(type: Exec) {
    if (System.properties['os.name'].toLowerCase(Locale.ROOT).contains('windows')) {
        commandLine 'ndk-build.cmd', '-j8', '-C', file('src/main').absolutePath
    } else {
        commandLine 'ndk-build', '-j8', '-C', file('src/main').absolutePath
    }
}

//Make the NDK task depend on Java build Task
tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn ndkBuild
}

【讨论】:

    猜你喜欢
    • 2013-10-04
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    • 2019-02-20
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多