c++windowscmakeglewpcl

A Module mode failure prevents Config mode from finding the package - how to fix it?


I am building a C++ project on Windows 10 using CMake. The project links to the PCL library and to my own package pcview, both of which in turn depend on GLEW. Incidentally, PCL shouldn't actually use GLEW because the visualization module was not built. I have PCL, pcview, GLEW and all other packages set up on my computer in such a way that find_package can easily find them in the Config mode.

project ---> PCL
   |          |
   |          |
   v          v
 pcview ---> GLEW

However, when processing the project's src/CMakeLists.txt:

1. find_package( PCL REQUIRED )
2. find_package( pcview REQUIRED )
3. ...

it outputs an error:

CMake Error at D:/CMake/share/cmake-3.30/Modules/FindPackageHandleStandardArgs.cmake:233 (message):
  Could NOT find GLEW (missing: GLEW_INCLUDE_DIR GLEW_LIBRARY)
Call Stack (most recent call first):
  D:/CMake/share/cmake-3.30/Modules/FindPackageHandleStandardArgs.cmake:603 (_FPHSA_FAILURE_MESSAGE)
  D:/packages/PCL/cmake/Modules/FindGLEW.cmake:38 (find_package_handle_standard_args)
  D:/CMake/share/cmake-3.30/Modules/CMakeFindDependencyMacro.cmake:75 (find_package)
  D:/packages/pcview/cmake/pcview-config.cmake:28 (find_dependency)
  src/CMakeLists.txt:2 (find_package)

I have found out that PCL itself has a FindGLEW.cmake module, so when my pcview-config.cmake calls find_dependency( GLEW ) (a variant of find_package), the search proceeds in the Module mode first. Had that mode just silently failed, the fallback Config mode would have found GLEW without any issues. Instead, the FindGLEW.cmake provided by PCL fails to find it and calls find_package_handle_standard_args, which terminates completely with the error shown above.

Am I doing anything in the wrong way? What is the most healthy way to get CMake to find the package?

Of course I could just delete PCL's FindGLEW.cmake, or force the Config mode manually, or do some other ugly workaround. But I assume PCL is set-up in a healthy way, which means the problem lies on my end. I would like to know how to connect everything together in the most clean and professional way.


I'm pretty sure these are irrelevant, but somebody is going to ask anyway, so here are my CMake files.

Top CMakeLists.txt:

cmake_minimum_required( VERSION 3.12...3.30 FATAL_ERROR )

project( pcl-pcview VERSION 1.0 )

set( CMAKE_CXX_STANDARD 20 )
set( CMAKE_CXX_STANDARD_REQUIRED True )

add_subdirectory( src )

src/CMakeLists.txt:

find_package( PCL REQUIRED )
find_package( pcview REQUIRED )

set( LIBS ${PCL_LIBRARIES} pcview::pcview )


add_executable( pcl-pcview main.cxx )

target_link_libraries( pcl-pcview PRIVATE ${LIBS} )

Solution

  • Here again as a proper answer: You can add message(CMAKE_MODULE_PATH="${CMAKE_MODULE_PATH}") before and after the find_package(PCL REQUIRED) call to find out if PCL changes this variable; as a consequence PCL's FindGLEW.cmake is used. One option is to reset CMAKE_MODULE_PATH to the original value after PCL was found:

    set(original_cmake_module_path "${CMAKE_MODULE_PATH}")
    find_package( PCL REQUIRED )
    set(CMAKE_MODULE_PATH "${original_cmake_module_path}")
    find_package( pcview REQUIRED )
    

    Or switch the find_package calls for PCL and pcview.

    PCL's FindGLEW.cmake has actually been removed 2 months ago, so future PCL releases will not have that any more. That version was seemingly equivalent to the one from CMake 3.13. The FindGLEW.cmake from newer CMake versions looks quite different. So seems like PCL's FindGLEW.cmake was outdated.