I write a simple c++ code to call some functions defined in ExternalProject_Add() target. When I compile this c++ code, I see some undefined reference errors as follows.
CMakeFiles/okvis_test.dir/main.cpp.o: In function `okvis::cameras::CameraBase::CameraBase(int, int, unsigned long)':
main.cpp:(.text._ZN5okvis7cameras10CameraBaseC2Eiim[_ZN5okvis7cameras10CameraBaseC5Eiim]+0x17): undefined reference to `vtable for okvis::cameras::CameraBase'
CMakeFiles/okvis_test.dir/main.cpp.o: In function `okvis::cameras::CameraBase::~CameraBase()':
main.cpp:(.text._ZN5okvis7cameras10CameraBaseD2Ev[_ZN5okvis7cameras10CameraBaseD5Ev]+0xd): undefined reference to `vtable for okvis::cameras::CameraBase'
CMakeFiles/okvis_test.dir/main.cpp.o:(.rodata._ZTVN5okvis7cameras13PinholeCameraINS0_21EquidistantDistortionEEE[_ZTVN5okvis7cameras13PinholeCameraINS0_21EquidistantDistortionEEE]+0xa0): undefined reference to `okvis::cameras::CameraBase::createRandomImagePoint() const'
CMakeFiles/okvis_test.dir/main.cpp.o:(.rodata._ZTVN5okvis7cameras13PinholeCameraINS0_21EquidistantDistortionEEE[_ZTVN5okvis7cameras13PinholeCameraINS0_21EquidistantDistortionEEE]+0xa8): undefined reference to `okvis::cameras::CameraBase::createRandomVisiblePoint(double, double) const'
CMakeFiles/okvis_test.dir/main.cpp.o:(.rodata._ZTVN5okvis7cameras13PinholeCameraINS0_21EquidistantDistortionEEE[_ZTVN5okvis7cameras13PinholeCameraINS0_21EquidistantDistortionEEE]+0xb0): undefined reference to `okvis::cameras::CameraBase::createRandomVisibleHomogeneousPoint(double, double) const'
CMakeFiles/okvis_test.dir/main.cpp.o:(.rodata._ZTIN5okvis7cameras13PinholeCameraINS0_21EquidistantDistortionEEE[_ZTIN5okvis7cameras13PinholeCameraINS0_21EquidistantDistortionEEE]+0x10): undefined reference to `typeinfo for okvis::cameras::CameraBase'
CMakeFiles/okvis_test.dir/main.cpp.o: In function `okvis::ceres::ReprojectionError<okvis::cameras::PinholeCamera<okvis::cameras::EquidistantDistortion> >::EvaluateWithMinimalJacobians(double const* const*, double*, double**, double**) const':
main.cpp:(.text._ZNK5okvis5ceres17ReprojectionErrorINS_7cameras13PinholeCameraINS2_21EquidistantDistortionEEEE28EvaluateWithMinimalJacobiansEPKPKdPdPSB_SC_[_ZNK5okvis5ceres17ReprojectionErrorINS_7cameras13PinholeCameraINS2_21EquidistantDistortionEEEE28EvaluateWithMinimalJacobiansEPKPKdPdPSB_SC_]+0x937): undefined reference to `okvis::ceres::PoseLocalParameterization::liftJacobian(double const*, double*)'
main.cpp:(.text._ZNK5okvis5ceres17ReprojectionErrorINS_7cameras13PinholeCameraINS2_21EquidistantDistortionEEEE28EvaluateWithMinimalJacobiansEPKPKdPdPSB_SC_[_ZNK5okvis5ceres17ReprojectionErrorINS_7cameras13PinholeCameraINS2_21EquidistantDistortionEEEE28EvaluateWithMinimalJacobiansEPKPKdPdPSB_SC_]+0xe2b): undefined reference to `okvis::ceres::PoseLocalParameterization::liftJacobian(double const*, double*)'
collect2: error: ld returned 1 exit status
CMakeFiles/okvis_test.dir/build.make:148: recipe for target 'okvis_test' failed
make[2]: *** [okvis_test] Error 1
CMakeFiles/Makefile2:96: recipe for target 'CMakeFiles/okvis_test.dir/all' failed
make[1]: *** [CMakeFiles/okvis_test.dir/all] Error 2
Makefile:102: recipe for target 'all' failed
make: *** [all] Error 2
My CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.12)
project(okvis_test)
include(ExternalProject)
####################
# Compile as C++11 and C++14 for CMake versions earlier than 3.1
####################
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -std=c++14")
####################
# Find libraries
####################
find_package(Eigen3 REQUIRED)
find_package(OpenCV REQUIRED)
####################
# Add okvis as an external project
####################
ExternalProject_Add(okvis
GIT_REPOSITORY https://github.com/ethz-asl/okvis.git
GIT_TAG master
UPDATE_COMMAND ""
INSTALL_DIR ${CMAKE_BINARY_DIR}
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
-DBUILD_TESTS:BOOL=OFF
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/okvis
BUILD_IN_SOURCE 0
BUILD_COMMAND make
INSTALL_COMMAND make install
)
# Make okvis a dependency for other target
ExternalProject_Get_Property(okvis INSTALL_DIR)
set(OKVIS_INCLUDE_DIR ${INSTALL_DIR}/include)
set(OKVIS_LIBS_DIR ${INSTALL_DIR}/lib)
add_library(OKVIS_LIBS STATIC IMPORTED)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_ceres.a)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_common.a)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_cv.a)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_frontend.a)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_kinematics.a)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_matcher.a)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_multisensor_processing.a)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_time.a)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_timing.a)
set_target_properties(OKVIS_LIBS PROPERTIES IMPORTED_LOCATION ${OKVIS_LIBS_DIR}/libokvis_util.a)
# Our main target
add_executable(${PROJECT_NAME} main.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC ${EIGEN3_INCLUDE_DIR} ${OKVIS_INCLUDE_DIR} ${OpenCV_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} OKVIS_LIBS ${OpenCV_LIBS})
add_dependencies(${PROJECT_NAME} okvis)
My simple c++ code:
#include <Eigen/Dense>
#include <okvis/cameras/EquidistantDistortion.hpp>
#include <okvis/cameras/PinholeCamera.hpp>
#include <okvis/ceres/ReprojectionError.hpp>
int main(int argc, char **argv) {
using DistortedPinholeCameraGeometry =
okvis::cameras::PinholeCamera<okvis::cameras::EquidistantDistortion>;
std::shared_ptr<const DistortedPinholeCameraGeometry> camera_geometry =
std::static_pointer_cast<const DistortedPinholeCameraGeometry>(
DistortedPinholeCameraGeometry::createTestObject());
Eigen::Vector2d kp;
Eigen::Matrix2d information = Eigen::Matrix2d::Identity();
okvis::ceres::ReprojectionError<DistortedPinholeCameraGeometry>
reprojection_error(camera_geometry, 1, kp, information);
return 0;
}
I don't think the undefined reference to vtable is related to undefined virtual function. The virtual destructor CameraBase class is defined, see https://github.com/ethz-asl/okvis/blob/master/okvis_cv/include/okvis/cameras/CameraBase.hpp#L93 Basically, all virtual functions in CameraBase class are defined or pure virtual.
I have been stuck in this error for hours. Any help or suggestions would be appreciated.