2017-01-10 11 views
0

У меня есть следующий код, чтобы попробовать найти wxWidgets 3.1 готовые библиотеки, используя CMake 3.7.1.CMake FindwxWidgets терпит неудачу только при первом вызове команды «configure»

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»/button, когда кеш 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 после первого (не удалось) "Configure":

//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 после последующего (успешного) "Configure":

//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: ВНУТРЕННЕЕ" и т.д.

+1

'Это нормально' - Нет, как правило, алгоритм поиска должен дать * настойчивые * результаты? , Код «FindwxWidgets.cmake» использует некоторую «чистую» логику, когда находит вещи в каталогах, отличных от 'wxWidgets_ROOT_DIR' или' wxWidgets_LIB_DIR'. Вероятно, такая логика вызывает поведение, которое вы наблюдаете. Не могли бы вы предоставить ** содержимое CMake cache ** после первого (неудачного) «configure» и второго? Это даст ключ. Интересны только записи в кеш, начинающиеся с 'wx' или' WX_'. BTW, пример использует букву драйвера в верхнем регистре ('C: /'), но ваш код использует строчный регистр ('m: /'). Это может иметь значение. – Tsyvarev

+0

@ Цыварев На основании вашего комментария я перерисовал cmake-gui и захватил содержимое кэша CMake. Я соответствующим образом обновил этот вопрос. Благодаря! – thebat

+1

@ Цыварев Я нашел обходное решение. Я удалил команды набора для 'wxWidgets_ROOT_DIR' и' wxWidgets_LIB_DIR'. Вместо этого я установил переменную окружения 'wxWidgets_ROOT_DIR' и переместил предварительно созданные файлы библиотеки в одно из мест, которое будет искать FindwxWidgets.cmake. – thebat

ответ

0

FindwxWidgets.cmake сценария имеет нон-intuiti ве логики, так намекая с 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 ") 
    

Это то, что происходит в вашем случае.

Первый "настроить" призывание:

  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, но он уже имеет это значение.

Настройка кэшируются переменной wxWidgets_LIB_DIR на шаге 4 очищает без кэш переменной с тем же именем, так futher поиски не удалось.

На втором "Configure" вызов:

  1. Переменные WX_ROOT_PATH и wxWidgets_LIB_DIR уже в кэше.
  2. find_path() ничего не делает, так как WX_ROOT_PATH уже находится в кеше.
  3. Значения WX_ROOT_PATH (cached) и wxWidgets_ROOT_DIR (без кэша) одинаковы.
  4. Настройка кешированной переменной wxWidgets_LIB_DIR не выполняется (весь шаг не выполняется).
  5. find_path до сих пор не может найти путь к библиотеке, но значение переменной кэшированных wxWidgets_LIB_DIR является уже-NOTFOUND, поэтому она не изменяется.

некэшируемый переменная wxWidgets_LIB_DIR (который устанавливается ваша) не очищается, и используется в поисках futher. (кеширование кэша переменной кэша отсутствует, см. * Variable types in CMake * в documentation для команды set). Так что эта конфигурация преуспеть.

+0

Мне очень нравится ваш ответ. Я изменил код, как было предложено, он постоянно терпел неудачу с той же ошибкой каждый раз. :(Но я думаю, что вы указываете меня в правильном направлении. – thebat

+0

К сожалению, на самом деле это * переменная кэша * wxWidgets_ROOT_DIR *, которая установлена ​​на шаге 2 с помощью 'find_path'. Итак, шаг 3 при первом вызове« configure »неизбежен и он очищает * wxWidgets_ROOT_DIR *. В качестве быстрого обхода вы можете установить как * wxWidgets_ROOT_DIR *, так и * WX_ROOT_DIR * кешированные переменные: 'set (wxWidgets_ROOT_DIR) M:/wxWidgets" CACHE PATH "wxWidgets_ROOT_DIR") ',' set (WX_ROOT_DIR "M :/wxWidgets "CACHE PATH" wxWidgets_ROOT_DIR ")', но это взломать, конечно. Я подумаю о более приятном решении. – Tsyvarev

+0

Я попытался установить как подсказки в виде записей в кэш, так и даже с 'FORCE'. , или сбой при первом вызове. Я не думаю, что эти подсказки действительно работают. – thebat

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)