Qt5 CMake включает все библиотеки в исполняемый файл - PullRequest
1 голос
/ 25 марта 2020

Я пытаюсь собрать приложение с Qt 5.14 в режиме релиза, и внутри Qt Creator все работает нормально, но когда я пытаюсь запустить исполняемый файл сам по себе, я получаю ошибку, подобную этой:


ОС: Windows 10

Qt: 5.14

Cmake: 3,5


enter image description here


Что я пробовал:

  1. set ( CMAKE_EXE_LINKER_FLAGS "-stati c -libg cc -stati c -libstdc ++ -stati c")
  2. set (CMAKE_CXX_FLAGS "$ {CMAKE_CXX_FLAGS} -std = c ++ 0x 1047 * ")
  3. $ {ADDITIONAL_LIBRARIES} -stati c внутри target_link_libraries

Ничего из вышеперечисленного не работает для меня, и я получаю ту же ошибку всякий раз, когда я пытается запустить исполняемый файл самостоятельно без использования 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
        )

1 Ответ

1 голос
/ 25 марта 2020

A Вы хотите статически скомпилировать. Это не сработает для Qt libs и Mingw libs, потому что они также должны быть скомпилированы статически. Но они распространяются только в виде динамически связанных c библиотек.

Если вы действительно хотите иметь статически связываемые библиотеки Qt, вам нужно статически скомпилировать Qt, прежде чем вы сможете связать их. Есть некоторые описания для статической компиляции Qt. Но это большая работа.

B Почему Qt5Core.dll не найден:

Внутри Qt Creator автоматически устанавливается путь к библиотекам Qt для вашего приложения, из-за автоопределения Compiler / Toolchain.

Но когда вы запускаете исполняемый файл приложения автономно, путь к библиотекам Qt не задается, и они не находятся в папке приложения рядом с исполняемым файлом.


Чтобы решить эту проблему, я бы предложил использовать windeployqt. windeployqt анализирует созданную вами библиотеку или исполняемый файл и копирует необходимые зависимости Qt в папку сборки.

Я склонен использовать для этого вспомогательную функцию cmake.

  1. Создать windeployqt.cmake со следующим содержимым и поместить его в папку /cmake modules вашего проекта:
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: Пожалуйста, обработайте исключение самостоятельно. Я не знаю конкретных c требований вашего приложения, например, если вам нужна поддержка 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"
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...