我有以下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/