2017-01-28 13 views
2

Я следующий CMakeLists.txt для создания маленького приложения:Deploy ICU библиотеки при компоновке на CMake проект с Qt5

cmake_minimum_required (VERSION 3.5.0) 

project (sampleapp) 

# Setting project flags 
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib) 
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib) 
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin) 
set (CMAKE_INCLUDE_CURRENT_DIR ON) 
set (CMAKE_AUTOMOC ON) 

# Finding needed packages 
find_package (Qt5Widgets REQUIRED) 
find_package (Qt5Core REQUIRED) 
find_package (Qt5Gui REQUIRED) 

# Setting project files 
include_directories (${CMAKE_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}) 
file (GLOB_RECURSE PROJECT_SRC *.cpp) 

# Creating project 
add_executable(${PROJECT_NAME} ${PROJECT_SRC}) 

# Linking dependencies 
target_link_libraries (${PROJECT_NAME} somelibrary Qt5::Widgets Qt5::Gui Qt5::Core) 
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:${PROJECT_NAME}>) 
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:${PROJECT_NAME}>) 
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:${PROJECT_NAME}>) 

Когда я запускаю его, а затем построить приложение на Qt библиотеки DLL копируются в целевую папку. В частности, я копирую:

  • Qt5Core.dll
  • Qt5Gui.dll
  • Qt5Widgets.dll

При запуске приложения он не запускается в любом случае, потому что ICU библиотеки, необходимые для Qt не копируются. При запуске приложения, Windows говорит мне, что следующие библиотеки отсутствуют:

  • icuin53.dll
  • icuuc53.dll

Если скопировать эти библиотеки вручную из папки Qt insallation это работает (хорошо, Я ошибка в отношении «окон плагинов плагинов» отсутствует, но это еще одна история).

Есть ли способ скопировать библиотеки icu стандартным способом, например, команды post build, которые я использую для копирования библиотек? Или как лучше всего копировать их прозрачным способом, если это возможно (CMake может знать, что такое зависимости Qt и скопировать их, где Qt необходимо)?

+0

'CMake может знать, что являются зависимостями Qt и скопировать их, где Qt необходимы' - сам CMake не имеет возможности копировать все depdendent библиотеки. – Tsyvarev

+0

Итак, каков наилучший способ cmake для копирования этих библиотек вместе с Qt? – Jepessen

+0

Насколько я понимаю, CMake рассматривает ** копирование 3d-партийных библиотек ** в каталог с исполняемым файлом как ** плохой дизайн **. С точки зрения разработчика, библиотеки 3d-party должны быть установлены * system-wide *, поэтому их можно загрузить из любого исполняемого файла. Хотя я понимаю, что ваша проблема актуальна, я не знаю решения. – Tsyvarev

ответ

4

Вместо копирования каждой dll вручную вы можете установить все зависимости Qt, используя windeployqt, инструмент, поставляемый с Qt для развертывания в Windows.

Вы можете сначала объявить windeployqt как импортируемого исполняемый:

find_package(Qt5 
    # ... 
) 

if(Qt5_FOUND AND WIN32 AND TARGET Qt5::qmake AND NOT TARGET Qt5::windeployqt) 
    get_target_property(_qt5_qmake_location 
     Qt5::qmake IMPORTED_LOCATION 
    ) 

    execute_process(
     COMMAND "${_qt5_qmake_location}" -query QT_INSTALL_PREFIX 
     RESULT_VARIABLE return_code 
     OUTPUT_VARIABLE qt5_install_prefix 
     OUTPUT_STRIP_TRAILING_WHITESPACE 
    ) 

    set(imported_location "${qt5_install_prefix}/bin/windeployqt.exe") 

    if(EXISTS ${imported_location}) 
     add_executable(Qt5::windeployqt IMPORTED) 

     set_target_properties(Qt5::windeployqt PROPERTIES 
      IMPORTED_LOCATION ${imported_location} 
     ) 
    endif() 
endif() 

Теперь импортируемый исполняемый файл может быть использован следующим образом:

add_executable(foo 
    # ... 
) 

if(TARGET Qt5::windeployqt) 
    add_custom_command(TARGET foo 
     POST_BUILD 
     COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/windeployqt" 
     COMMAND set PATH=%PATH%$<SEMICOLON>${qt5_install_prefix}/bin 
     COMMAND Qt5::windeployqt --dir "${CMAKE_CURRENT_BINARY_DIR}/windeployqt" "$<TARGET_FILE:foo>" 
    ) 

    install(
     DIRECTORY 
     "${CMAKE_CURRENT_BINARY_DIR}/windeployqt/" 
     DESTINATION ${FOO_INSTALL_RUNTIME_DESTINATION} 
    ) 
endif() 
+0

Отлично! Спасибо, это инструмент, который мне нужен ... Мне нужно только создать функцию cmake для обработки всего этого и поместить его в отдельный файл, чтобы я мог использовать его во всех моих проектах без вздутия. Еще раз спасибо. – Jepessen

+1

Не можете ли вы просто заменить '$ /$ ' с '$ '? Последний - полный путь к цели, это то, что вы пытаетесь построить с помощью первого. Я ошибаюсь? – skypjack

+0

@skypjack выглядит так, будто вы правы. Я отредактировал свой ответ. Спасибо :) – wasthishelpful