首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果安装了多个版本,cmake find_package(X [ version ])总是选择最高版本的X?

如果安装了多个版本,cmake find_package(X [ version ])总是选择最高版本的X?
EN

Stack Overflow用户
提问于 2022-05-27 18:53:34
回答 1查看 214关注 0票数 1

我在运行cmake 3.23.0。我想要基于版本标准的find_library(VTK)。我的ubuntu20.04系统安装了两个版本的VTK:

代码语言:javascript
运行
复制
/usr/local/lib/cmake/vtk-8.2
/usr/local/lib/cmake/vtk-9.0

我的项目需要VTK版本8.x.x,即需要排除VTK 9.x.x -所以CMakeLists.txt包括:

代码语言:javascript
运行
复制
   find_package(VTK "8...<9" REQUIRED)

但是VTK_VERSION发现的是9.0.1 -考虑到约束,为什么呢?也试过

代码语言:javascript
运行
复制
find_package(VTK "8.0...<9.0" REQUIRED)
find_package(VTK "8.0.0...<9.0.0" REQUIRED)

同样的结果- VTK_VERSION 9.0.1被找到。在没有版本范围的情况下尝试,但是find_package()仍然返回VTK_VERSION 9.0.1:

代码语言:javascript
运行
复制
   find_package(VTK "8" REQUIRED) 
   find_package(VTK “8.2” REQUIRED)
   find_package(VTK “8.2.0” REQUIRED)

唯一真正返回VTK_VERSION 8.2.0的内容是:

代码语言:javascript
运行
复制
   find_package(VTK “8.2.0” REQUIRED EXACT)

这种行为是因为我的系统上安装了两个VTK版本,而find_packages()假设只安装了一个版本吗?

*更新#2: /usr/local/lib/cmake/vtk-中版本配置文件的内容。

/usr/local/lib/cmake/vtk-8.2/VTKConfigVersion.cmake:

代码语言:javascript
运行
复制
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version,
# but only if the requested major version is the same as the current one.
# The variable CVF_VERSION must be set before calling configure_file().


set(PACKAGE_VERSION "8.2.0")

if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()

  if("8.2.0" MATCHES "^([0-9]+)\\.")
    set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
  else()
    set(CVF_VERSION_MAJOR "8.2.0")
  endif()

  if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR)
    set(PACKAGE_VERSION_COMPATIBLE TRUE)
  else()
    set(PACKAGE_VERSION_COMPATIBLE FALSE)
  endif()

  if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
      set(PACKAGE_VERSION_EXACT TRUE)
  endif()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
   return()
endif()

# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
  math(EXPR installedBits "8 * 8")
  set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
  set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

/usr/local/lib/cmake/vtk-9.0/vtk-config-version.cmake:

代码语言:javascript
运行
复制
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
# The variable CVF_VERSION must be set before calling configure_file().

set(PACKAGE_VERSION "9.0.1")

if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
  set(PACKAGE_VERSION_COMPATIBLE TRUE)
  if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
    set(PACKAGE_VERSION_EXACT TRUE)
  endif()
endif()

# if the installed project requested no architecture check, don't perform the check
if("FALSE")
  return()
endif()

# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
   return()
endif()

# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
   math(EXPR installedBits "8 * 8")
   set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
   set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

*更新#1:带有--调试-查找-pkg=VTK的CMake输出:

代码语言:javascript
运行
复制
CMake Debug Log at CMakeLists.txt:212 (find_package):
  find_package considered the following paths for VTK.cmake

    /home/oreilly/projects/mb-system/MB-System/build-utils/FindVTK.cmake
    /usr/local/share/cmake-3.23/Modules/FindVTK.cmake

  The file was not found.

  <PackageName>_ROOT CMake variable [CMAKE_FIND_USE_PACKAGE_ROOT_PATH].

    none

  CMAKE_PREFIX_PATH variable [CMAKE_FIND_USE_CMAKE_PATH].

    none

  CMAKE_FRAMEWORK_PATH and CMAKE_APPBUNDLE_PATH variables
  [CMAKE_FIND_USE_CMAKE_PATH].

    none

  Env variable VTK_DIR [CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].

    none

  CMAKE_PREFIX_PATH env variable [CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].

    none

  CMAKE_FRAMEWORK_PATH and CMAKE_APPBUNDLE_PATH env variables
  [CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].

  none

  Paths specified by the find_package HINTS option.

    none

  Standard system environment variables
  [CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH].

    /home/oreilly/OpenSceneGraph/build
    /home/oreilly/projects/mb-system/MB-System/build
    /home/oreilly/projects/hotspot/onboard/smc-script
    /home/oreilly/projects/hotspot/onboard/script
    /home/oreilly/myUtilities
    /home/oreilly/cxxtest-4.3
    /home/oreilly/Qt/Tools/QtCreator
    /home/oreilly/Qt/5.14.2/gcc_64
    /home/oreilly/Android/Sdk/platform-tools
    /home/oreilly/android-studio/tools
    /home/oreilly/android-studio
    /home/oreilly/idea
    /home/oreilly
    /home/oreilly/.local
    /usr/local
    /usr
    /
    /usr/games
    /usr/local/games
    /snap
    /home/oreilly/anaconda2
CMake User Package Registry [CMAKE_FIND_USE_PACKAGE_REGISTRY].

    none

  CMake variables defined in the Platform file
  [CMAKE_FIND_USE_CMAKE_SYSTEM_PATH].

    /usr/X11R6
    /usr/pkg
    /opt

  

  CMake System Package Registry
  [CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY].

    none

  Paths specified by the find_package PATHS option.

    none

  find_package considered the following locations for the Config module:

    /home/oreilly/OpenSceneGraph/build/VTKConfig.cmake
    /home/oreilly/OpenSceneGraph/build/vtk-config.cmake
    /home/oreilly/projects/mb-system/MB-System/build/VTKConfig.cmake
    /home/oreilly/projects/mb-system/MB-System/build/vtk-config.cmake
    /home/oreilly/projects/hotspot/onboard/smc-script/VTKConfig.cmake
    /home/oreilly/projects/hotspot/onboard/smc-script/vtk-config.cmake
    /home/oreilly/projects/hotspot/onboard/script/VTKConfig.cmake
 /home/oreilly/projects/hotspot/onboard/script/vtk-config.cmake
    /home/oreilly/myUtilities/VTKConfig.cmake
    /home/oreilly/myUtilities/vtk-config.cmake
    /home/oreilly/cxxtest-4.3/VTKConfig.cmake
    /home/oreilly/cxxtest-4.3/vtk-config.cmake
    /home/oreilly/Qt/Tools/QtCreator/VTKConfig.cmake
    /home/oreilly/Qt/Tools/QtCreator/vtk-config.cmake
    /home/oreilly/Qt/5.14.2/gcc_64/VTKConfig.cmake
    /home/oreilly/Qt/5.14.2/gcc_64/vtk-config.cmake
    /home/oreilly/Android/Sdk/platform-tools/VTKConfig.cmake
    /home/oreilly/Android/Sdk/platform-tools/vtk-config.cmake
    /home/oreilly/android-studio/tools/VTKConfig.cmake
    /home/oreilly/android-studio/tools/vtk-config.cmake
    /home/oreilly/android-studio/VTKConfig.cmake
    /home/oreilly/android-studio/vtk-config.cmake
    /home/oreilly/idea/VTKConfig.cmake
    /home/oreilly/idea/vtk-config.cmake
    /home/oreilly/VTKConfig.cmake
    /home/oreilly/vtk-config.cmake
    /home/oreilly/CMake/VTKConfig.cmake
    /home/oreilly/CMake/vtk-config.cmake
    /home/oreilly/vtk/VTKConfig.cmake
    /home/oreilly/vtk/vtk-config.cmake
    /home/oreilly/VTK-8.2.0/VTKConfig.cmake
    /home/oreilly/VTK-8.2.0/vtk-config.cmake
    /home/oreilly/VTKWikiExamples-master/VTKConfig.cmake
    /home/oreilly/VTKWikiExamples-master/vtk-config.cmake
    /home/oreilly/VTK-9.0.1/VTKConfig.cmake
    /home/oreilly/VTK-9.0.1/vtk-config.cmake
    /home/oreilly/VTKExamples/VTKConfig.cmake
    /home/oreilly/VTKExamples/vtk-config.cmake
    /home/oreilly/vtk/CMake/VTKConfig.cmake
    /home/oreilly/vtk/CMake/vtk-config.cmake
    /home/oreilly/VTK-8.2.0/CMake/VTKConfig.cmake
/home/oreilly/VTK-8.2.0/CMake/vtk-config.cmake
    /home/oreilly/VTKWikiExamples-master/CMake/VTKConfig.cmake
    /home/oreilly/VTKWikiExamples-master/CMake/vtk-config.cmake
    /home/oreilly/VTK-9.0.1/CMake/VTKConfig.cmake
    /home/oreilly/VTK-9.0.1/CMake/vtk-config.cmake
    /home/oreilly/VTKExamples/CMake/VTKConfig.cmake
    /home/oreilly/VTKExamples/CMake/vtk-config.cmake
    /home/oreilly/.local/VTKConfig.cmake
    /home/oreilly/.local/vtk-config.cmake
    /usr/local/VTKConfig.cmake
    /usr/local/vtk-config.cmake
    /usr/local/lib/cmake/vtk-9.0/VTKConfig.cmake
    /usr/local/lib/cmake/vtk-9.0/vtk-config.cmake

  The file was found at

    /usr/local/lib/cmake/vtk-9.0/vtk-config.cmake



CMake Debug Log at CMakeLists.txt:212 (find_package):


Found VTK package version 9.0.1, VTK_LIBRARIES: VTK::WrappingTools;VTK::ViewsQt;[et cetera...]
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-27 22:59:48

find_package根据搜索过程选择它找到的第一个包。当在搜索过程中断线时,它会按文件系统顺序排列。这取决于您的文件系统,因此没有指定。

对于版本选择询问包的*-config-version.cmake*ConfigVersion.cmake脚本是否与请求的版本兼容。没有这样的脚本的包被认为是不兼容的。旧包通常不会理解版本范围,并且倾向于将像8.0.0...<9.0.0这样的表达式简单地看作是8.0.0

您从--debug-find-pkg=VTK输出中看到的是,您的文件系统在VTK 8之前订购了VTK 9,这可能是因为它更新了,或者碰巧被分配给了一个较小的inode,或者谁知道呢?它不一定是字母顺序或其他什么的。

然后首先考虑VTK 9并加载vtk-9.0/vtk-config-version.cmake文件。如你所见:

代码语言:javascript
运行
复制
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
  set(PACKAGE_VERSION_COMPATIBLE TRUE)
  if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
    set(PACKAGE_VERSION_EXACT TRUE)
  endif()
endif()

它只检查当前版本(9.0.1)是否小于请求的版本(任何以8开头的版本字符串)。由于9不小于8,所以将PACKAGE_VERSION_COMPATIBLE变量设置为true,并接受包。

当您指定EXACT时,STREQUAL比较将返回false,因此PACKAGE_VERSION_EXACT不会被设置为TRUE,因此将拒绝该包并考虑VTK 8包。

这是VTK 9的不幸行为,它不够复杂,不足以解释版本范围参数,它声称向后兼容所有以前的版本。

要强制在您的情况下使用VTK 8,您应该编写以下内容:

代码语言:javascript
运行
复制
find_package(VTK 8...<9 REQUIRED) 
if (VTK_VERSION VERSION_GREATER_EQUAL 9)
    message(FATAL_ERROR "This application requires VTK 8.x, but VTK ${VTK_VERSION} was found. Please set VTK_DIR to a folder containing the VTKConfig.cmake file from a VTK 8 installation.")
endif ()

然后可以在命令行设置-DVTK_DIR=/usr/local/lib/cmake/vtk-8.2

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72409928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档