From 42e68018438b225ae68eecd3e36338e11dd177b8 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 22 Oct 2013 12:56:14 +0200 Subject: [PATCH] iOS (OSX): rework how to bundle QML import folders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this patch, we would copy "$QTDIR/qml" directly into the bundle as "qml". This would cause problems if the user also tried to deploy qml files to a "qml" folder, or if any other file in the bundle ended up with the name "qml" (which is the case for QtDeclarative/tools/qml, where the executable is called "qml"). This patch will instead copy the contents of each import folder into QMAKE_QML_BUNDLE_PATH, which will default to "qt_qml" on iOS and "Resources/qt_qml" on OSX. We also change the implementation to use a post script rather then QMAKE_BUNDLE_DATA for two reasons: 1. Xcode does not like "copy build phases" to copy folders, only files (You cannot even create such a phase from Xcode, although it is possible to force it the way we create project.pbx. But this was error prone) 2. We need to strip away unneeded files from the bundle, like archives (which are linked in statically, not dlopened run-time). Using rsync lets us copy and strip in one operation. Change-Id: I7c2117f6cfbe11efdc272dff71adb0b1e619a5ff Reviewed-by: Oswald Buddenhagen Reviewed-by: Morten Johan Sørvig --- mkspecs/features/qt.prf | 50 ++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index d13b9bb8d5..279540c384 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -124,33 +124,37 @@ if(contains(QT, qml)|contains(QT_PRIVATE, qml)): \ QMAKE_CLEAN += $$QML_IMPORT_CPP # copy qml files. this part is platform spesific. - macx { - # copy to Contents/Resources in the bundle. - QmlImports.path = Contents/Resources/ - QmlImports.files *= $$QMLPATHS - QMAKE_BUNDLE_DATA += QmlImports + mac { + osx { + # Note: user can override QMAKE_BUNDLE_QML from pro file to change target bundle path + isEmpty(QMAKE_QML_BUNDLE_PATH):QMAKE_QML_BUNDLE_PATH = "Resources/qt_qml" + qmlTargetPath = $$OUT_PWD/$${TARGET}.app/Contents/$$QMAKE_QML_BUNDLE_PATH + qtconfTargetPath = $$OUT_PWD/$${TARGET}.app/Contents/Resources/qt.conf + } else { + # iOS: flat bundle layout (no Contents/Resources) + isEmpty(QMAKE_QML_BUNDLE_PATH):QMAKE_QML_BUNDLE_PATH = "qt_qml" + qmlTargetPath = $CODESIGNING_FOLDER_PATH/$$QMAKE_QML_BUNDLE_PATH + qtconfTargetPath = $CODESIGNING_FOLDER_PATH/qt.conf + } - # place qt.conf in Contents/Resources in the app bundle + # set import path in qt.conf to point to the bundeled qml: QT_CONF_CONTENTS = \ "[Paths]" \ - "Imports = Resources/qml" \ - "Qml2Imports = Resources/qml" - QT_CONF = "$$OUT_PWD/$${TARGET}.app/Contents/Resources/qt.conf" - write_file($$QT_CONF, QT_CONF_CONTENTS)|error("Aborting.") - } else: ios { - # flat bundle layout (no Contents/Resources) - QmlImports.files *= $$QMLPATHS - QMAKE_BUNDLE_DATA += QmlImports + "Imports = $$QMAKE_QML_BUNDLE_PATH" \ + "Qml2Imports = $$QMAKE_QML_BUNDLE_PATH" + write_file("$$OUT_PWD/qt.conf", QT_CONF_CONTENTS)|error("Aborting.") - # write qt.conf to OUT_PWD and make xcode copy it via QMAKE_BUNDLE_DATA - QT_CONF_CONTENTS = \ - "[Paths]" \ - "Imports = qml" \ - "Qml2Imports = qml" - QT_CONF = "$$OUT_PWD/qt.conf" - write_file($$QT_CONF, QT_CONF_CONTENTS)|error("Aborting.") - QtConf.files = $$QT_CONF - QMAKE_BUNDLE_DATA += QtConf + # write qt.conf and copy each qml import dir into the bundle. + # But strip away archives and other files that are not needed: + !isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK += ";" + QMAKE_POST_LINK += \ + "cp $$OUT_PWD/qt.conf $$qtconfTargetPath; " \ + "test -d $$qmlTargetPath && rm -r $$qmlTargetPath; " \ + "mkdir -p $$qmlTargetPath && " \ + "for p in $$QMLPATHS; do" \ + "rsync -r --exclude='*.a' --exclude='*.prl' --exclude='*.qmltypes' " + macx-xcode: QMAKE_POST_LINK += "$p/ $$qmlTargetPath; done" + else: QMAKE_POST_LINK += "\$\$p/ $$qmlTargetPath; done" } } }