在Android

时间:2017-09-08 13:25:22

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

我正在尝试使用OpenCL在Android Studio中设置一个简单的项目。所以我创建了一个NDK支持和空活动的新项目。我已将libOpenCL.so从我的手机复制到文件夹app \ src \ main \ jniLibs \ arm8,我已从Khronos网页下载了OpenCL标题并将其复制到app \ src \ main \ jni \ CL。此外,我对build.gradle文件进行了两次修改,我已经在cppFlags中添加了一个参数以包含OpenCL文件夹,并且我已经设置了一个仅为arm8构建的abi过滤器。我在这里复制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函数的未定义引用错误。这是完整的错误: 任务执行失败&#39;:app:externalNativeBuildArm8Debug&#39;。

  

构建命令失败。   执行进程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&#34; 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, - fatal-warnings -Wl, - no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shal,-son,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&#34; C:/ Users / Juan / AppData / Local / Android / sdk / ndk-bundle / sources / cxx-stl / gnu -libstdc ++ / 4.9 /库/ arm64-V8A / libgnustl_static.a&#34; &安培;&安培; cd。&#34;   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 to clGetPlatformIDs&#39;     clang ++。exe:错误:链接器命令失败,退出代码为1(使用-v查看调用)

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

2 个答案:

答案 0 :(得分:1)

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

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

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

参考:Getting Started with OpenCL on Android

答案 1 :(得分:0)

我建议您更换自己的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
}