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?