From 6cabb18bc2c983fc7013273841739a3490b55f55 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Sat, 28 May 2016 02:13:57 -0700 Subject: Make the Xcode generator recognize embedded frameworks/plugins This makes the Xcode generator smarter so that it recognizes when a QMAKE_BUNDLE_DATA entry is attempting to embed a framework, dynamic library, or plugin into the application bundle, and places it into the correct generated PBXCopyFilesBuildPhase. Change-Id: I67ac1534a0521eecfc90537db6f9aca2bdbc96b0 Reviewed-by: Oswald Buddenhagen Reviewed-by: Gabriel de Dietrich --- qmake/generators/mac/pbuilder_pbx.cpp | 50 +++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 09581879ef..51c39a66d9 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1086,6 +1086,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } bool copyBundleResources = project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app"; ProStringList bundle_resources_files; + ProStringList embedded_frameworks; + QMap embedded_plugins; // Copy Bundle Data if (!project->isEmpty("QMAKE_BUNDLE_DATA")) { ProStringList bundle_file_refs; @@ -1096,6 +1098,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) for(int i = 0; i < bundle_data.count(); i++) { ProStringList bundle_files; ProString path = project->first(ProKey(bundle_data[i] + ".path")); + const bool isEmbeddedFramework = ((!osx && path == QLatin1String("Frameworks")) + || (osx && path == QLatin1String("Contents/Frameworks"))); + const ProString pluginsPrefix = ProString(osx ? QLatin1String("Contents/PlugIns") : QLatin1String("PlugIns")); + const bool isEmbeddedPlugin = (path == pluginsPrefix) || path.startsWith(pluginsPrefix + "/"); + //all files const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files")); for(int file = 0; file < files.count(); file++) { @@ -1113,14 +1120,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) bundle_files += file_key; t << "\t\t" << file_key << " = {\n" << "\t\t\t" << writeSettings("fileRef", file_ref_key) << ";\n" - << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";\n" - << "\t\t};\n"; + << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";\n"; + if (isEmbeddedFramework || isEmbeddedPlugin || name.endsWith(".dylib") || name.endsWith(".framework")) + t << "\t\t\t" << writeSettings("settings", "{ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }", SettingsNoQuote) << ";\n"; + t << "\t\t};\n"; } if (copyBundleResources && ((!osx && path.isEmpty()) || (osx && path == QLatin1String("Contents/Resources")))) { for (const ProString &s : qAsConst(bundle_files)) bundle_resources_files << s; + } else if (copyBundleResources && isEmbeddedFramework) { + for (const ProString &s : qAsConst(bundle_files)) + embedded_frameworks << s; + } else if (copyBundleResources && isEmbeddedPlugin) { + for (const ProString &s : qAsConst(bundle_files)) { + ProString subpath = (path == pluginsPrefix) ? ProString() : path.mid(pluginsPrefix.size() + 1); + embedded_plugins[subpath] << s; + } } else { QString phase_key = keyFor("QMAKE_PBX_BUNDLE_COPY." + bundle_data[i]); //if (!project->isActiveConfig("shallow_bundle") @@ -1169,6 +1186,35 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("name", grp) << ";\n" << "\t\t};\n"; + + QString grp2("Embed Frameworks"), key2 = keyFor(grp2); + project->values("QMAKE_PBX_BUILDPHASES").append(key2); + t << "\t\t" << key2 << " = {\n" + << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("dstPath", "") << ";\n" + << "\t\t\t" << writeSettings("dstSubfolderSpec", "10", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("files", embedded_frameworks, SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("name", grp2) << ";\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" + << "\t\t};\n"; + + QMapIterator it(embedded_plugins); + while (it.hasNext()) { + it.next(); + QString suffix = !it.key().isEmpty() ? (" (" + it.key() + ")") : QString(); + QString grp3("Embed PlugIns" + suffix), key3 = keyFor(grp3); + project->values("QMAKE_PBX_BUILDPHASES").append(key3); + t << "\t\t" << key3 << " = {\n" + << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("dstPath", it.key()) << ";\n" + << "\t\t\t" << writeSettings("dstSubfolderSpec", "13", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("files", it.value(), SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("name", grp3) << ";\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" + << "\t\t};\n"; + } } //REFERENCE -- cgit v1.2.3