Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
vittoema96 opened this issue May 5, 2023 · 1 comment

Comments

@vittoema96
Copy link

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?

@IShiraiKurokoI
Copy link

I also encountered this problem, and I know why. I used IDA to reversely view the symbol tables of all compiled functions, and found that open3d::io does not exist. Then I found this sentence in the readme: "in this fork IO module is removed since some external libraries are hard to compile (turbojpeg).". The IO code is also commented out in the patch file, so of course IO cannot be used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants