我有以下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\.24@2.25@' ../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
命令行的情况下执行此操作(在实际项目中可以使用很长时间)?
答案 0 :(得分:2)
将我的评论转化为答案
这似乎是一个众所周知的问题: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()