CMake FindwxWidgets仅在第一次调用" configure"时失败。命令

时间:2017-01-10 16:57:45

标签: cmake wxwidgets

我有以下代码尝试使用CMake 3.7.1查找wxWidgets 3.1预构建的库。

set(wxWidgets_ROOT_DIR M:/wxWidgets)
set(wxWidgets_LIB_DIR M:/wxWidgets/lib/gcc510TDM_x64_dll)
set(wxWidgets_CONFIGURATION mswud)
find_package(wxWidgets 3.1 REQUIRED COMPONENTS core base stc)
include(${wxWidgets_USE_FILE})
target_link_libraries(MyTarget ${wxWidgets_LIBRARIES})

生成器是" CodeBlocks - MinGW Makefiles"。它在Windows 7上。因此,FindwxWidgets模块的搜索样式为" win32"。

奇怪的是,这个代码总是在第一次调用" configure"时失败。命令/按钮,当尚未设置CMake缓存时。并且它将在随后的" configure"的调用中成功。错误信息是

CMake Error at M:/cmake-3.7.1-win64-x64/share/cmake-3.7/Modules/FindPackageHandleStandardArgs.cmake:138 (message):
  Could NOT find wxWidgets (missing: wxWidgets_LIBRARIES
  wxWidgets_INCLUDE_DIRS) (Required is at least version "3.1")
Call Stack (most recent call first):
  M:/cmake-3.7.1-win64-x64/share/cmake-3.7/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
  M:/cmake-3.7.1-win64-x64/share/cmake-3.7/Modules/FindwxWidgets.cmake:929 (find_package_handle_standard_args)
  CMakeLists.txt:16 (find_package)

我是CMake的新手。这是正常的吗? FindwxWidgets模块应该以这种方式工作吗?

以下是第一个(失败)"配置"之后的CMake缓存的内容:

//Cleared.
wxWidgets_LIB_DIR:PATH=wxWidgets_LIB_DIR-NOTFOUND
...
...
//wxWidgets_LIB_DIR
WX_LIB_DIR:INTERNAL=wxWidgets_LIB_DIR-NOTFOUND
//wxWidgets_ROOT_DIR
WX_ROOT_DIR:INTERNAL=M:/wxWidgets

以下是后续(成功)"配置"

后的CMake缓存内容
//Path to a file.
_filename:FILEPATH=M:/wxWidgets/include/wx/version.h

//Set wxWidgets configuration (mswud;mswu)
wxWidgets_CONFIGURATION:STRING=mswud

//Cleared.
wxWidgets_LIB_DIR:PATH=wxWidgets_LIB_DIR-NOTFOUND

//Location of wxWidgets resource file compiler binary (wxrc)
wxWidgets_wxrc_EXECUTABLE:FILEPATH=wxWidgets_wxrc_EXECUTABLE-NOTFOUND
...
...
//Details about finding wxWidgets
FIND_PACKAGE_MESSAGE_DETAILS_wxWidgets:INTERNAL=[M:/wxWidgets/lib/gcc510TDM_x64_dll/libwxmsw31ud_core.a;M:/wxWidgets/lib/gcc510TDM_x64_dll/libwxbase31ud.a;M:/wxWidgets/lib/gcc510TDM_x64_dll/libwxmsw31ud_stc.a;M:/wxWidgets/lib/gcc510TDM_x64_dll/libwxpngd.a;M:/wxWidgets/lib/gcc510TDM_x64_dll/libwxtiffd.a;M:/wxWidgets/lib/gcc510TDM_x64_dll/libwxjpegd.a;M:/wxWidgets/lib/gcc510TDM_x64_dll/libwxzlibd.a;M:/wxWidgets/lib/gcc510TDM_x64_dll/libwxregexud.a;M:/wxWidgets/lib/gcc510TDM_x64_dll/libwxexpatd.a;winmm;comctl32;rpcrt4;wsock32][M:/wxWidgets/lib/gcc510TDM_x64_dll/mswud;M:/wxWidgets/include][v3.1.0(3.1)]
//wxWidgets_LIB_DIR
WX_LIB_DIR:INTERNAL=M:/wxWidgets/lib/gcc510TDM_x64_dll
//wxWidgets_ROOT_DIR
WX_ROOT_DIR:INTERNAL=M:/wxWidgets

我省略了针对各个wxWidgets组件的键,例如" WX_zlib:FILEPATH"或" WX_zlib-ADVANCED:INTERNAL"等。

2 个答案:

答案 0 :(得分:0)

脚本FindwxWidgets.cmake具有非直观的逻辑,因此使用 wxWidgets_LIB_DIR 路径进行提示非常棘手:

  1. 提示 wxWidgets_ROOT_DIR 应采用某种规范形式,其中驱动程序字母为大写:

    set(wxWidgets_ROOT_DIR "M:/wxWidgets")
    
  2. 提示 wxWidgets_LIB_DIR 应为缓存变量

    set(wxWidgets_LIB_DIR "M:/wxWidgets/lib/gcc510TDM_x64_dll"
        CACHE PATH "wxWidgets_LIB_DIR ")
    
  3. 这就是你的情况。

    首先"配置"调用:

    1. 缓存为空。
    2. 脚本检测(使用find_path)库的根目录,并将结果存储到 WX_ROOT_PATH 缓存变量中。
    3. 该脚本发现 WX_ROOT_PATH 变量的值与 wxWidgets_ROOT_DIR 的值不同。因此,它将缓存变量 WX_ROOT_PATH 的值修改为 wxWidgets_ROOT_DIR 的值。
    4. 另外,由于上一步检测到差异,脚本会将缓存变量 wxWidgets_LIB_DIR 设置为-NOTFOUND
    5. 脚本尝试检测(使用find_path)库目录而不提示 wxWidgets_LIB_DIR 。当然,这失败了。结果(-NOTFOUND)将存储到缓存变量 wxWidgets_LIB_DIR 中,但它已具有此值。
    6. 在步骤4中设置缓存变量 wxWidgets_LIB_DIR 使用相同的名称清除非缓存变量,因此进一步搜索失败

      在第二个"配置"调用:

      1. 变量 WX_ROOT_PATH wxWidgets_LIB_DIR 已经在缓存中。
      2. find_path()不执行任何操作,因为 WX_ROOT_PATH 已经在缓存中。
      3. WX_ROOT_PATH (缓存)和 wxWidgets_ROOT_DIR (非缓存)的值相同。
      4. 未执行缓存变量 wxWidgets_LIB_DIR 的设置(不执行整个步骤。)
      5. find_path仍无法找到库路径,但缓存变量 wxWidgets_LIB_DIR 的值已经 -NOTFOUND,因此未修改。< / LI>

        非缓存变量 wxWidgets_LIB_DIR (由您自己设置)不会被清除,并且会在进一步搜索中使用。 (非缓存变量阴影缓存一个,请参阅documentation中的* Variable types in CMake *以获取set命令。所以这个配置成功

答案 1 :(得分:0)

我在使用Visual Studio 2015x64的生成器时遇到了同样的问题,直到我添加了行设置WX_ROOT_DIR:

SET(WX_ROOT_DIR ${wxwidgets_path})
SET(wxWidgets_CONFIGURATION mwsu)
SET(wxWidgets_ROOT_DIR ${wxwidgets_path})
SET(wxWidgets_LIB_DIR ${wxwidgets_path}/vc_x64_lib)
FIND_PACKAGE(wxWidgets REQUIRED QUIET)