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

如何在Windows上打包使用CMake构建的Qt程序?,windows,qt,cmake,package,Windows,Qt,Cmake,Package,我正在写一个跨平台的程序,我想在Windows上打包。我把三个DLL(Qt5Core、Qt5Widgets、Qt5Gui)放在build目录中运行它,然后制作一个tarball并把它交给另一个使用Windows box的人,但它不会在他的Windows box上运行。我搜索了一种获取所需其他内容的方法,找到了Nathan Osman关于windeployqt的帖子,因此我将windeployqt.cmake复制到了cmake/Modules目录,但不知道如何使用它。有没有一种方法可以使用CPac

我正在写一个跨平台的程序,我想在Windows上打包。我把三个DLL(Qt5Core、Qt5Widgets、Qt5Gui)放在build目录中运行它,然后制作一个tarball并把它交给另一个使用Windows box的人,但它不会在他的Windows box上运行。我搜索了一种获取所需其他内容的方法,找到了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)
项目(perfecttin)
cmake_最低要求(3.8.0版)
设置(CMAKE\U INCLUDE\U CURRENT\U DIR ON)
设置(CMAKE_自动监控开启)
集合(CMAKE_CXX_标准17)出现在CMAKE 3.8中
设置(上需要CMAKE\U CXX\U标准)
设置(CMAKE_CXX_扩展打开)
set(SHARE_DIR${CMAKE_INSTALL_PREFIX}/SHARE/perfecttin)
添加定义(-DBOOST\u ALL\u NO\u LIB)
if(${CMAKE\u CXX\u COMPILER\u ID}”STREQUAL“MSVC”)
设置(启动\u使用\u静态\u库打开)
else()
设置(Boost\u USE\u STATIC\u LIBS OFF)
endif()
设置(CMAKE_模块路径${CMAKE_模块路径}“${CMAKE_源目录}/CMAKE/Modules/”)
查找_包(LibPLYXX)
查找_包(需要Qt5组件核心小部件Gui语言工具)
查找_程序包(Boost COMPONENTS program_选项)
查找包(线程)
qt5添加资源(lib\u resources perfecttin.qrc)
qt5_添加_翻译(qm_文件perfecttin_en.ts perfecttin_es.ts)
#要更新翻译,请在源目录中运行“lupdate*.cpp-ts*.ts”。
添加可执行文件(perfecttin gui adjelev.cpp angle.cpp binio.cpp
unitbutton.cpp${lib\u资源}${qm\u文件})
目标链接库(PerfectTinGUI${CMAKE_线程{LIBS_INIT}Qt5::Widgets Qt5::Core)
目标链接库(fuzzptin${CMAKE\u线程\u LIBS\u INIT})
目标\u编译\u定义(模糊公共\u使用\u数学\u定义)
目标编译定义(perfecttin gui公共使用数学定义)
设置目标属性(perfecttin gui属性WIN32可执行文件TRUE)
安装(目标为gui目标箱)
安装(文件${qm_FILES}目标共享/perfecttin)
包含目录(${PROJECT\u BINARY\u DIR})
配置_文件(config.h.in config.h)
设置(CPACK\u PACKAGE\u VERSION\u MAJOR${PERFECTTIN\u MAJOR\u VERSION})
设置(CPACK\u PACKAGE\u VERSION\u MINOR${PERFECTTIN\u MINOR\u VERSION})
设置(CPACK\u PACKAGE\u VERSION\u PATCH${PERFECTTIN\u PATCH\u VERSION})
设置(CPACK\u RESOURCE\u FILE\u LICENSE${CMAKE\u SOURCE\u DIR}/复制)
设置(CPACK\u SOURCE\u IGNORE\u FILES/\\\\\.git;*~)
包括(注册会计师)
包括(CTest)

如果您的
${CMAKE\u SOURCE\u DIR}/CMAKE/Modules/
目录中已有文件
Windeployqt.CMAKE
,您可以这样使用它:

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

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

这是一个完整的例子。

我在这方面花了很长时间,虽然我确实从中借用了很多东西,但是它缺少必要的环境设置,这导致了

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>\"
)
#检索qmake的绝对路径,然后使用该路径查找
#windeployqt可执行文件
获取\u目标\u属性(QMAKE\u EXE Qt6::QMAKE导入的\u位置)
获取\u文件名\u组件(QT\u BIN\u DIR“${QMAKE\u EXE}”目录)
find_程序(WINDEPLOYQT_ENV_SETUP qtenv2.bat提示“${QT_BIN_DIR}”)
find_程序(WINDEPLOYQT_可执行WINDEPLOYQT提示“${QT_BIN_DIR}”)
#生成后立即运行windeployqt
添加自定义命令(目标用户界面)
后期构建
命令“${WINDEPLOYQT\u ENV\u SETUP}”&&“${WINDEPLOYQT\u EXECUTABLE}”\“$\”
)

我尝试将DESTINATION设置为${INSTALL\u BIN\u PATH},但出现了以下错误:``安装目标没有为可执行目标“perfecttin gui”指定运行时目标。```这个变量集在哪里?我在CMake文档中找不到它。您需要使用
set(INSTALL\u BIN\u PATH“BIN”)
或其他方法为您的项目定义INSTALL\u BIN\u PATH变量的值。该页面上没有提到
安装路径。我一直在使用
bin
,在Linux和BSD上没有问题;我不知道Windows。
INSTALL\u BIN\u PATH
只是一个变量的名称。您可以创建并为变量指定您喜欢的任何名称。这个名字没什么特别的。如果您在CMakeLists.txt中包含(GNUInstallDirs),它将为您提供一个名为
CMAKE\u INSTALL\u BINDIR
的变量和默认值
bin
。文档中提到了这个变量:对于常规可执行文件、静态库和共享库,不需要DESTINATION参数……我只是开始在Windows上构建它。首先,我使用函数的不正确参数调用了
windeployqt函数。然后,我将变量替换为“bin”、“windeployqt(perfecttin gui-bin)
,它基于MinGW构建,生成目录
iconengines
imageformats
平台
样式
翻译。但是,在MSVC上,它失败了,说
C:\Users\phma\build\perfecttin\vs\dbg\perfecttin.exe似乎不是Qt可执行文件。
。下一步是什么?你能链接到Nathan Osman关于windeployqt的帖子吗?听起来不错!