From 86eb6974126b4fdf4cfa3340b7a80833479f2d37 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sat, 1 May 2021 21:10:11 +0200 Subject: Fix reading Xcode 12.5 specs Since Xcode 12.5, common specs for darwin platforms were moved to "Darwin Package/Product Types.xcspec" in the different folder. However, the old configs are still present, so we need to merge info from both variants. Also, allow to use undefined variables in .xcspec files - since 12.5, this is a valid use-case. Also, implement the "default=" variable formatter used as a fallback when variable is not set. Fixes: QBS-1644 Change-Id: I9a55c5d511cbb01f30219478ee9f3b85763a08d5 Reviewed-by: Christian Kandeler --- share/qbs/imports/qbs/DarwinTools/darwin-tools.js | 13 ++-- share/qbs/modules/bundle/BundleModule.qbs | 9 ++- share/qbs/modules/bundle/bundle.js | 80 +++++++++++++++------- .../bundle-structure/bundle-structure.qbs | 3 + .../testdata-apple/infoPlistVariables/Info.plist | 2 + tests/auto/blackbox/tst_blackboxapple.cpp | 2 + 6 files changed, 78 insertions(+), 31 deletions(-) diff --git a/share/qbs/imports/qbs/DarwinTools/darwin-tools.js b/share/qbs/imports/qbs/DarwinTools/darwin-tools.js index 0a944802d..f88f6ff52 100644 --- a/share/qbs/imports/qbs/DarwinTools/darwin-tools.js +++ b/share/qbs/imports/qbs/DarwinTools/darwin-tools.js @@ -212,10 +212,15 @@ var PropertyListVariableExpander = (function () { varValue = ""; } varValue = String(varValue); - if (varFormatter !== undefined) - varFormatter = varFormatter.toLowerCase(); - if (varFormatter === "rfc1034identifier") - varValue = Utilities.rfc1034Identifier(varValue); + if (varFormatter !== undefined) { + // TODO: XCode supports multiple formatters separated by a comma + var varFormatterLower = varFormatter.toLowerCase(); + if (varFormatterLower === "rfc1034identifier") + varValue = Utilities.rfc1034Identifier(varValue); + if (varValue === "" && varFormatterLower.startsWith("default=")) + varValue = varFormatter.split("=")[1]; + } + value = value.slice(0, i) + varValue + value.slice(j + repl.syntax.close.length); changes = true; repl = indexOfReplacementStart(syntaxes, value); diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs index 63f12db07..2568f3435 100644 --- a/share/qbs/modules/bundle/BundleModule.qbs +++ b/share/qbs/modules/bundle/BundleModule.qbs @@ -71,6 +71,9 @@ Module { "PRODUCT_NAME": product.targetName, "LOCAL_APPS_DIR": Environment.getEnv("HOME") + "/Applications", "LOCAL_LIBRARY_DIR": Environment.getEnv("HOME") + "/Library", + // actually, this is cpp.targetAbi, but XCode does not set it for non-simulator builds + // while Qbs set it to "macho". + "LLVM_TARGET_TRIPLE_SUFFIX": qbs.targetOS.contains("simulator") ? "-simulator" : "", "SWIFT_PLATFORM_TARGET_PREFIX": isMacOs ? "macos" : qbs.targetOS.contains("ios") ? "ios" : "", "TARGET_BUILD_DIR": product.buildDirectory, @@ -83,14 +86,14 @@ Module { property var productTypeIdentifierChain: [] configure: { - var specsPath = path; + var specsPaths = [path]; var specsSeparator = "-"; if (xcodeDeveloperPath && useXcodeBuildSpecs) { - specsPath = Bundle.macOSSpecsPath(xcodeVersion, xcodeDeveloperPath); + specsPaths = Bundle.macOSSpecsPaths(xcodeVersion, xcodeDeveloperPath); specsSeparator = " "; } - var reader = new Bundle.XcodeBuildSpecsReader(specsPath, + var reader = new Bundle.XcodeBuildSpecsReader(specsPaths, specsSeparator, additionalSettings, !isMacOs); diff --git a/share/qbs/modules/bundle/bundle.js b/share/qbs/modules/bundle/bundle.js index 6bb43ecdc..293f53225 100644 --- a/share/qbs/modules/bundle/bundle.js +++ b/share/qbs/modules/bundle/bundle.js @@ -28,6 +28,7 @@ ** ****************************************************************************/ +var File = require("qbs.File"); var FileInfo = require("qbs.FileInfo"); var DarwinTools = require("qbs.DarwinTools"); var ModUtils = require("qbs.ModUtils"); @@ -149,38 +150,69 @@ function _assign(target, source) { } } -function macOSSpecsPath(version, developerPath) { +function macOSSpecsPaths(version, developerPath) { + var result = []; + if (Utilities.versionCompare(version, "12.5") >= 0) { + result.push(FileInfo.joinPaths( + developerPath, "..", "PlugIns", "XCBSpecifications.ideplugin", + "Contents", "Resources")); + } + if (Utilities.versionCompare(version, "12") >= 0) { - return FileInfo.joinPaths( + result.push(FileInfo.joinPaths( developerPath, "Platforms", "MacOSX.platform", "Developer", "Library", "Xcode", - "PrivatePlugIns", "IDEOSXSupportCore.ideplugin", "Contents", "Resources"); + "PrivatePlugIns", "IDEOSXSupportCore.ideplugin", "Contents", "Resources")); + } else { + result.push(FileInfo.joinPaths( + developerPath, "Platforms", "MacOSX.platform", "Developer", "Library", "Xcode", + "Specifications")); } - return FileInfo.joinPaths( - developerPath, "Platforms", "MacOSX.platform", "Developer", "Library", "Xcode", - "Specifications"); + return result; } var XcodeBuildSpecsReader = (function () { - function XcodeBuildSpecsReader(specsPath, separator, additionalSettings, useShallowBundles) { + function XcodeBuildSpecsReader(specsPaths, separator, additionalSettings, useShallowBundles) { this._additionalSettings = additionalSettings; this._useShallowBundles = useShallowBundles; - var i; - var plist = new PropertyList2(); - var plist2 = new PropertyList2(); - try { - plist.readFromFile(specsPath + ["/MacOSX", "Package", "Types.xcspec"].join(separator)); - plist2.readFromFile(specsPath + ["/MacOSX", "Product", "Types.xcspec"].join(separator)); - this._packageTypes = plist.toObject(); - this._productTypes = plist2.toObject(); - this._types = {}; - for (i = 0; i < this._packageTypes.length; ++i) - this._types[this._packageTypes[i]["Identifier"]] = this._packageTypes[i]; - for (i = 0; i < this._productTypes.length; ++i) - this._types[this._productTypes[i]["Identifier"]] = this._productTypes[i]; - } finally { - plist.clear(); - plist2.clear(); + + this._packageTypes = []; + this._productTypes = []; + + var i, j; + for (i = 0; i < specsPaths.length; ++i) { + var specsPath = specsPaths[i]; + var names = ["Darwin", "MacOSX"]; + for (j = 0; j < names.length; ++j) { + var name = names[j]; + var plist = new PropertyList2(); + var plist2 = new PropertyList2(); + try + { + var plistName = [name, "Package", "Types.xcspec"].join(separator); + var plistName2 = [name, "Product", "Types.xcspec"].join(separator); + var plistPath = FileInfo.joinPaths(specsPath, plistName); + var plistPath2 = FileInfo.joinPaths(specsPath, plistName2); + if (File.exists(plistPath)) { + plist.readFromFile(plistPath); + this._packageTypes = this._packageTypes.concat(plist.toObject()); + } + if (File.exists(plistPath2)) { + plist2.readFromFile(plistPath2); + this._productTypes = this._productTypes.concat(plist2.toObject()); + } + } finally { + plist.clear(); + plist2.clear(); + } + } } + + this._types = {}; + for (i = 0; i < this._packageTypes.length; ++i) + this._types[this._packageTypes[i]["Identifier"]] = this._packageTypes[i]; + for (i = 0; i < this._productTypes.length; ++i) + this._types[this._productTypes[i]["Identifier"]] = this._productTypes[i]; + } XcodeBuildSpecsReader.prototype.productTypeIdentifierChain = function (typeIdentifier) { var ids = [typeIdentifier]; @@ -291,7 +323,7 @@ var XcodeBuildSpecsReader = (function () { var original; while (original !== setting) { original = setting; - setting = DarwinTools.expandPlistEnvironmentVariables({ key: setting }, obj, true)["key"]; + setting = DarwinTools.expandPlistEnvironmentVariables({ key: setting }, obj, false)["key"]; } return setting; } diff --git a/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs b/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs index db5f15b18..705f054a8 100644 --- a/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs +++ b/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs @@ -134,6 +134,9 @@ Project { name: "G" bundle.isBundle: true bundle.resources: ["resource.txt"] + // XCode 12.5 does not support com.apple.product-type.in-app-purchase-content type anymore, + // so use older specs from Qbs + bundle._useXcodeBuildSpecs: false Group { fileTagsFilter: product.type.concat(project.bundleFileTags) qbs.install: true diff --git a/tests/auto/blackbox/testdata-apple/infoPlistVariables/Info.plist b/tests/auto/blackbox/testdata-apple/infoPlistVariables/Info.plist index b357378ac..cb879d70c 100644 --- a/tests/auto/blackbox/testdata-apple/infoPlistVariables/Info.plist +++ b/tests/auto/blackbox/testdata-apple/infoPlistVariables/Info.plist @@ -18,5 +18,7 @@ ${${EXE}_NAME} BracesNested ${${EXE}_NAME} + WithDefault + ${NON_EXISTING:default=DEFAULT} diff --git a/tests/auto/blackbox/tst_blackboxapple.cpp b/tests/auto/blackbox/tst_blackboxapple.cpp index 884d2c077..8c9792211 100644 --- a/tests/auto/blackbox/tst_blackboxapple.cpp +++ b/tests/auto/blackbox/tst_blackboxapple.cpp @@ -1069,6 +1069,8 @@ void TestBlackboxApple::infoPlistVariables() QStringLiteral("infoPlistVariables")); QCOMPARE(content.value(QStringLiteral("BracesNested")), QStringLiteral("infoPlistVariables")); + QCOMPARE(content.value(QStringLiteral("WithDefault")), + QStringLiteral("DEFAULT")); } void TestBlackboxApple::objcArc() -- cgit v1.2.3