如何在Windows上打包用CMake构建的Qt程序?

x8goxv8g  于 2022-12-23  发布在  Windows
关注(0)|答案(3)|浏览(350)

我正在写一个跨平台的程序,我想把它打包在Windows上。我把它放在三个DLL中运行(Qt 5Core,Qt 5 Widgets,Qt 5Gui),然后做了一个tarball,把它给了其他有Windows盒子的人,但是它不会在他的Windows盒子上运行。我搜索了一种方法来获得它所需要的其他任何东西,并找到了Nathan Osman关于windeployqt的帖子,所以我把windeployqt.cmake复制到cmake/Modules目录,但是不知道如何使用它。有没有一种方法可以使用CPack来创建一个包(即使它只是一个tarball),在没有安装编译器或Qt的Windows机器上运行程序所需的一切?
下面是CMakeLists.txt文件,其中删除了一些内容(希望不相关):

project(perfecttin)
cmake_minimum_required(VERSION 3.8.0)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD 17) # appeared in CMake 3.8
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
set(SHARE_DIR ${CMAKE_INSTALL_PREFIX}/share/perfecttin)
add_definitions(-DBOOST_ALL_NO_LIB)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(Boost_USE_STATIC_LIBS ON)
else ()
set(Boost_USE_STATIC_LIBS OFF)
endif ()

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
find_package(LibPLYXX)
find_package(Qt5 COMPONENTS Core Widgets Gui LinguistTools REQUIRED)
find_package(Boost COMPONENTS program_options)
find_package(Threads)

qt5_add_resources(lib_resources perfecttin.qrc)
qt5_add_translation(qm_files perfecttin_en.ts perfecttin_es.ts)
# To update translations, run "lupdate *.cpp -ts *.ts" in the source directory.

add_executable(perfecttin-gui adjelev.cpp angle.cpp binio.cpp
           <snip lots of source files>
               unitbutton.cpp ${lib_resources} ${qm_files})
target_link_libraries(perfecttin-gui ${CMAKE_THREAD_LIBS_INIT} Qt5::Widgets Qt5::Core)
target_link_libraries(fuzzptin ${CMAKE_THREAD_LIBS_INIT})
target_compile_definitions(fuzzptin PUBLIC _USE_MATH_DEFINES)
target_compile_definitions(perfecttin-gui PUBLIC _USE_MATH_DEFINES)
set_target_properties(perfecttin-gui PROPERTIES WIN32_EXECUTABLE TRUE)

install(TARGETS perfecttin-gui DESTINATION bin)
install(FILES ${qm_files} DESTINATION share/perfecttin)

include_directories(${PROJECT_BINARY_DIR})
configure_file (config.h.in config.h)

set(CPACK_PACKAGE_VERSION_MAJOR ${PERFECTTIN_MAJOR_VERSION})
set(CPACK_PACKAGE_VERSION_MINOR ${PERFECTTIN_MINOR_VERSION})
set(CPACK_PACKAGE_VERSION_PATCH ${PERFECTTIN_PATCH_VERSION})
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/COPYING)
set(CPACK_SOURCE_IGNORE_FILES /\\\\.git;.*~)
include(CPack)

include(CTest)
rdlzhqv9

rdlzhqv91#

如果您的${CMAKE_SOURCE_DIR}/cmake/Modules/目录中已经有Windeployqt.cmake文件,您可以这样使用它:

install(TARGETS perfecttin-gui 
    DESTINATION "${INSTALL_BIN_PATH}"
)

if(WIN32)
    include(Windeployqt)
    windeployqt(nitroshare-cli ${INSTALL_BIN_PATH})
endif()

Here是完整的示例。

x6yk4ghg

x6yk4ghg2#

我确实从this answer中借了很多东西,但是它缺少了必要的环境设置,这导致了Warning: Cannot find GCC installation directory. g++.exe must be in the path.
Qt具有以下有关使用windeployqt.exe的文档

The tool can be found in QTDIR/bin/windeployqt. It needs to be run within the build environment in order to function correctly.
When using Qt Installer, the script QTDIR/bin/qtenv2.bat should be used to set it up.

基本上,您需要在正确的环境中将windeployqt.exe作为自定义命令运行。

# Retrieve the absolute path to qmake and then use that path to find
# the windeployqt executable
get_target_property(QMAKE_EXE Qt6::qmake IMPORTED_LOCATION)
get_filename_component(QT_BIN_DIR"${QMAKE_EXE }" DIRECTORY)

find_program(WINDEPLOYQT_ENV_SETUP qtenv2.bat HINTS "${QT_BIN_DIR}")
find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_BIN_DIR}")

# Run windeployqt immediately after build
add_custom_command(TARGET perfecttin-gui
    POST_BUILD
    COMMAND "${WINDEPLOYQT_ENV_SETUP}" && "${WINDEPLOYQT_EXECUTABLE}" \"$<TARGET_FILE:perfectin-gui>\"
)
bxfogqkk

bxfogqkk3#

自版本6.3起,Qt提供了一种定义安装时执行的其他部署步骤的方法。
第一个月
除此之外,现在已经包含了一个*deploy实用程序脚本生成器。

install(TARGETS perfecttin-gui DESTINATION bin)

qt_generate_deploy_app_script(
    TARGET perfecttin-gui
    FILENAME_VARIABLE deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})

文档位于:生成部署应用程序脚本
根据目前为止的文档,这在Linux上不起作用
对于更多的选项(显然是Linux支持?),可以使用上面的方便版本实际调用的函数:qt部署运行时依赖关系
例如qt_generate_deploy_app_script()把Qt插件放在目标目录“bin”之外,每个插件都在自己的文件夹中,我不喜欢这样(我希望它们都在“bin”下)。所以我不得不使用完整版本(这基本上都来自上面链接的Qt文档):

set(MY_APP perfecttin-gui)

if(APPLE)
  set(executable_path "$<TARGET_FILE_NAME:${MY_APP}>.app")
else()
  set(executable_path "\${QT_DEPLOY_BIN_DIR}/$<TARGET_FILE_NAME:${MY_APP}>")
endif()

set(deploy_script "${CMAKE_CURRENT_BINARY_DIR}/deploy_${MY_APP}.cmake")

file(GENERATE OUTPUT ${deploy_script} CONTENT "
include(\"${QT_DEPLOY_SUPPORT}\")
qt_deploy_runtime_dependencies(
    EXECUTABLE \"${executable_path}\"
    PLUGINS_DIR bin
)"
)

install(TARGETS ${MY_APP} DESTINATION bin)
install(SCRIPT ${deploy_script})

有关一般部署的更多详细信息,请参见https://www.qt.io/blog/cmake-deployment-api

增加

已找到qt_deploy_runtime_dependencies()的源文件。
看起来下一个版本增加了一个NO_TRANSLATIONS选项,但它不在我的6.4.1中。
但我确实发现了一个黑客传递额外的选项到部署工具...
如果你在代码中搜索__qt_deploy_tool_extra_options,你会看到关于它如何消失的警告。
我的file(GENERATE OUTPUT)现在看起来像这样(可能需要根据平台进行调整):

file(GENERATE OUTPUT ${deploy_script} CONTENT "
include(\"${QT_DEPLOY_SUPPORT}\")
set(__qt_deploy_tool_extra_options --no-compiler-runtime --no-translations)
qt_deploy_runtime_dependencies(
    EXECUTABLE \"${executable_path}\"
    PLUGINS_DIR bin
#    NO_TRANSLATIONS
)
")

还有qt_generate_deploy_app_script()源代码(如果有人感兴趣)。

相关问题