cmake - 如何让cmake自动重新检查依赖项的版本?

标签 cmake

我有以下CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.11)

project(test)

find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED gtk+-2.0>=2.24)
include_directories(SYSTEM ${GTK_INCLUDE_DIRS})

set(test_SOURCES test.c)
add_executable(test ${test_SOURCES})
target_link_libraries(test ${GTK_LIBRARIES})

和源文件test.c:

#include <gtk/gtk.h>

int main(int argc, char** argv)
{
    gtk_init(&argc,&argv);
    return 0;
}

然后我就这么做了

mkdir build && cd build
cmake ..
make

成功配置并构建了测试。现在我做到了

sed -i 's@2\<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="85abb7b1c5b7abb7b0" rel="noreferrer noopener nofollow">[email protected]</a>@' ../CMakeLists.txt

从而将所需的 GTK 版本更新为我没有的版本(GTK 2.25 不存在)。现在再次运行 make 我得到:

-- Configuring done
-- Generating done
-- Build files have been written to: /home/ruslan/cmake-test/build
[100%] Built target test

cmake 甚至没有检查现在需要的版本是否已安装。

所以我的问题是:如何让它自动重新检查所需的版本?如果自动不可能,那么我如何在不需要提供整个 cmake 命令行(在实际项目中可能会变得很长)的情况下执行此操作?

最佳答案

将我的评论转化为答案

这似乎是一个已知问题:0015795: pkg_check_modules produces incorrect results depending on contents of CMakeCache.txt 。但不幸的是,到目前为止,这一点还没有得到太多支持。

那么让我们简单看一下相关的FindPkgConfig.cmake代码片段:

macro(pkg_check_modules _prefix _module0)
  # check cached value
  if (NOT DEFINED __pkg_config_checked_${_prefix} OR 
      __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR 
      NOT ${_prefix}_FOUND)
     ...
    _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
  endif()
endmacro()

如您所见,一旦使用名为 ${_prefix}_FOUND 的缓存变量将包标记为已找到,它就不再执行任何操作。

可能的解决方法

如果您想强制检查每个配置,您可以添加例如在检查模块之前unset(GTK_FOUND CACHE)。这是性能和更改所需包的便利性之间的权衡,而无需从头开始进行完整的配置/构建。

...
unset(GTK_FOUND CACHE)
pkg_check_modules(GTK REQUIRED gtk+-2.0>=2.24)
...

建议的修复

以下代码作为解决此问题的草案。如果有人可以评论一下,我欢迎任何评论:

编辑:通过将参数合并到 pkgconfig 版本检查中来简化我的方法。无论如何,我们应该重新检查 pkgconfig 脚本是否发生更改。

macro(pkg_check_modules _prefix _module0)
  # check cached value
  if (NOT DEFINED __pkg_config_checked_${_prefix} OR 
      NOT __pkg_config_checked_${_prefix} STREQUAL "${PKG_CONFIG_VERSION},${ARGV}" OR 
      NOT ${_prefix}_FOUND) 
    ...
    # save pkgconfig version and the arguments used
    _pkgconfig_set(__pkg_config_checked_${_prefix} "${PKG_CONFIG_VERSION},${ARGV}")
  endif()
endmacro()

如果这得到了一些积极的反馈,我会将其作为提案添加到上面提到的 CMake 错误跟踪器票证中。

编辑:为了更具体地说明我提议的更改,这里是 FindPkgConfig.cmake version as of 21th March, 2016 的统一 diff :

--- FindPkgConfig.cmake 
+++ FindPkgConfig.cmake      
@@ -523,11 +523,13 @@
 #]========================================]
 macro(pkg_check_modules _prefix _module0)
   # check cached value
-  if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
+  if (NOT DEFINED __pkg_config_checked_${_prefix} OR
+      NOT __pkg_config_checked_${_prefix} STREQUAL "${PKG_CONFIG_VERSION},${ARGV}" OR
+      NOT ${_prefix}_FOUND)
     _pkgconfig_parse_options   (_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path "${_module0}" ${ARGN})
     _pkg_check_modules_internal("${_pkg_is_required}" "${_pkg_is_silent}" ${_no_cmake_path} ${_no_cmake_environment_path} "${_prefix}" ${_pkg_modules})

-    _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
+    _pkgconfig_set(__pkg_config_checked_${_prefix} "${PKG_CONFIG_VERSION},${ARGV}")
   endif()
 endmacro()

@@ -550,7 +552,9 @@
 #]========================================]
 macro(pkg_search_module _prefix _module0)
   # check cached value
-  if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
+  if (NOT DEFINED __pkg_config_checked_${_prefix} OR
+      NOT __pkg_config_checked_${_prefix} STREQUAL "${PKG_CONFIG_VERSION},${ARGV}" OR
+      NOT ${_prefix}_FOUND)
     set(_pkg_modules_found 0)
     _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path "${_module0}" ${ARGN})

@@ -575,7 +579,7 @@
       endif()
     endif()

-    _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
+    _pkgconfig_set(__pkg_config_checked_${_prefix} "${PKG_CONFIG_VERSION},${ARGV}")
   endif()
 endmacro()

关于cmake - 如何让cmake自动重新检查依赖项的版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37026867/

相关文章:

linux - 配置VTK时如何安装x11_xt_lib?

android - Android NDK 项目中的 undefined reference 错误

c++ - CMake Ninja Git 自签名证书颁发机构密码提示

c++ - 现代 CMake 应该如何添加 SSE 标志?

c++ - 如何为 CMAKE 外部项目指定编译器?

c++ - CMAKE 没有找到我的第一个柯南包?

c++ - .CPP中的类定义时,CMake for Google测试

opencv - Cmake gui 重置参数。如何在cmake gui中设置参数?

python - 无法使用用于 python 的 opencv_contrib 模块构建 opencv-3.0

c - 我应该在 CLion 中包含哪个库才能启用 readline