Issue
현재 스터디원들과 함께 Ceres
를 활용해 LDSO 최적화를 진행하고 있습니다. 그 일환으로 Gauss-Newton Method를 Ceres의 Residual Block으로 Refactoring 중 아래와 같은 에러가 발생했는데요. 빌드도 다 끝냈지만 링크 에러가 발생하고 말았는데요. 몇 가지 이해할 수 없는 부분이 있었습니다.
- Environment
OS: macOS Ventura 13.3.1
Model: MacBook Pro 14 (2021, M1)
Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Target: arm64-apple-darwin22.4.0
- Error Log
Undefined symbols for architecture arm64:
"ceres::Problem::Problem()", referenced from:
ldso::CoarseInitializer::calcResAndGS(int, Eigen::Matrix<float, 8, 8, 0, 8, 8>&, Eigen::Matrix<float, 8, 1, 0, 8, 1>&, Eigen::Matrix<float, 8, 8, 0, 8, 8>&, Eigen::Matrix<float, 8, 1, 0, 8, 1>&, Sophus::SE3Group<double, 0> const&, ldso::AffLight, bool) in libldso.a(CoarseInitializer.cc.o)
"ceres::Problem::~Problem()", referenced from:
ldso::CoarseInitializer::calcResAndGS(int, Eigen::Matrix<float, 8, 8, 0, 8, 8>&, Eigen::Matrix<float, 8, 1, 0, 8, 1>&, Eigen::Matrix<float, 8, 8, 0, 8, 8>&, Eigen::Matrix<float, 8, 1, 0, 8, 1>&, Sophus::SE3Group<double, 0> const&, ldso::AffLight, bool) in libldso.a(CoarseInitializer.cc.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [/Users/youngjin/Desktop/LDSO/bin/run_dso_kitti] Error 1
make[2]: *** [examples/CMakeFiles/run_dso_kitti.dir/all] Error 2
make[1]: *** [examples/CMakeFiles/run_dso_kitti.dir/rule] Error 2
make: *** [run_dso_kitti] Error 2
Analysis
우선 CMakeLists.txt
를 가장 먼저 점검했습니다. 많고 많은 녀석들 중 Root directory의 파일을 살펴보면 아래와 같이 include를 해주었네요. 왜 안 되는 걸까요?
find_package(Eigen3 REQUIRED NO_MODULE)
find_package(OpenCV REQUIRED)
find_package(Glog REQUIRED)
find_package(Pangolin REQUIRED)
find_package(Gflags REQUIRED)
find_package(Boost REQUIRED)
find_package(Ceres REQUIRED)
...
include_directories(
${EIGEN3_INCLUDE_DIR}
${OpenCV_INCLUDE_DIR}
${Glog_INCLUDE_DIRS}
${Pangolin_INCLUDE_DIRS}
${GFLAGS_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${Ceres_INCLUDE_DIRS}
...
}
...
set( THIRD_PARTY_LIBS
${OpenCV_LIBS}
${GLOG_LIBRARY}
${Pangolin_LIBRARIES}
${PROJECT_SOURCE_DIR}/thirdparty/g2o/lib/libg2o${CMAKE_SHARED_LIBRARY_SUFFIX}
${PROJECT_SOURCE_DIR}/thirdparty/DBoW3/build/src/libDBoW3${CMAKE_SHARED_LIBRARY_SUFFIX}
${LIBZIP_LIBRARY}
${Ceres_LIBRARIES}
)
혹시 몰라서 include_directories
와 THIRD_PARTY_LIBS
양쪽에 하나씩 추가하다가, 결국 양쪽 모두 추가했네요. 그래도 에러는 해결되지 않았습니다. 그렇다고 못 찾고 있는 것도 아닙니다. 아래와 같이 Log를 보면 잘 찾았다고 알려주거든요.
-- Found Ceres version: 2.1.0 installed in: /opt/homebrew with components: [EigenSparse, SparseLinearAlgebraLibrary, LAPACK, SuiteSparse, CXSparse, AccelerateSparse, SchurSpecializations, Multithreading]
Solution
어디까지나 임시 방책으로 아래와 같이 빌드하고 싶은 파일인 run_dso_kitti
가 위치한 examples
폴더의 CMakeLists.txt
를 수정해 주었습니다.
# Kitti dataset
add_executable( run_dso_kitti run_dso_kitti.cc )
target_link_libraries( run_dso_kitti
ldso ${THIRD_PARTY_LIBS} )
target_link_libraries( run_dso_kitti Ceres::ceres) # 강제로 Ceres 링크
강제로 링크를 걸어주니 오류 없이 빌드를 성공하더군요. 여기서 드는 의문은 '왜 THIRD_PARTY_LIBS
에 Ceres
를 추가해 주어도 링크를 못 하는가?'입니다. 아마 M1 architecture로 넘어오면서 발생한 수많은 오류 중 하나인 것 같은데요. 아니면 Mac의 고질적인 문제일 수도 있습니다. 아니면 그냥 제 실력 이슈이거나..
Conclusion
아무튼 M1 MacBook에서 LDSO와 Ceres를 빌드하는 단계까지는 무사히 성공했습니다. 역시 C++은 세팅이 가장 어려운 것 같네요. 이제 다시 원래 하던 작업으로 돌아가 Ceres를 활용한 LDSO 최적화 포스팅으로 찾아뵙도록 하겠습니다. 아래는 해당 작업이 진행되는 브랜치이니 관심 있으신 분은 방문해주세요.