Qt5 CMake 将所有库包含到可执行文件中
Qt5 CMake include all libraries into executable
我正在尝试使用 Qt 5.14 构建一个处于发布模式的应用程序,并且在 Qt Creator 中一切正常,但是当我尝试 运行 可执行文件本身时,我得到了像这样的错误:
OS: Windows 10
Qt:5.14
Cmake:3.5
我试过的:
- 设置(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
- 设置(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC")
- ${ADDITIONAL_LIBRARIES} - target_link_libraries
内部的静态
上面的 None 对我有用,每当我尝试 运行 不使用 Qt Creator 自行 运行 可执行文件时,我都会遇到同样的错误。
我的 CMake 文件:
cmake_minimum_required(VERSION 3.5)
project(Scrollable LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 REQUIRED Core Widgets Gui Qml Quick Qml)
qt5_add_resources(resource.qrc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories("MoviesInterface")
set(SOURCES
main.cpp
MovieInterface/movieinterfaceomdb.cpp
MovieInterface/moviesinterface.cpp
)
set(HEADERS
MovieInterface/movieinterfaceomdb.h
MovieInterface/moviesinterface.h
)
add_executable(Scrollable ${SOURCES} ${HEADERS} qml.qrc)
qt5_use_modules(Scrollable Core Network)
target_link_libraries(Scrollable
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::Qml
${ADDITIONAL_LIBRARIES} -static
)
A 你要静态编译。这不适用于 Qt 库和 Mingw 库本身,因为它们也需要静态编译。
但它们仅作为动态 linked 库分发。
如果您真的想要静态 link 可用的 Qt 库,则需要先静态编译 Qt,然后才能 link 它们。那里有一些关于静态编译 Qt 的描述。但这是很多工作。
B 为什么找不到Qt5Core.dll:
在 Qt Creator 中,由于 Compiler/Toolchain 自动检测,您的应用程序的 Qt 库路径会自动设置。
但是,当您 运行 您的应用程序可执行文件独立时,未设置 Qt 库的路径,它们不位于可执行文件旁边的应用程序文件夹中。
为了解决这个问题,我建议使用 windeployqt
。
windeployqt 分析您构建的库或可执行文件,并将所需的 Qt 依赖项复制到构建文件夹中。
我倾向于为此使用 cmake 辅助函数。
- 使用以下内容创建
windeployqt.cmake
并将其放入项目的 /cmake
模块文件夹中:
find_package(Qt5Core REQUIRED)
# get absolute path to qmake, then use it to find windeployqt executable
get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION)
get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY)
function(windeployqt target)
# POST_BUILD step
# - after build, we have a bin/lib for analyzing qt dependencies
# - we run windeployqt on target and deploy Qt libs
add_custom_command(TARGET ${target} POST_BUILD
COMMAND "${_qt_bin_dir}/windeployqt.exe"
--verbose 1
--release
--no-svg
--no-angle
--no-opengl
--no-opengl-sw
--no-compiler-runtime
--no-system-d3d-compiler
\"$<TARGET_FILE:${target}>\"
COMMENT "Deploying Qt libraries using windeployqt for compilation target '${target}' ..."
)
endfunction()
注1:设置--verbose 1
,让你看看是怎么回事。您可以稍后禁用它。
注2:请自行处理排除项。我不知道您的应用程序的具体要求,例如如果您需要 OpenGL 或 SVG 支持。
- 然后添加到你的
CMakeLists.txt
:
# Set path to our custom CMAKE scripts
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
# Include Qt deployment helper function
include(windeployqt)
最后在CMakeLists.txt
末尾加上:
windeployqt(Scrollable)
现在,windeployqt 运行 作为可执行文件的 POST_BUILD 步骤,将 qt 库复制到构建文件夹。可执行文件现在将从该文件夹中获取 Qt 依赖项,并且应该能够 运行 独立(没有设置 Qt 库的路径)。
记住还要复制其他依赖项,例如第三方库或 运行时间依赖性。
跟进您的 mingw 依赖项:
set(QT_MINGW "/path/to/your/qt/mingw/compiler")
add_custom_command(TARGET Scrollable POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libgcc_s_dw2-1.dll $<TARGET_FILE_DIR:${TARGET}>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libstdc++-6.dll $<TARGET_FILE_DIR:${TARGET}>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libwinpthread-1.dll $<TARGET_FILE_DIR:${TARGET}>
COMMENT "Deploy mingw runtime libraries from ${QT_MINGW}/bin"
)
Follow-up for your mingw dependencies:
...
如果 Qt 也与 MinGW 一起安装,您可以避免在 add_custom_command
中对运行时库进行额外的复制操作,只需使用 windeployqt.exe
和 --compiler-runtime
命令行选项。
我正在尝试使用 Qt 5.14 构建一个处于发布模式的应用程序,并且在 Qt Creator 中一切正常,但是当我尝试 运行 可执行文件本身时,我得到了像这样的错误:
OS: Windows 10
Qt:5.14
Cmake:3.5
我试过的:
- 设置(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
- 设置(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC")
- ${ADDITIONAL_LIBRARIES} - target_link_libraries 内部的静态
None 对我有用,每当我尝试 运行 不使用 Qt Creator 自行 运行 可执行文件时,我都会遇到同样的错误。
我的 CMake 文件:
cmake_minimum_required(VERSION 3.5)
project(Scrollable LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 REQUIRED Core Widgets Gui Qml Quick Qml)
qt5_add_resources(resource.qrc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories("MoviesInterface")
set(SOURCES
main.cpp
MovieInterface/movieinterfaceomdb.cpp
MovieInterface/moviesinterface.cpp
)
set(HEADERS
MovieInterface/movieinterfaceomdb.h
MovieInterface/moviesinterface.h
)
add_executable(Scrollable ${SOURCES} ${HEADERS} qml.qrc)
qt5_use_modules(Scrollable Core Network)
target_link_libraries(Scrollable
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::Qml
${ADDITIONAL_LIBRARIES} -static
)
A 你要静态编译。这不适用于 Qt 库和 Mingw 库本身,因为它们也需要静态编译。 但它们仅作为动态 linked 库分发。
如果您真的想要静态 link 可用的 Qt 库,则需要先静态编译 Qt,然后才能 link 它们。那里有一些关于静态编译 Qt 的描述。但这是很多工作。
B 为什么找不到Qt5Core.dll:
在 Qt Creator 中,由于 Compiler/Toolchain 自动检测,您的应用程序的 Qt 库路径会自动设置。
但是,当您 运行 您的应用程序可执行文件独立时,未设置 Qt 库的路径,它们不位于可执行文件旁边的应用程序文件夹中。
为了解决这个问题,我建议使用 windeployqt
。
windeployqt 分析您构建的库或可执行文件,并将所需的 Qt 依赖项复制到构建文件夹中。
我倾向于为此使用 cmake 辅助函数。
- 使用以下内容创建
windeployqt.cmake
并将其放入项目的/cmake
模块文件夹中:
find_package(Qt5Core REQUIRED)
# get absolute path to qmake, then use it to find windeployqt executable
get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION)
get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY)
function(windeployqt target)
# POST_BUILD step
# - after build, we have a bin/lib for analyzing qt dependencies
# - we run windeployqt on target and deploy Qt libs
add_custom_command(TARGET ${target} POST_BUILD
COMMAND "${_qt_bin_dir}/windeployqt.exe"
--verbose 1
--release
--no-svg
--no-angle
--no-opengl
--no-opengl-sw
--no-compiler-runtime
--no-system-d3d-compiler
\"$<TARGET_FILE:${target}>\"
COMMENT "Deploying Qt libraries using windeployqt for compilation target '${target}' ..."
)
endfunction()
注1:设置--verbose 1
,让你看看是怎么回事。您可以稍后禁用它。
注2:请自行处理排除项。我不知道您的应用程序的具体要求,例如如果您需要 OpenGL 或 SVG 支持。
- 然后添加到你的
CMakeLists.txt
:
# Set path to our custom CMAKE scripts
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
# Include Qt deployment helper function
include(windeployqt)
最后在CMakeLists.txt
末尾加上:
windeployqt(Scrollable)
现在,windeployqt 运行 作为可执行文件的 POST_BUILD 步骤,将 qt 库复制到构建文件夹。可执行文件现在将从该文件夹中获取 Qt 依赖项,并且应该能够 运行 独立(没有设置 Qt 库的路径)。
记住还要复制其他依赖项,例如第三方库或 运行时间依赖性。
跟进您的 mingw 依赖项:
set(QT_MINGW "/path/to/your/qt/mingw/compiler")
add_custom_command(TARGET Scrollable POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libgcc_s_dw2-1.dll $<TARGET_FILE_DIR:${TARGET}>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libstdc++-6.dll $<TARGET_FILE_DIR:${TARGET}>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libwinpthread-1.dll $<TARGET_FILE_DIR:${TARGET}>
COMMENT "Deploy mingw runtime libraries from ${QT_MINGW}/bin"
)
Follow-up for your mingw dependencies: ...
如果 Qt 也与 MinGW 一起安装,您可以避免在 add_custom_command
中对运行时库进行额外的复制操作,只需使用 windeployqt.exe
和 --compiler-runtime
命令行选项。