Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake - Force find_package to update cache variables

Tags:

cmake

In my CMake project, I provide a default path to Boost editable by the user.

set(PATH_BOOST_DEFAULT "/softs/boost/${BOOST_VER}/${ARCH}/gcc/${GCCVER}")
set(PATH_BOOST "${PATH_BOOST_DEFAULT}" CACHE PATH "Default path to Boost")

After that, I try to find the libs with:

set(BOOST_ROOT "${PATH_BOOST}")
set(Boost_USE_MULTITHREAD ON)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost 1.53.0 REQUIRED COMPONENTS thread system)

This works fine and a lot of cache variables like Boost_INCLUDE_DIR, Boost_LIBRARY_DIRS or Boost_THREAD_LIBRARY_DEBUG are generated.

My problem comes when I try to modify the cache variable PATH_BOOST: the cache variables generated by FindBoost.cmake aren't updated. The script FindBoost.cmake seems to be called again (it print messages about found components). I think the variables like Boost_INCLUDE_DIR are not updated because they are in cache.

Is there a way to say to CMake "if the path is modified by the user, re-find the package by forcing the cache variables"?

Also, is there a nicer way to detect a cache variable was just modified than the following ugly idea?

set(MY_VAR ${MY_VAR_DEFAULT} CACHE TYPE "")
if(NOT DEFINED MY_VAR_copy)
  set(MY_VAR_copy ${MY_VAR} CACHE INTERNAL "")
  mark_as_advanced(FORCE MY_VAR_copy)
endif()
if(NOT "${MY_VAR}" STREQUAL "${MY_VAR_copy}")
  # my_var is modified : do something
  set(MY_VAR_copy ${MY_VAR} CACHE INTERNAL "")
endif()
like image 361
Caduchon Avatar asked Feb 06 '15 12:02

Caduchon


People also ask

How does Find_package work in CMake?

CMake searches for a file called Find<package>. cmake in the CMAKE_MODULE_PATH followed by the CMake installation. If the file is found, it is read and processed by CMake. It is responsible for finding the package, checking the version, and producing any needed messages.

Where does Find_package look CMake?

CMake ships with its own set of built-in find_package scripts, and their location is in the default CMAKE_MODULE_PATH.

What is CMake cache variable?

The CMake cache may be thought of as a configuration file. The first time CMake is run on a project, it produces a CMakeCache. txt file in the top directory of the build tree. CMake uses this file to store a set of global cache variables, whose values persist across multiple runs within a project build tree.

Where is config CMake?

For a candidate package configuration file <config-file>. cmake the corresponding version file is located next to it and named either <config-file>-version. cmake or <config-file>Version. cmake .


1 Answers

I think I've got the same problem as you. My setup tries to find a specific version of a package:

set (MYPACK_REQUIRED_VERSION 1.2.3)
find_package (mypack ${MYPACK_REQUIRED_VERSION} EXACT)

The package config script sets the cached variable MYPACK_LIBRARIES which then is used at a later stage. However when I change the MYPACK_REQUIRED_VERSION variable cmake still use the old MYPACK_LIBRARIES instead of trying to look for the new version.

I think I've solved the problem now by unsetting this cache variable:

set (MYPACK_REQUIRED_VERSION 1.2.3)
unset (MYPACK_LIBRARIES CACHE)
find_package (mypack ${MYPACK_REQUIRED_VERSION} EXACT)

This seems to trigger the find_package procedure again in my case. There are some finer details of the find_package procedure that I don't completely understand so this might not work in your case, but it might be worth a try.

like image 51
Paul Avatar answered Sep 17 '22 21:09

Paul