簡體   English   中英

帶有用於 Qt 應用程序的 BundleUtiliies 的 CMake MacOS X 捆綁包

[英]CMake MacOS X bundle with BundleUtiliies for Qt application

我是一名 CMake 初學者,在為 MacOS X 創建 Qt 應用程序包時遇到了問題。讓我們考慮一個僅包含一個main.cpp文件的簡單小部件“helloworld”應用程序。

// main.cpp
#include <QApplication>
#include <QLabel>

int main(int argc, char** argv)
{
    QApplication app(argc,argv);
    QLabel lbl("Hello");
    lbl.show();
    return app.exec();
}

CMakeLists.txt文件也很簡單。

# CMakeLists.txt
cmake_minimum_required( VERSION 3.0 )
project( QtBundle )    
set( CMAKE_INCLUDE_CURRENT_DIR ON )
set( CMAKE_AUTOMOC ON )

set( SOURCES main.cpp )    
find_package( Qt5Widgets REQUIRED )

add_executable( ${PROJECT_NAME} MACOSX_BUNDLE ${SOURCES} )    
qt5_use_modules( ${PROJECT_NAME} Widgets )

我運行cmake .. -DCMAKE_PREFIX_PATH=/path/to/Qt5.5.1/並在build目錄中生成Makefile

然后我運行make並擁有我想要的QtBundle.app目錄和QtBundle.app/Contents/MacOS/QtBundle可執行文件,好的。

但是當我啟動它時,我得到:

This application failed to start because it could not find or load the Qt platform plugin "cocoa".

Reinstalling the application may fix this problem.
Abort trap: 6 

據我所知,發生錯誤是因為應用程序包沒有任何 Qt 的東西(框架庫和插件),所以我運行macdeployqt ,它在框架和插件文件夾中填充了大量文件的包目錄,應用程序能夠運行並重新定位到另一個系統。

它部分解決了問題,但我想用 CMake 和BundleUtilities填充捆綁包,而不用 macdeployqt 工具。

不幸的是,我沒有找到使用 BundleUtilities 部署 Qt5 的任何好的和簡單的示例。

有人可以幫我修改我的“helloworld”示例,讓 CMake 自動創建准備部署的包?

提前致謝。

主要問題:如何使用 CMake BundleUtilities 獲取可重定位的應用程序?

將下面的代碼添加到CMakeLists.txt 最具挑戰性的事情是弄清楚你需要什么插件,找到它們的名字,然后為 BundleUtilities 的fixup_bundle()正確指定路徑。

install_qt5_plugin()宏按名稱定位插件。 它只會找到已經找到的 Qt 模塊的插件。 在這種情況下,Qt5::QCcoaIntegrationPlugin 是 Qt5Gui 模塊中的插件,它被find_package(Qt5 COMPONENTS Widgets REQUIRED)發現為 Qt5Widgets 的依賴項。 宏為插件生成 install() 命令並計算已安裝插件的完整路徑。 后者我們將傳遞(參見QT_PLUGIN變量)到fixup_bundle()

筆記:

  1. 我們創建並安裝qt.conf文件,這樣在應用程序啟動時就可以找到插件。
  2. APPS變量指定包的路徑,而不是其中的可執行文件。
  3. 填充DIRS非常重要。 請注意,它如何使用 CMAKE_PREFIX_PATH。
  4. 印刷APPSQT_PLUGINSDIRS是可選的但非常有用的。
  5. 應該僅手動復制/安裝那些未從 app.xml 引用的動態庫(包括插件)。 Qt 平台插件就是這樣的動態庫。

依賴項查找和修復發生在安裝時。 要在必要的位置獲取可重定位的包,可以使用指向該位置的 CMAKE_INSTALL_PREFIX 進行配置,然后構建install目標。

我更喜歡創建 .dmg 文件

mkdir build
cd build
cmake ..
cpack -G DragNDrop

添加到 CMakeLists.txt 的內容來自這里

set(prefix "${PROJECT_NAME}.app/Contents")
set(INSTALL_RUNTIME_DIR "${prefix}/MacOS")
set(INSTALL_CMAKE_DIR "${prefix}/Resources")

# based on code from CMakes QtDialog/CMakeLists.txt
macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var _prefix)
    get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
    if(EXISTS "${_qt_plugin_path}")
        get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
        get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
        get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
        set(_qt_plugin_dest "${_prefix}/PlugIns/${_qt_plugin_type}")
        install(FILES "${_qt_plugin_path}"
            DESTINATION "${_qt_plugin_dest}")
        set(${_qt_plugins_var}
            "${${_qt_plugins_var}};\$ENV{DEST_DIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
    else()
        message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
    endif()
endmacro()

install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS ${prefix})
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
    "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
    DESTINATION "${INSTALL_CMAKE_DIR}")

# Destination paths below are relative to ${CMAKE_INSTALL_PREFIX}
install(TARGETS ${PROJECT_NAME}
    BUNDLE DESTINATION . COMPONENT Runtime
    RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR} COMPONENT Runtime
    )

# Note Mac specific extension .app
set(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app")

# Directories to look for dependencies
set(DIRS "${CMAKE_BINARY_DIR}")

# Path used for searching by FIND_XXX(), with appropriate suffixes added
if(CMAKE_PREFIX_PATH)
    foreach(dir ${CMAKE_PREFIX_PATH})
        list(APPEND DIRS "${dir}/bin" "${dir}/lib")
    endforeach()
endif()

# Append Qt's lib folder which is two levels above Qt5Widgets_DIR
list(APPEND DIRS "${Qt5Widgets_DIR}/../..")

include(InstallRequiredSystemLibraries)

message(STATUS "APPS: ${APPS}")
message(STATUS "QT_PLUGINS: ${QT_PLUGINS}")
message(STATUS "DIRS: ${DIRS}")

install(CODE "include(BundleUtilities)
    fixup_bundle(\"${APPS}\" \"${QT_PLUGINS}\" \"${DIRS}\")")

set(CPACK_GENERATOR "DRAGNDROP")
include(CPack)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM