Hello all,
I'm trying to use the Ceres solver for a project in Android. I've compiled the whole project successfully before for Linux x86-64, now trying to port it to Android, but I'm running into some "undefined reference" linker errors and I was hoping somebody could help me figure out what's wrong. I'm using ceres-solver-1.9.0.
I first compiled libceres.a via running ndk-build from ceres' jni folder (
http://ceres-solver.org/building.html#android). No problems. I should add that I'm using APP_STL := gnustl_static (details below).
Then, I'm running ndk-build from my project's main folder. Compilation works fine, linking fails with the following error messages:
...
[armeabi-v7a] Compile++ arm : _myproject <= slam.cpp
[armeabi-v7a] SharedLibrary : lib_myproject.so
jni/../../ceres-solver-1.9.0/obj/local/armeabi-v7a/libceres.a(schur_eliminator.o):schur_eliminator.cc:vtable for ceres::internal::SchurEliminator<2, 4, 8>: error: undefined reference to 'ceres::internal::SchurEliminator<2, 4, 8>::~SchurEliminator()'
jni/../../ceres-solver-1.9.0/obj/local/armeabi-v7a/libceres.a(schur_eliminator.o):schur_eliminator.cc:vtable for ceres::internal::SchurEliminator<2, 4, 8>: error: undefined reference to 'ceres::internal::SchurEliminator<2, 4, 8>::~SchurEliminator()'
jni/../../ceres-solver-1.9.0/obj/local/armeabi-v7a/libceres.a(schur_eliminator.o):schur_eliminator.cc:vtable for ceres::internal::SchurEliminator<2, 4, 8>: error: undefined reference to 'ceres::internal::SchurEliminator<2, 4, 8>::Init(int, ceres::internal::CompressedRowBlockStructure const*)'
jni/../../ceres-solver-1.9.0/obj/local/armeabi-v7a/libceres.a(schur_eliminator.o):schur_eliminator.cc:vtable for ceres::internal::SchurEliminator<2, 4, 8>: error: undefined reference to 'ceres::internal::SchurEliminator<2, 4, 8>::Eliminate(ceres::internal::BlockSparseMatrix const*, double const*, double const*, ceres::internal::BlockRandomAccessMatrix*, double*)'
jni/../../ceres-solver-1.9.0/obj/local/armeabi-v7a/libceres.a(schur_eliminator.o):schur_eliminator.cc:vtable for ceres::internal::SchurEliminator<2, 4, 8>: error: undefined reference to 'ceres::internal::SchurEliminator<2, 4, 8>::BackSubstitute(ceres::internal::BlockSparseMatrix const*, double const*, double const*, double const*, double*)'
/<...>/ceres-solver-1.9.0/jni/../internal/ceres/partitioned_matrix_view.cc:118: error: undefined reference to 'ceres::internal::PartitionedMatrixView<2, 4, 8>::PartitionedMatrixView(ceres::internal::BlockSparseMatrix const&, int)'
collect2: error: ld returned 1 exit status
make: *** [obj/local/armeabi-v7a/lib_dtslam.so] Error 1
Here are the relevant parts of my project's Android.mk and Application.mk:
--- Application.mk: ---
APP_ABI := armeabi-v7a
APP_PLATFORM := android-16
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_MODULES = lib_myproject
--- Android.mk: ---
LOCAL_PATH := $(call my-dir)
# Ceres as prebuilt library:
include $(CLEAR_VARS)
LOCAL_MODULE := ceres
LOCAL_SRC_FILES := ../../ceres-solver-1.9.0/obj/local/armeabi-v7a/libceres.a
include $(PREBUILT_STATIC_LIBRARY)
(...including OpenCV here...)
include $(CLEAR_VARS)
LOCAL_MODULE := lib_myproject
# enable C++11 support:
LOCAL_CFLAGS += -std=gnu++11
LOCAL_STATIC_LIBRARIES := \
opencv_calib3d opencv_features2d opencv_flann opencv_imgproc opencv_core tbb \
ceres \
LOCAL_SRC_FILES := \
(list of local source files here)
LOCAL_C_INCLUDES := \
(list of include paths here)
LOCAL_ARM_MODE := arm
include $(BUILD_SHARED_LIBRARY)
Not sure if this is relevant, but as stated above, I modified ceres' Application.mk and Android.mk to use APP_STL := gnustl_static, because the project *also* uses OpenCV, which appears to not like c++_static (see
http://stackoverflow.com/questions/13037659/opencv-build-issue-cant-find-ext-atomicity-h).
The changes for that were: APP_STL := gnustl_static in Application.mk, and adding -std=gnu++11 -DCERES_TR1_MEMORY_HEADER -DCERES_TR1_SHARED_PTR to LOCAL_CFLAGS in Android.mk.
Any ideas what causes the linker errors?
Thanks a lot!
Steffen