Taejin
Taejin

Reputation: 17

How this CMakeList.txt dereference unknown variables?

I'm studying how the cmakelists.txt find dependencies to project.

Below is CMakelists.txt(ORB_SLAM3) and two variables are seen only once in this file, not the declaration but dereferencing, EIGEN3_INCLUDE_DIR, Pangolin_INCLUDE_DIRS.

I can't understand how the CMake dereference those variables.

# part of CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(ORB_SLAM3)

IF(NOT CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE Debug)
ENDIF()

MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  -Wall   -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall   -O3")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=native")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=native")
set(CMAKE_BUILD_TYPE Debug)

# Check C++14 or C++0x support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
   add_definitions(-DCOMPILEDWITHC11)
   message(STATUS "Using flag -std=c++14.")
elseif(COMPILER_SUPPORTS_CXX0X)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
   add_definitions(-DCOMPILEDWITHC0X)
   message(STATUS "Using flag -std=c++0x.")
else()
   message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
endif()

LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)

find_package(OpenCV 4)
   if(NOT OpenCV_FOUND)
      message(FATAL_ERROR "OpenCV > 3 not found.")
   endif()

MESSAGE("OPENCV VERSION:")
MESSAGE(${OpenCV_VERSION})

find_package(Eigen3 3.1.0 REQUIRED)
find_package(Pangolin REQUIRED)
find_package(realsense2)

include_directories(
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/include/CameraModels
${PROJECT_SOURCE_DIR}/Thirdparty/Sophus
${EIGEN3_INCLUDE_DIR}
${Pangolin_INCLUDE_DIRS}
)

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)

add_library(${PROJECT_NAME} SHARED
src/System.cc
src/Tracking.cc
src/LocalMapping.cc
src/LoopClosing.cc
src/ORBextractor.cc
src/ORBmatcher.cc
src/FrameDrawer.cc
src/Converter.cc
src/MapPoint.cc
src/KeyFrame.cc
src/Atlas.cc
src/Map.cc
src/MapDrawer.cc
src/Optimizer.cc
src/Frame.cc
src/KeyFrameDatabase.cc
src/Sim3Solver.cc
src/Viewer.cc
src/ImuTypes.cc
src/G2oTypes.cc
src/CameraModels/Pinhole.cpp
src/CameraModels/KannalaBrandt8.cpp
src/OptimizableTypes.cpp
src/MLPnPsolver.cpp
src/GeometricTools.cc
src/TwoViewReconstruction.cc
src/Config.cc
src/Settings.cc
include/System.h
include/Tracking.h
include/LocalMapping.h
include/LoopClosing.h
include/ORBextractor.h
include/ORBmatcher.h
include/FrameDrawer.h
include/Converter.h
include/MapPoint.h
include/KeyFrame.h
include/Atlas.h
include/Map.h
include/MapDrawer.h
include/Optimizer.h
include/Frame.h
include/KeyFrameDatabase.h
include/Sim3Solver.h
include/Viewer.h
include/ImuTypes.h
include/G2oTypes.h
include/CameraModels/GeometricCamera.h
include/CameraModels/Pinhole.h
include/CameraModels/KannalaBrandt8.h
include/OptimizableTypes.h
include/MLPnPsolver.h
include/GeometricTools.h
include/TwoViewReconstruction.h
include/SerializationUtils.h
include/Config.h
include/Settings.h)

add_subdirectory(Thirdparty/g2o)

target_link_libraries(${PROJECT_NAME}
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so
${PROJECT_SOURCE_DIR}/Thirdparty/g2o/lib/libg2o.so
-lboost_serialization
-lcrypto
)

At first, I assumed those were environment variables. But when I searched them on terminal, those were not found. (env | grep DIR)

Also, I searched if those variables are Cache Variables.

(base) ict@:~/src/ORB_SLAM3$ grep -r "EIGEN3_INCLUDE_DIR" .
./CMakeLists.txt:${EIGEN3_INCLUDE_DIR}
./Thirdparty/Sophus/CMakeLists.txt:  target_include_directories (sophus SYSTEM INTERFACE ${EIGEN3_INCLUDE_DIR})
./Thirdparty/Sophus/test/ceres/CMakeLists.txt:list(APPEND SEARCH_HEADERS ${EIGEN3_INCLUDE_DIR})
./Thirdparty/Sophus/appveyor.yml:  - cmake -G "Visual Studio 14 2015 Win64" -D EIGEN3_INCLUDE_DIR=C:\projects\eigen-3.3.4 ..
./Thirdparty/g2o/CMakeLists.txt:SET(EIGEN3_INCLUDE_DIR ${G2O_EIGEN3_INCLUDE})
./Thirdparty/g2o/CMakeLists.txt:  SET(G2O_EIGEN3_INCLUDE ${EIGEN3_INCLUDE_DIR} CACHE PATH "Directory of Eigen3")
(base) ict@:~/src/ORB_SLAM3$ grep -r "Pangolin_INCLUDE_DIRS" .
./Examples_old/ROS/ORB_SLAM3/CMakeLists.txt:${Pangolin_INCLUDE_DIRS}
./CMakeLists.txt:${Pangolin_INCLUDE_DIRS}

Upvotes: 0

Views: 218

Answers (1)

KamilCuk
KamilCuk

Reputation: 141493

How this CMakeList.txt dereference unknown variables?

Unset variables expand to empty. There's also a cmake --warn-uninitialized.

how the cmakelists.txt find dependencies to project

find_package operation is described in documentation https://cmake.org/cmake/help/latest/command/find_package.html . In short it finds a file named like SomethingConfig.cmake and then executes the file like with include() in CMake. If that file happens to set(EIGEN3_INCLUDE_DIR ..) than this variable will be set.

how it found Eigen3

There are many directories and file names that find_package searches for explained in docs https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure . On my system EIGEN3_INCLUDE_DIR is set in:

$ pacman -Ql eigen | grep cmake
...
eigen /usr/share/eigen3/cmake/Eigen3Config.cmake
...
$ grep INCLUDE_DIR /usr/share/eigen3/cmake/Eigen3Config.cmake
set (EIGEN3_INCLUDE_DIR  "${PACKAGE_PREFIX_DIR}/include/eigen3")
set (EIGEN3_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/eigen3")

Different packages expose or not differently names of variables, some INCLUDE_DIR some INCLUDE_DIRS some upper case, some not. You have to read documentation specific to the library you are find_package-ing, or the source code of it, to know what is set.

Upvotes: 2

Related Questions