1

I'm having trouble using an Android library that i compiled.

The library is open3d-core-android (https://github.com/InstytutXR/open3d-core-android).

Whenever i try to call CreateImageFromFile (or any other method from this library that receives an std:string as an argument), during compilation i get hit with the following error:

C/C++: ld: error: undefined symbol: open3d::io::CreateImageFromFile(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&)

I understand that it may be a compilation/ndk problem, but not much more than that.

Here I'll explain how i compiled the project and setup the Android Studio environment:

I am trying to build on Windows 10
I have version 3.14 of CMake installed

I have cloned the project with git clone https://github.com/InstytutXR/open3d-core-android.
I have edited the CMakeLists.txt file to download version 0.9.0 instead of 0.10.0 (keeping 0.10 did not work)
Inside the downloaded project folder, I have run the commands:

mkdir build & cd build
cmake -G Ninja -DANDROID_NDK=C:\Users\vittorio.veloccia\AppData\Local\Android\Sdk\ndk\20.1.5948944 -DCMAKE_INSTALL_PREFIX=../install .. && cmake --build .

This part correclty builds (aka no errors thrown)

Now i created an Android Studio Native C++ project.

My app's gradle.build file looks like this:

plugins {
    id 'com.android.application'
}

android {
    namespace 'com.example.testo3d'
    compileSdk 33
    ndkVersion "20.1.5948944"

    defaultConfig {
        applicationId "com.example.testo3d"
        minSdk 24
        targetSdk 33
        versionCode 1
        versionName "1.0"

        externalNativeBuild {
            cmake {
                version '3.22.1'
                arguments "-DOPEN3D_PATH=C:\\Development\\open3d-core-android\\install"
            }
        }
        ndk {
            abiFilters = []
            abiFilters.addAll(ABI_FILTERS.split(';').collect{it as String})
        }
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    externalNativeBuild {
        cmake {
            path file('src/main/cpp/CMakeLists.txt')
            version '3.22.1'
        }
    }
    buildFeatures {
        viewBinding true
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

In gradle.properties I have set the following property ABI_FILTERS=armeabi-v7a;arm64-v8a (these 2 are the only ones i have compiled)

My CMakeLists.txt file (inside Android Studio's cpp folder) looks like this:


cmake_minimum_required(VERSION 3.22.1)

project("testo3d")

set(SOURCE_FILES native-lib.cpp)

add_library( ${PROJECT_NAME} SHARED ${SOURCE_FILES})

find_library(log-lib log)

if(NOT OPEN3D_PATH)
    message(FATAL_ERROR "Open3D path not specified")
endif()

set(open3d-abi-path ${OPEN3D_PATH}/open3d-${ANDROID_ABI})

find_package(Open3D 0.9.0 # exact match required (major, minor, patch)
        REQUIRED
        PATHS ${open3d-abi-path}
        # don't look anywhere except in the path(s) we specify
        NO_DEFAULT_PATH
        # ignore the NDK CMAKE_FIND_ROOT_PATH, otherwise all search paths get prefixed with it
        NO_CMAKE_FIND_ROOT_PATH)

find_library(open3d-lib
        Open3D
        PATHS ${Open3D_LIBRARY_DIRS}
        NO_DEFAULT_PATH
        NO_CMAKE_FIND_ROOT_PATH)

file(COPY ${open3d-lib} DESTINATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI})

# Open3D gives us non-existing directories
# CMake doesn't allow adding those as interface include directories
foreach(dir ${Open3D_INCLUDE_DIRS})
    if(NOT EXISTS ${dir})
        list(REMOVE_ITEM Open3D_INCLUDE_DIRS ${dir})
    endif()
endforeach()


add_library(Open3D SHARED IMPORTED)
set_target_properties(Open3D PROPERTIES
        IMPORTED_LOCATION ${open3d-lib})
set_property(TARGET Open3D APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Open3D_INCLUDE_DIRS})

target_link_libraries(# Specifies the target library.
        ${PROJECT_NAME} PRIVATE
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib}

        Open3D)

Lastly, my native-lib.cpp file (inside Android Studio's cpp folder) looks like this:

#include <jni.h>
#include "string"
#include "Open3D/Geometry/RGBDImage.h"
#include "Open3D/IO/ClassIO/ImageIO.h"

using namespace open3d::geometry;

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_o3dnative_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string path = "/emulated/storagew/0/Android/data/com.example.testo3d/files/image.jpg";
    Image colImg = *open3d::io::CreateImageFromFile(path);
    return env->NewStringUTF(path.c_str());
}

Can anyone help me out on understanding what that error might mean and how to resolve it?

vittoema96
  • 121
  • 1
  • 1
  • 6
  • Make sure that the library is located in the correct path and the library name. – Patrick Apr 14 '23 at 10:59
  • With 'in the correct path' what do you mean? The 'install' directory (C:/Development/open3d-core-android/install) should be moved elsewhere? Inside the project? – vittoema96 Apr 14 '23 at 12:46
  • https://stackoverflow.com/q/12573816/11107541 – starball Apr 14 '23 at 19:17
  • I mean that the Open3D library should be installed in a location where your project can access it – Patrick Apr 16 '23 at 14:01
  • yes it can access it because if I instanciate a class of Open3D that does not require arguments (such as std:string) it actually creates it without error – vittoema96 Apr 17 '23 at 13:58
  • Also, this line in CMakeLists.txt copies the files from the install folder to the projects folder: file(COPY ${open3d-lib} DESTINATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI} – vittoema96 Apr 18 '23 at 07:09

0 Answers0