CMake MacOS X bundle with BundleUtiliies for Qt application
CMake MacOS X bundle with BundleUtiliies for Qt application
我是CMake初学者,在为MacOS X创建Qt应用程序包时遇到问题。让我们考虑一个简单的小部件"helloworld"应用程序,仅在一个main.cpp
文件中。
// 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工具。
不幸的是,我没有找到任何使用捆绑实用程序进行Qt5部署的良好而简单的示例。
有人可以帮助我修改我的"helloworld"示例,以便 CMake 自动创建可随时部署的捆绑包吗?
提前谢谢。
主要问题:如何使用CMake BundleUtilities来获取可重定位的应用程序?
将下面的代码添加到CMakeLists.txt
.最具挑战性的事情是弄清楚您需要哪些插件,找到它们的名称,然后正确指定 BundleUtilities fixup_bundle()
的路径。
install_qt5_plugin()
宏按名称查找插件。它只会找到已经找到的Qt模块的插件。在这种情况下,Qt5::QCocoaIntegrationPlugin 是 Qt5Gui 模块中的插件,它被 find_package(Qt5 COMPONENTS Widgets REQUIRED)
找到为 Qt5Widgets 的依赖项。宏为插件生成 install() 命令并计算已安装插件的完整路径。后者我们将传递给(请参阅QT_PLUGIN
变量)fixup_bundle()
。
笔记:
- 我们创建并安装
qt.conf
文件,以便在应用程序启动时找到插件。 -
APPS
变量指定捆绑包的路径,而不是其中的可执行文件。 - 填充
DIRS
非常重要。请注意,它如何使用CMAKE_PREFIX_PATH。 - 打印
APPS
、QT_PLUGINS
和DIRS
是可选的,但非常有用。 - 应该只手动复制/安装那些不是从应用程序引用的动态库(包括插件)。 Qt平台插件就是这样的动态库。
依赖项查找和修复在安装时进行。要在必要的位置获取可重定位的捆绑包,可以使用指向该位置的CMAKE_INSTALL_PREFIX进行配置,然后构建install
目标。
我更喜欢创建.dmg文件
mkdir build
cd build
cmake ..
cpack -G DragNDrop
要添加到CMakeList的内容.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)
- 如何在 qt for windows 中使用 QAxObject 创建 docx 和 doc 文件?
- 我可以在不使用Qt for Webassembly的情况下使用Emscripten编译Qt吗?
- Qt QML for Android bugs
- Qt for wasm: 错误: 使用未声明的标识符 'QThreadPool'
- C++编译Qt for Visual Studio 2017的问题
- Vtk 图表在 QT 中突破,"no override found for 'vtkContextDevice2D"
- Qt::CustomizeWindowHint and Qt::Tool analogs for gtkmm
- 在 qt 控制台应用程序中未定义对 'vtable for myObj' 的引用 - 信号和插槽
- Qt for Android:Jni - 不幸的是,应用程序已停止
- 在 Qt 中使用 for 与 OpenCV3 时出错
- QT 单元测试 moc "unresolved external symbol" for QMetaObject
- QT for Embedded Linux VNC Server 是否已启用互联网
- mysql driver for qt database fedora
- CI for Qt 应用程序:使用不同的 Qt 版本构建
- 如何在 Qt/QML for Android 中创建网页的缩略图
- Qt QDataStream:运算符>> for quint16 - 我根本没有得到它
- Compiling Qt 4.8.x for Visual Studio 2012
- CMake MacOS X bundle with BundleUtiliies for Qt application
- Interface in C++ for Qt
- SOAP library for Qt