mapillary / OpenSfM

Open source Structure-from-Motion pipeline
https://www.opensfm.org/
BSD 2-Clause "Simplified" License
3.35k stars 853 forks source link

Build issue: search paths for Eigen are hard coded in cmake file #802

Closed rudyryk closed 2 years ago

rudyryk commented 2 years ago

https://github.com/mapillary/OpenSfM/blob/343d1c349a008507f3b7e4be84e31e74c52f92f5/opensfm/src/cmake/FindEigen.cmake#L88

This prevents from having Eigen to be installed to custom location even if paths are explicitly provided via CFLAGS or CXXFLAGS etc.

In my case, I was using Nix packager and shell:

$ nix-shell -p python38Full python38Packages.opencv4 \
    python38Packages.setuptools python38Packages.sphinx \
    python38Packages.wheel cmake clang opencv suitesparse \
    blas lapack eigen ceres-solver

[nix-shell:~/OpenSfM]$ python setup.py build

Generated output:

Configuring for python 3.8...
-- Could NOT find OpenMP_C (missing: OpenMP_C_FLAGS OpenMP_C_LIB_NAMES)
-- Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES)
-- Could NOT find OpenMP (missing: OpenMP_C_FOUND OpenMP_CXX_FOUND)
-- Found AMD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libamd.dylib
-- Found AMD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found CAMD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libcamd.dylib
-- Found CAMD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found COLAMD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libcolamd.dylib
-- Found COLAMD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found CCOLAMD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libccolamd.dylib
-- Found CCOLAMD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found CHOLMOD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libcholmod.dylib
-- Found CHOLMOD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found CXSPARSE library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libcxsparse.dylib
-- Found SuiteSparseQR library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libspqr.dylib
-- Found SuiteSparseQR header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Did not find Intel TBB library, assuming SuiteSparseQR was not compiled with TBB.
-- Found SuiteSparse_config library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libsuitesparseconfig.dylib
-- Found SuiteSparse_config header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Did not find METIS library (optional SuiteSparse dependency)
CMake Error at cmake/FindEigen.cmake:77 (MESSAGE):
  Failed to find Eigen - Could not find eigen3 include directory, set
  EIGEN_INCLUDE_DIR to path to eigen3 include directory, e.g.
  /usr/local/include/eigen3.
Call Stack (most recent call first):
  cmake/FindEigen.cmake:103 (EIGEN_REPORT_NOT_FOUND)
  CMakeLists.txt:54 (find_package)
rudyryk commented 2 years ago

And after dirty hackish symlink, it's working:

[nix-shell:~/OpenSfM]$ sudo ln -s /nix/store/1fdvw6dlcmpx6fhhslblfgs9xy81wch0-eigen-3.3.9/include/eigen3 \
/usr/local/include/eigen3

[nix-shell:~/OpenSfM]$ python setup.py build

Output generated:

Configuring for python 3.8...
-- Could NOT find OpenMP_C (missing: OpenMP_C_FLAGS OpenMP_C_LIB_NAMES)
-- Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES)
-- Could NOT find OpenMP (missing: OpenMP_C_FOUND OpenMP_CXX_FOUND)
-- Found AMD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libamd.dylib
-- Found AMD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found CAMD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libcamd.dylib
-- Found CAMD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found COLAMD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libcolamd.dylib
-- Found COLAMD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found CCOLAMD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libccolamd.dylib
-- Found CCOLAMD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found CHOLMOD library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libcholmod.dylib
-- Found CHOLMOD header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Found CXSPARSE library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libcxsparse.dylib
-- Found SuiteSparseQR library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libspqr.dylib
-- Found SuiteSparseQR header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Did not find Intel TBB library, assuming SuiteSparseQR was not compiled with TBB.
-- Found SuiteSparse_config library: /nix/store/hsw3xs8lxiklblc6lvdqrp3rpz3mh440-suitesparse-5.9.0/lib/libsuitesparseconfig.dylib
-- Found SuiteSparse_config header in: /nix/store/43hac8g89rxcy8a8wjcq36ilg8bschl7-suitesparse-5.9.0-dev/include
-- Did not find METIS library (optional SuiteSparse dependency)
CMake Warning (dev) at /nix/store/ci8d9x1r1z5mcka1v68a2l17hvk5l2m4-cmake-3.21.2/share/cmake-3.21/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (ceres) does
  not match the name of the calling package (Ceres).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  cmake/FindCeres.cmake:49 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:55 (find_package)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- No preference for use of exported gflags CMake configuration set, and no hints for include/library directories provided. Defaulting to preferring an installed/exported gflags CMake configuration if available.
-- Found installed version of gflags: /nix/store/5wqndhmwhq79x47027bkyrl8k5j78xgf-gflags-2.2.2/lib/cmake/gflags
-- Detected gflags version: 2.2.2
-- Found OpenCV: / (found version "4.5.2")
-- Found OpenCV: / (found version "4.5.2") found components: core imgproc calib3d imgcodecs
-- pybind11 v2.2.4
-- Configuring done
-- Generating done
-- Build files have been written to: ...
SomeoneSerge commented 2 years ago

Eigen is actually distributed both with a cmake exported target and with a pkg-config file, so they can be discovered through normal means (e.g. pkg-config --libs --cflags eigen3). I think the custom FindEigen.cmake is ought to be removed

I'm not entirely sure how to use use the exported cmake target though, I've tried just deleting FindEigen.cmake, but cmake seemed to ignore CMAKE_PREFIX_PATH (locating eigen) and searched in opensfm/src/cmake instead...

@rudyryk If you're building opensfm with Nix, you can just use:

{
  cmakeFlags = [
   # ...
    "-DEIGEN_INCLUDE_DIR=${eigen}/include/eigen3"
  ];
}

and opensfm's cmake script will catch it up from there

SomeoneSerge commented 2 years ago

Oh well, it's because we're looking for Eigen in find_package(Eigen REQUIRED) and upstream distributes Eigen3

This works just fine:

  postPatch = ''
    rm opensfm/src/cmake/FindEigen.cmake
    rm opensfm/src/cmake/FindCeres.cmake
    sed -i 's/Eigen/Eigen3/g' opensfm/src/CMakeLists.txt
    sed -i '/find_package(Eigen/a set(EIGEN_INCLUDE_DIRS ''${EIGEN3_INCLUDE_DIR})' opensfm/src/CMakeLists.txt
    sed -i '/find_package(Eigen/a set(EIGEN_INCLUDE_DIR ''${EIGEN3_INCLUDE_DIR})' opensfm/src/CMakeLists.txt
  '';

https://eigen.tuxfamily.org/dox/TopicCMakeGuide.html