aboutsummaryrefslogtreecommitdiffstats
path: root/share/qbs
diff options
context:
space:
mode:
Diffstat (limited to 'share/qbs')
-rw-r--r--share/qbs/imports/qbs/DarwinTools/darwin-tools.js16
-rw-r--r--share/qbs/imports/qbs/ModUtils/utils.js4
-rw-r--r--share/qbs/imports/qbs/Probes/XcodeProbe.qbs3
-rw-r--r--share/qbs/imports/qbs/Probes/path-probe.js4
-rw-r--r--share/qbs/module-providers/Qt/templates/android_support.qbs14
-rw-r--r--share/qbs/module-providers/Qt/templates/dbus.js1
-rw-r--r--share/qbs/module-providers/Qt/templates/plugin_support.qbs2
-rw-r--r--share/qbs/module-providers/Qt/templates/quick.js6
-rw-r--r--share/qbs/module-providers/Qt/templates/quick.qbs4
-rw-r--r--share/qbs/modules/Android/sdk/sdk.qbs4
-rw-r--r--share/qbs/modules/Android/sdk/utils.js2
-rw-r--r--share/qbs/modules/Exporter/pkgconfig/pkgconfig.js8
-rw-r--r--share/qbs/modules/Exporter/qbs/qbsexporter.js6
-rw-r--r--share/qbs/modules/bundle/BundleModule.qbs71
-rw-r--r--share/qbs/modules/bundle/bundle.js2
-rw-r--r--share/qbs/modules/codesign/CodeSignModule.qbs45
-rw-r--r--share/qbs/modules/codesign/apple.qbs385
-rw-r--r--share/qbs/modules/codesign/codesign.js279
-rw-r--r--share/qbs/modules/codesign/noop.qbs37
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs6
-rw-r--r--share/qbs/modules/cpp/DarwinGCC.qbs2
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs23
-rw-r--r--share/qbs/modules/cpp/gcc.js36
-rw-r--r--share/qbs/modules/cpp/iar.js505
-rw-r--r--share/qbs/modules/cpp/iar.qbs3
-rw-r--r--share/qbs/modules/cpp/keil.js2
-rw-r--r--share/qbs/modules/cpp/keil.qbs3
-rw-r--r--share/qbs/modules/cpp/msvc.js2
-rw-r--r--share/qbs/modules/cpp/sdcc.js13
-rw-r--r--share/qbs/modules/cpp/sdcc.qbs3
-rw-r--r--share/qbs/modules/cpp/windows-msvc-base.qbs1
-rw-r--r--share/qbs/modules/ico/ico.js1
-rw-r--r--share/qbs/modules/java/JavaModule.qbs2
-rw-r--r--share/qbs/modules/protobuf/cpp/protobufcpp.qbs19
-rw-r--r--share/qbs/modules/xcode/xcode.js21
-rw-r--r--share/qbs/modules/xcode/xcode.qbs272
36 files changed, 1225 insertions, 582 deletions
diff --git a/share/qbs/imports/qbs/DarwinTools/darwin-tools.js b/share/qbs/imports/qbs/DarwinTools/darwin-tools.js
index 9b81310f0..0a944802d 100644
--- a/share/qbs/imports/qbs/DarwinTools/darwin-tools.js
+++ b/share/qbs/imports/qbs/DarwinTools/darwin-tools.js
@@ -260,19 +260,3 @@ function cleanPropertyList(plist) {
cleanPropertyList(plist[key]);
}
}
-
-function _codeSignTimestampFlags(product) {
- // If signingTimestamp is undefined, do not specify the flag at all -
- // this uses the system-specific default behavior
- var signingTimestamp = product.moduleProperty("xcode", "signingTimestamp");
- if (signingTimestamp !== undefined) {
- // If signingTimestamp is an empty string, specify the flag but do
- // not specify a value - this uses a default Apple-provided server
- var flag = "--timestamp";
- if (signingTimestamp)
- flag += "=" + signingTimestamp;
- return [flag];
- }
-
- return [];
-}
diff --git a/share/qbs/imports/qbs/ModUtils/utils.js b/share/qbs/imports/qbs/ModUtils/utils.js
index 586564d73..0433fa46e 100644
--- a/share/qbs/imports/qbs/ModUtils/utils.js
+++ b/share/qbs/imports/qbs/ModUtils/utils.js
@@ -48,7 +48,7 @@ function mergeCFiles(inputs, outputFilePath)
}
function sanitizedList(list, product, fullPropertyName) {
- if (!Array.isArray(list))
+ if (!(list instanceof Array))
return list;
var filterFunc = function(elem) {
if (typeof elem === "string" && elem.length === 0) {
@@ -588,6 +588,8 @@ function guessArchitecture(m) {
architecture = "sh";
} else if (hasAnyOf(m, ["__CR16__"])) {
architecture = "cr16";
+ } else if (hasAnyOf(m, ["__mc68hc1x__", "__mc68hc1x"])) {
+ architecture = "hcs12";
}
}
diff --git a/share/qbs/imports/qbs/Probes/XcodeProbe.qbs b/share/qbs/imports/qbs/Probes/XcodeProbe.qbs
index e0ed99346..edd67433b 100644
--- a/share/qbs/imports/qbs/Probes/XcodeProbe.qbs
+++ b/share/qbs/imports/qbs/Probes/XcodeProbe.qbs
@@ -48,6 +48,7 @@ Probe {
// Outputs
property var architectureSettings
property var availableSdks
+ property var platformSettings
property string xcodeVersion
configure: {
@@ -97,6 +98,8 @@ Probe {
});
availableSdks = Xcode.sdkInfoList(sdksPath);
+ var platformInfoPlist = FileInfo.joinPaths(platformPath, "Info.plist");
+ platformSettings = Xcode.platformInfo(platformInfoPlist);
found = !!xcodeVersion;
}
}
diff --git a/share/qbs/imports/qbs/Probes/path-probe.js b/share/qbs/imports/qbs/Probes/path-probe.js
index b1bdf9930..1f55dcf32 100644
--- a/share/qbs/imports/qbs/Probes/path-probe.js
+++ b/share/qbs/imports/qbs/Probes/path-probe.js
@@ -36,7 +36,7 @@ var ModUtils = require("qbs.ModUtils");
function asStringList(key, value) {
if (typeof(value) === "string")
return [value];
- if (Array.isArray(value))
+ if (value instanceof Array)
return value;
throw key + " must be a string or a stringList";
}
@@ -45,7 +45,7 @@ function canonicalSelectors(selectors, nameSuffixes) {
var mapper = function(selector) {
if (typeof(selector) === "string")
return {names : [selector]};
- if (Array.isArray(selector))
+ if (selector instanceof Array)
return {names : selector};
// dict
if (!selector.names)
diff --git a/share/qbs/module-providers/Qt/templates/android_support.qbs b/share/qbs/module-providers/Qt/templates/android_support.qbs
index 3790037f3..87c980448 100644
--- a/share/qbs/module-providers/Qt/templates/android_support.qbs
+++ b/share/qbs/module-providers/Qt/templates/android_support.qbs
@@ -38,7 +38,7 @@ Module {
Depends { name: "Android.sdk"; condition: _enableSdkSupport }
Depends { name: "Android.ndk"; condition: _enableNdkSupport }
Depends { name: "java"; condition: _enableSdkSupport }
- Depends { name: "cpp" }
+ Depends { name: "cpp"; condition: _enableNdkSupport }
Properties {
condition: _enableNdkSupport && qbs.toolchain.contains("clang")
@@ -62,8 +62,10 @@ Module {
condition: _enableSdkSupport && Utilities.versionCompare(version, "6.0") >= 0
java.additionalClassPaths: [FileInfo.joinPaths(_qtInstallDir, "jar", "Qt6Android.jar")]
}
+ // "ANDROID_HAS_WSTRING" was removed from qtcore qstring.h in Qt 5.14.0
Properties {
- condition: _enableNdkSupport && (Android.ndk.abi === "armeabi-v7a" || Android.ndk.abi === "x86")
+ condition: _enableNdkSupport && Utilities.versionCompare(version, "5.14.0") < 0 &&
+ (Android.ndk.abi === "armeabi-v7a" || Android.ndk.abi === "x86")
cpp.defines: "ANDROID_HAS_WSTRING"
}
Properties {
@@ -78,7 +80,11 @@ Module {
condition: _enableSdkSupport && Utilities.versionCompare(version, "6.0") >= 0
Android.sdk.minimumVersion: "23"
}
- cpp.archSuffix: _multiAbi ? "_" + Android.ndk.abi : ""
+
+ Properties {
+ condition: _enableNdkSupport
+ cpp.archSuffix: _multiAbi ? "_" + Android.ndk.abi : ""
+ }
Rule {
condition: _enableSdkSupport
@@ -191,7 +197,7 @@ Module {
var prefixDirs = product.Qt.android_support.extraPrefixDirs;
if (prefixDirs && prefixDirs.length > 0)
f.writeLine('"extraPrefixDirs": ' + JSON.stringify(prefixDirs) + ',');
- if (Array.isArray(product.qmlImportPaths) && product.qmlImportPaths.length > 0)
+ if ((product.qmlImportPaths instanceof Array) && product.qmlImportPaths.length > 0)
f.writeLine('"qml-import-paths": "' + product.qmlImportPaths.join(',') + '",');
if (Utilities.versionCompare(product.Qt.android_support.version, "6.0") >= 0) {
diff --git a/share/qbs/module-providers/Qt/templates/dbus.js b/share/qbs/module-providers/Qt/templates/dbus.js
index 0674bf684..3cdd6fb90 100644
--- a/share/qbs/module-providers/Qt/templates/dbus.js
+++ b/share/qbs/module-providers/Qt/templates/dbus.js
@@ -29,6 +29,7 @@
****************************************************************************/
var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
function outputFileName(input, suffix)
{
diff --git a/share/qbs/module-providers/Qt/templates/plugin_support.qbs b/share/qbs/module-providers/Qt/templates/plugin_support.qbs
index 1de923f17..19a739589 100644
--- a/share/qbs/module-providers/Qt/templates/plugin_support.qbs
+++ b/share/qbs/module-providers/Qt/templates/plugin_support.qbs
@@ -32,7 +32,7 @@ Module {
newValue = [];
else if (typeof newValue == "string")
newValue = [newValue];
- if (!Array.isArray(newValue))
+ if (!newValue instanceof Array)
throw "Invalid value '" + newValue + "' in Qt.plugin_support.pluginsByType";
eppt[pluginType] = (eppt[pluginType] || []).uniqueConcat(newValue);
}
diff --git a/share/qbs/module-providers/Qt/templates/quick.js b/share/qbs/module-providers/Qt/templates/quick.js
index 4f3da2fb0..76f2e9e53 100644
--- a/share/qbs/module-providers/Qt/templates/quick.js
+++ b/share/qbs/module-providers/Qt/templates/quick.js
@@ -31,7 +31,7 @@
var FileInfo = require("qbs.FileInfo");
var Process = require("qbs.Process");
-function scanQrc(qrcFilePath) {
+function scanQrc(product, qrcFilePath) {
var absInputDir = FileInfo.path(qrcFilePath);
var result = [];
var process = new Process();
@@ -65,8 +65,8 @@ function qtQuickResourceFileOutputName(fileName) {
return fileName.replace(/\.qrc$/, "_qtquickcompiler.qrc");
}
-function contentFromQrc(qrcFilePath) {
- var filesInQrc = scanQrc(qrcFilePath);
+function contentFromQrc(product, qrcFilePath) {
+ var filesInQrc = scanQrc(product, qrcFilePath);
var qmlJsFiles = filesInQrc.filter(function (filePath) {
return (/\.(js|qml)$/).test(filePath);
} );
diff --git a/share/qbs/module-providers/Qt/templates/quick.qbs b/share/qbs/module-providers/Qt/templates/quick.qbs
index bf04fe869..ac3ab5b26 100644
--- a/share/qbs/module-providers/Qt/templates/quick.qbs
+++ b/share/qbs/module-providers/Qt/templates/quick.qbs
@@ -79,7 +79,7 @@ QtModule {
condition: useCompiler
inputs: 'qt.quick.qrc'
searchPaths: [FileInfo.path(input.filePath)]
- scan: QC.scanQrc(input.filePath)
+ scan: QC.scanQrc(product, input.filePath)
}
FileTagger {
@@ -100,7 +100,7 @@ QtModule {
var cmd = new JavaScriptCommand();
cmd.silent = true;
cmd.sourceCode = function() {
- var content = QC.contentFromQrc(input.filePath);
+ var content = QC.contentFromQrc(product, input.filePath);
content.qrcFilePath = input.filePath;
var tf = new TextFile(output.filePath, TextFile.WriteOnly);
diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs
index f0e727caf..0e40d059b 100644
--- a/share/qbs/modules/Android/sdk/sdk.qbs
+++ b/share/qbs/modules/Android/sdk/sdk.qbs
@@ -273,7 +273,7 @@ Module {
for (var i = 0; i < (aidlSearchPaths ? aidlSearchPaths.length : 0); ++i)
args.push("-I" + aidlSearchPaths[i]);
args.push(input.filePath, output.filePath);
- cmd = new Command(aidl, args);
+ var cmd = new Command(aidl, args);
cmd.description = "Processing " + input.fileName;
return [cmd];
}
@@ -498,7 +498,7 @@ Module {
outputArtifacts: {
var deploymentData = SdkUtils.stlDeploymentData(product, inputs, "stl");
var outputs = [];
- for (i = 0; i < deploymentData.outputFilePaths.length; ++i) {
+ for (var i = 0; i < deploymentData.outputFilePaths.length; ++i) {
outputs.push({filePath: deploymentData.outputFilePaths[i],
fileTags: "android.stl_deployed"});
}
diff --git a/share/qbs/modules/Android/sdk/utils.js b/share/qbs/modules/Android/sdk/utils.js
index 63bf1f5c4..6fa200822 100644
--- a/share/qbs/modules/Android/sdk/utils.js
+++ b/share/qbs/modules/Android/sdk/utils.js
@@ -30,9 +30,11 @@
var File = require("qbs.File");
var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
var Process = require("qbs.Process");
var TextFile = require("qbs.TextFile");
var Utilities = require("qbs.Utilities");
+var Xml = require("qbs.Xml");
function availableBuildToolsVersions(sdkDir) {
var re = /^([0-9]+)\.([0-9]+)\.([0-9]+)$/;
diff --git a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js
index a3109d61d..52b4dffe3 100644
--- a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js
+++ b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js
@@ -44,9 +44,9 @@ function writeEntry(product, file, key, propertyName, required, additionalValues
var value = product.Exporter.pkgconfig[propertyName];
if (additionalValues && additionalValues.length > 0)
value = (value || []).concat(additionalValues);
- var valueIsNotEmpty = value && (!Array.isArray(value) || value.length > 0);
+ var valueIsNotEmpty = value && (!(value instanceof Array) || value.length > 0);
if (valueIsNotEmpty) {
- if (Array.isArray(value))
+ if (value instanceof Array)
value = value.join(' ');
file.writeLine(key + ": " + value);
} else if (required) {
@@ -83,7 +83,7 @@ function collectAutodetectedData(topLevelProduct)
|| (value.length > installPrefix.length && value[installPrefix.length] !== '/')) {
return quotedValue;
}
- return quotedValue.replace(product.qbs.installPrefix, "${prefix}");
+ return quotedValue.replace(topLevelProduct.qbs.installPrefix, "${prefix}");
}
function transformedValue(product, moduleName, propertyName)
@@ -92,7 +92,7 @@ function collectAutodetectedData(topLevelProduct)
var value = transformFunc
? eval("(" + transformFunc + ")(product, moduleName, propertyName, originalValue)")
: originalValue;
- if (Array.isArray(value))
+ if (value instanceof Array)
value.forEach(function(v, i, a) { a[i] = quoteAndPrefixify(v); });
else if (value)
value = quoteAndPrefixify(value);
diff --git a/share/qbs/modules/Exporter/qbs/qbsexporter.js b/share/qbs/modules/Exporter/qbs/qbsexporter.js
index 015ed4418..be46372c3 100644
--- a/share/qbs/modules/Exporter/qbs/qbsexporter.js
+++ b/share/qbs/modules/Exporter/qbs/qbsexporter.js
@@ -113,7 +113,7 @@ function checkValuePrefix(name, value, forbiddenPrefix, prefixDescription)
function stringifyValue(project, product, moduleInstallDir, prop, value)
{
- if (Array.isArray(value)) {
+ if (value instanceof Array) {
var repr = "[";
for (var i = 0; i < value.length; ++i) {
repr += stringifyValue(project, product, moduleInstallDir, prop, value[i]) + ", ";
@@ -267,6 +267,6 @@ function writeImportStatements(product, moduleFile)
if (!imports.contains("import qbs.FileInfo"))
imports.push("import qbs.FileInfo");
- for (var i = 0; i < product.exports.imports.length; ++i)
- moduleFile.writeLine(product.exports.imports[i]);
+ for (var i = 0; i < imports.length; ++i)
+ moduleFile.writeLine(imports[i]);
}
diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs
index 05e77c81b..63f12db07 100644
--- a/share/qbs/modules/bundle/BundleModule.qbs
+++ b/share/qbs/modules/bundle/BundleModule.qbs
@@ -38,9 +38,11 @@ import qbs.PropertyList
import qbs.TextFile
import qbs.Utilities
import "bundle.js" as Bundle
+import "../codesign/codesign.js" as Codesign
Module {
Depends { name: "xcode"; required: false; }
+ Depends { name: "codesign"; required: false; }
Probe {
id: bundleSettingsProbe
@@ -510,9 +512,9 @@ Module {
multiplex: true
inputs: ["bundle.input",
"aggregate_infoplist", "pkginfo", "hpp",
- "icns", "xcent",
+ "icns", "codesign.xcent",
"compiled_ibdoc", "compiled_assetcatalog",
- "xcode.provisioningprofile.main"]
+ "codesign.embedded_provisioningprofile"]
// Make sure the inputs of this rule are only those rules which produce outputs compatible
// with the type of the bundle being produced.
@@ -540,13 +542,13 @@ Module {
});
}
- for (i in inputs["xcode.provisioningprofile.main"]) {
- var ext = inputs["xcode.provisioningprofile.main"][i].fileName.split('.')[1];
+ var provprofiles = inputs["codesign.embedded_provisioningprofile"];
+ for (i in provprofiles) {
artifacts.push({
filePath: FileInfo.joinPaths(product.destinationDirectory,
ModUtils.moduleProperty(product,
"contentsFolderPath"),
- "embedded." + ext),
+ provprofiles[i].fileName),
fileTags: ["bundle.provisioningprofile", "bundle.content"]
});
}
@@ -613,8 +615,8 @@ Module {
for (var i = 0; i < artifacts.length; ++i)
artifacts[i].bundle = { wrapperPath: wrapperPath };
- if (product.qbs.hostOS.contains("darwin") && product.xcode
- && product.xcode.signingIdentity) {
+ if (product.qbs.hostOS.contains("darwin") && product.codesign
+ && product.codesign.enableCodeSigning) {
artifacts.push({
filePath: FileInfo.joinPaths(product.bundle.contentsFolderPath, "_CodeSignature/CodeResources"),
fileTags: ["bundle.code-signature", "bundle.content"]
@@ -706,18 +708,21 @@ Module {
commands.push(cmd);
}
- var provisioningProfiles = outputs["bundle.provisioningprofile"];
- for (i in provisioningProfiles) {
- cmd = new JavaScriptCommand();
- cmd.description = "copying provisioning profile";
- cmd.highlight = "filegen";
- cmd.source = inputs["xcode.provisioningprofile.main"][i].filePath;
- cmd.destination = provisioningProfiles[i].filePath;
- cmd.sourceCode = function() {
- File.copy(source, destination);
- };
+ cmd = new JavaScriptCommand();
+ cmd.description = "copying provisioning profile";
+ cmd.highlight = "filegen";
+ cmd.sources = (inputs["codesign.embedded_provisioningprofile"] || [])
+ .map(function(artifact) { return artifact.filePath; });
+ cmd.destination = (outputs["bundle.provisioningprofile"] || [])
+ .map(function(artifact) { return artifact.filePath; });
+ cmd.sourceCode = function() {
+ var i;
+ for (var i in sources) {
+ File.copy(sources[i], destination[i]);
+ }
+ };
+ if (cmd.sources && cmd.sources.length)
commands.push(cmd);
- }
cmd = new JavaScriptCommand();
cmd.description = "copying public headers";
@@ -762,34 +767,8 @@ Module {
commands.push(cmd);
if (product.moduleProperty("qbs", "hostOS").contains("darwin")) {
- var actualSigningIdentity = product.moduleProperty("xcode", "actualSigningIdentity");
- var codesignDisplayName = product.moduleProperty("xcode", "actualSigningIdentityDisplayName");
- if (actualSigningIdentity) {
- var args = product.moduleProperty("xcode", "codesignFlags") || [];
- args.push("--force");
- args.push("--sign", actualSigningIdentity);
- args = args.concat(DarwinTools._codeSignTimestampFlags(product));
-
- for (var j in inputs.xcent) {
- args.push("--entitlements", inputs.xcent[j].filePath);
- break; // there should only be one
- }
-
- // If this is a framework, we need to sign its versioned directory
- if (bundleType === "framework") {
- args.push(product.bundle.contentsFolderPath);
- } else {
- args.push(product.bundle.bundleName);
- }
-
- cmd = new Command(product.moduleProperty("xcode", "codesignPath"), args);
- cmd.workingDirectory = product.destinationDirectory;
- cmd.description = "codesign "
- + ModUtils.moduleProperty(product, "bundleName")
- + " using " + codesignDisplayName
- + " (" + actualSigningIdentity + ")";
- commands.push(cmd);
- }
+ Array.prototype.push.apply(commands, Codesign.prepareSign(
+ project, product, inputs, outputs, input, output));
if (bundleType === "application"
&& product.moduleProperty("qbs", "targetOS").contains("macos")) {
diff --git a/share/qbs/modules/bundle/bundle.js b/share/qbs/modules/bundle/bundle.js
index 6d9305702..6bb43ecdc 100644
--- a/share/qbs/modules/bundle/bundle.js
+++ b/share/qbs/modules/bundle/bundle.js
@@ -89,7 +89,7 @@ function productTypeIdentifier(productType) {
}
function excludedAuxiliaryInputs(project, product) {
- var chain = product.moduleProperty("bundle", "_productTypeIdentifierChain");
+ var chain = product.bundle._productTypeIdentifierChain;
var bestPossibleType;
for (var i = chain.length - 1; i >= 0; --i) {
switch (chain[i]) {
diff --git a/share/qbs/modules/codesign/CodeSignModule.qbs b/share/qbs/modules/codesign/CodeSignModule.qbs
new file mode 100644
index 000000000..caa9e2e60
--- /dev/null
+++ b/share/qbs/modules/codesign/CodeSignModule.qbs
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2021 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs
+import qbs.File
+import qbs.FileInfo
+import "codesign.js" as CodeSign
+
+Module {
+ condition: false
+
+ property bool enableCodeSigning: false
+
+ property string codesignName
+ property string codesignPath: codesignName
+ property stringList codesignFlags
+}
diff --git a/share/qbs/modules/codesign/apple.qbs b/share/qbs/modules/codesign/apple.qbs
new file mode 100644
index 000000000..dbcd0a215
--- /dev/null
+++ b/share/qbs/modules/codesign/apple.qbs
@@ -0,0 +1,385 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2021 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs
+import qbs.BundleTools
+import qbs.DarwinTools
+import qbs.Environment
+import qbs.File
+import qbs.FileInfo
+import qbs.ModUtils
+import qbs.PropertyList
+import qbs.Probes
+import qbs.Utilities
+import "codesign.js" as CodeSign
+import "../xcode/xcode.js" as XcodeUtils
+
+CodeSignModule {
+ Depends { name: "xcode"; required: qbs.toolchain && qbs.toolchain.contains("xcode") }
+
+ Probes.BinaryProbe {
+ id: codesignProbe
+ names: [codesignName]
+ }
+
+ condition: qbs.hostOS.contains("macos") && qbs.targetOS.contains("darwin")
+ priority: 0
+
+ enableCodeSigning: _codeSigningRequired
+
+ codesignName: "codesign"
+ codesignPath: codesignProbe.filePath
+
+ property string signingType: {
+ if (_adHocCodeSigningAllowed)
+ return "ad-hoc";
+ if (_codeSigningAllowed)
+ return "app-store";
+ }
+
+ PropertyOptions {
+ name: "signingType"
+ allowedValues: ["app-store", "apple-id", "ad-hoc"]
+ }
+
+ property string signingIdentity: {
+ if (signingType === "ad-hoc") // only useful on macOS
+ return "-";
+
+ var isDebug = qbs.buildVariant !== "release";
+
+ if (qbs.targetOS.contains("ios") || qbs.targetOS.contains("tvos")
+ || qbs.targetOS.contains("watchos")) {
+ switch (signingType) {
+ case "app-store":
+ return isDebug ? "iPhone Developer" : "iPhone Distribution";
+ }
+ }
+
+ if (qbs.targetOS.contains("macos")) {
+ switch (signingType) {
+ case "app-store":
+ return isDebug ? "Mac Developer" : "3rd Party Mac Developer Application";
+ case "apple-id":
+ return "Developer ID Application";
+ }
+ }
+ }
+
+ property string signingTimestamp: "none"
+
+ property string provisioningProfile
+ PropertyOptions {
+ name: "provisioningProfile"
+ description: "Name or UUID of the provisioning profile to embed in the application; " +
+ "typically left blank to allow automatic provisioning"
+ }
+
+ property string teamIdentifier
+ PropertyOptions {
+ name: "teamIdentifier"
+ description: "Name or identifier of the development team whose identities will be used; " +
+ "typically left blank unless signed into multiple development teams"
+ }
+
+ property path provisioningProfilesPath: "~/Library/MobileDevice/Provisioning Profiles"
+
+ readonly property var _actualSigningIdentity: {
+ if (signingIdentity === "-") {
+ return {
+ SHA1: signingIdentity,
+ subjectInfo: { CN: "ad hoc" }
+ }
+ }
+
+ var identities = CodeSign.findSigningIdentities(signingIdentity, teamIdentifier);
+ if (identities && Object.keys(identities).length > 1) {
+ throw "Multiple codesigning identities (i.e. certificate and private key pairs) " +
+ "matching “" + signingIdentity + "” were found." +
+ CodeSign.humanReadableIdentitySummary(identities);
+ }
+
+ for (var i in identities)
+ return identities[i];
+ }
+
+ // Allowed for macOS
+ readonly property bool _adHocCodeSigningAllowed:
+ XcodeUtils.boolFromSdkOrPlatform("AD_HOC_CODE_SIGNING_ALLOWED",
+ xcode._sdkProps, xcode._platformProps, true)
+
+ // Allowed for all device platforms (not simulators)
+ readonly property bool _codeSigningAllowed:
+ XcodeUtils.boolFromSdkOrPlatform("CODE_SIGNING_ALLOWED",
+ xcode._sdkProps, xcode._platformProps, true)
+
+ // Required for tvOS, iOS, and watchOS (not simulators)
+ property bool _codeSigningRequired: {
+ // allow to override value from Xcode so tests do not require signing
+ var envRequired = Environment.getEnv("QBS_AUTOTEST_CODE_SIGNING_REQUIRED");
+ if (envRequired)
+ return envRequired === "1";
+ return XcodeUtils.boolFromSdkOrPlatform("CODE_SIGNING_REQUIRED",
+ xcode._sdkProps, xcode._platformProps, false)
+ }
+
+ // Required for tvOS, iOS, and watchOS (not simulators)
+ readonly property bool _entitlementsRequired:
+ XcodeUtils.boolFromSdkOrPlatform("ENTITLEMENTS_REQUIRED",
+ xcode._sdkProps, xcode._platformProps, false)
+
+ readonly property bool _provisioningProfileAllowed:
+ product.bundle
+ && product.bundle.isBundle
+ && product.type.contains("application")
+ && xcode.platformType !== "simulator"
+
+ // Required for tvOS, iOS, and watchOS (not simulators)
+ // PROVISIONING_PROFILE_REQUIRED is specified only in Embedded-Device.xcspec in the
+ // IDEiOSSupportCore IDE plugin, so we'll just write out the logic here manually
+ readonly property bool _provisioningProfileRequired:
+ _provisioningProfileAllowed && !qbs.targetOS.contains("macos")
+
+ // Not used on simulator platforms either but provisioning profiles aren't used there anyways
+ readonly property string _provisioningProfilePlatform: {
+ if (qbs.targetOS.contains("macos"))
+ return "OSX";
+ if (qbs.targetOS.contains("ios") || qbs.targetOS.contains("watchos"))
+ return "iOS";
+ if (qbs.targetOS.contains("tvos"))
+ return "tvOS";
+ }
+
+ readonly property string _embeddedProfileName:
+ (xcode._platformProps || {})["EMBEDDED_PROFILE_NAME"]
+
+ setupBuildEnvironment: {
+ var prefixes = product.xcode ? [
+ product.xcode.platformPath + "/Developer",
+ product.xcode.toolchainPath,
+ product.xcode.developerPath
+ ] : [];
+ for (var i = 0; i < prefixes.length; ++i) {
+ var codesign_allocate = prefixes[i] + "/usr/bin/codesign_allocate";
+ if (File.exists(codesign_allocate)) {
+ var v = new ModUtils.EnvironmentVariable("CODESIGN_ALLOCATE");
+ v.value = codesign_allocate;
+ v.set();
+ break;
+ }
+ }
+ }
+
+ Group {
+ name: "Provisioning Profiles"
+ prefix: codesign.provisioningProfilesPath + "/"
+ files: ["*.mobileprovision", "*.provisionprofile"]
+ }
+
+ FileTagger {
+ fileTags: ["codesign.entitlements"]
+ patterns: ["*.entitlements"]
+ }
+
+ FileTagger {
+ fileTags: ["codesign.provisioningprofile"]
+ patterns: ["*.mobileprovision", "*.provisionprofile"]
+ }
+
+ Rule {
+ multiplex: true
+ condition: product.codesign.enableCodeSigning &&
+ product.codesign._provisioningProfileAllowed
+ inputs: ["codesign.provisioningprofile"]
+
+ outputFileTags: ["codesign.embedded_provisioningprofile"]
+ outputArtifacts: {
+ var artifacts = [];
+ var provisioningProfiles = (inputs["codesign.provisioningprofile"] || [])
+ .map(function (a) { return a.filePath; });
+ var bestProfile = CodeSign.findBestProvisioningProfile(product, provisioningProfiles);
+ var uuid = product.provisioningProfile;
+ if (bestProfile) {
+ artifacts.push({
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ product.codesign._embeddedProfileName),
+ fileTags: ["codesign.embedded_provisioningprofile"],
+ codesign: {
+ _provisioningProfileFilePath: bestProfile.filePath,
+ _provisioningProfileData: JSON.stringify(bestProfile.data),
+ }
+ });
+ } else if (uuid) {
+ throw "Your build settings specify a provisioning profile with the UUID “"
+ + uuid + "”, however, no such provisioning profile was found.";
+ } else if (product._provisioningProfileRequired) {
+ var hasProfiles = !!((inputs["codesign.provisioningprofile"] || []).length);
+ var teamIdentifier = product.teamIdentifier;
+ var codeSignIdentity = product.signingIdentity;
+ if (hasProfiles) {
+ if (codeSignIdentity) {
+ console.warn("No provisioning profiles matching the bundle identifier “"
+ + product.bundle.identifier
+ + "” were found.");
+ } else {
+ console.warn("No provisioning profiles matching an applicable signing "
+ + "identity were found.");
+ }
+ } else {
+ if (codeSignIdentity) {
+ if (teamIdentifier) {
+ console.warn("No provisioning profiles with a valid signing identity "
+ + "(i.e. certificate and private key pair) matching the "
+ + "team ID “" + teamIdentifier + "” were found.")
+ } else {
+ console.warn("No provisioning profiles with a valid signing identity "
+ + "(i.e. certificate and private key pair) were found.");
+ }
+ } else {
+ console.warn("No non–expired provisioning profiles were found.");
+ }
+ }
+ }
+ return artifacts;
+ }
+
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ var data = JSON.parse(output.codesign._provisioningProfileData);
+ cmd.source = output.codesign._provisioningProfileFilePath;
+ cmd.destination = output.filePath;
+ cmd.description = "using provisioning profile " + data.Name + " (" + data.UUID + ")";
+ cmd.highlight = "filegen";
+ cmd.sourceCode = function() {
+ File.copy(source, destination);
+ };
+ return [cmd];
+ }
+ }
+
+ Rule {
+ multiplex: true
+ condition: product.codesign.enableCodeSigning
+ inputs: ["codesign.entitlements", "codesign.embedded_provisioningprofile"]
+
+ Artifact {
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ product.targetName + ".xcent")
+ fileTags: ["codesign.xcent"]
+ }
+
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "generating entitlements";
+ cmd.highlight = "codegen";
+ cmd.bundleIdentifier = product.bundle.identifier;
+ cmd.signingEntitlements = (inputs["codesign.entitlements"] || [])
+ .map(function (a) { return a.filePath; });
+ cmd.provisioningProfiles = (inputs["codesign.embedded_provisioningprofile"] || [])
+ .map(function (a) { return a.filePath; });
+ cmd.platformPath = product.xcode ? product.xcode.platformPath : undefined;
+ cmd.sdkPath = product.xcode ? product.xcode.sdkPath : undefined;
+ cmd.sourceCode = function() {
+ var i;
+ var provData = {};
+ var provisionProfiles = inputs["codesign.embedded_provisioningprofile"];
+ for (i in provisionProfiles) {
+ var plist = new PropertyList();
+ try {
+ plist.readFromData(Utilities.smimeMessageContent(
+ provisionProfiles[i].filePath));
+ provData = plist.toObject();
+ } finally {
+ plist.clear();
+ }
+ }
+
+ var aggregateEntitlements = {};
+
+ // Start building up an aggregate entitlements plist from the files in the SDKs,
+ // which contain placeholders in the same manner as Info.plist
+ function entitlementsFileContents(path) {
+ return File.exists(path) ? BundleTools.infoPlistContents(path) : undefined;
+ }
+ var entitlementsSources = [];
+ if (platformPath) {
+ entitlementsSources.push(
+ entitlementsFileContents(
+ FileInfo.joinPaths(platformPath, "Entitlements.plist")));
+ }
+ if (sdkPath) {
+ entitlementsSources.push(
+ entitlementsFileContents(
+ FileInfo.joinPaths(sdkPath, "Entitlements.plist")));
+ }
+
+ for (i = 0; i < signingEntitlements.length; ++i) {
+ entitlementsSources.push(entitlementsFileContents(signingEntitlements[i]));
+ }
+
+ for (i = 0; i < entitlementsSources.length; ++i) {
+ var contents = entitlementsSources[i];
+ for (var key in contents) {
+ if (contents.hasOwnProperty(key))
+ aggregateEntitlements[key] = contents[key];
+ }
+ }
+
+ contents = provData["Entitlements"];
+ for (key in contents) {
+ if (contents.hasOwnProperty(key) && !aggregateEntitlements.hasOwnProperty(key))
+ aggregateEntitlements[key] = contents[key];
+ }
+
+ // Expand entitlements variables with data from the provisioning profile
+ var env = {
+ "AppIdentifierPrefix": (provData["ApplicationIdentifierPrefix"] || "") + ".",
+ "CFBundleIdentifier": bundleIdentifier
+ };
+ DarwinTools.expandPlistEnvironmentVariables(aggregateEntitlements, env, true);
+
+ // Anything with an undefined or otherwise empty value should be removed
+ // Only JSON-formatted plists can have null values, other formats error out
+ // This also follows Xcode behavior
+ DarwinTools.cleanPropertyList(aggregateEntitlements);
+
+ var plist = new PropertyList();
+ try {
+ plist.readFromObject(aggregateEntitlements);
+ plist.writeToFile(outputs["codesign.xcent"][0].filePath, "xml1");
+ } finally {
+ plist.clear();
+ }
+ };
+ return [cmd];
+ }
+ }
+}
diff --git a/share/qbs/modules/codesign/codesign.js b/share/qbs/modules/codesign/codesign.js
new file mode 100644
index 000000000..1d039e7ca
--- /dev/null
+++ b/share/qbs/modules/codesign/codesign.js
@@ -0,0 +1,279 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2021 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+var PathTools = require("qbs.PathTools");
+var PropertyList = require("qbs.PropertyList");
+var Utilities = require("qbs.Utilities");
+
+function findSigningIdentities(searchString, team) {
+ if (!searchString)
+ return {};
+ var identities = Utilities.signingIdentities();
+ var matchedIdentities = {};
+ for (var key in identities) {
+ var identity = identities[key];
+ if (team && ![identity.subjectInfo.O, identity.subjectInfo.OU].contains(team))
+ continue;
+ if (searchString === key || identity.subjectInfo.CN.startsWith(searchString))
+ matchedIdentities[key] = identity;
+ }
+ return matchedIdentities;
+}
+
+function humanReadableIdentitySummary(identities) {
+ return "\n\t" + Object.keys(identities).map(function (key) {
+ return identities[key].subjectInfo.CN
+ + " in team "
+ + identities[key].subjectInfo.O
+ + " (" + identities[key].subjectInfo.OU + ")";
+ }).join("\n\t");
+}
+
+/**
+ * Returns the best provisioning profile for code signing a binary with the given parameters.
+ * Ideally, this should behave identically as Xcode but the algorithm is not documented
+ * \l{https://developer.apple.com/library/ios/qa/qa1814/_index.html}{Automatic Provisioning}
+ */
+function findBestProvisioningProfile(product, files) {
+ var actualSigningIdentity = product.codesign._actualSigningIdentity || {};
+ var teamIdentifier = product.codesign.teamIdentifier;
+ var bundleIdentifier = product.bundle.identifier;
+ var targetOS = product.qbs.targetOS;
+ var buildVariant = product.qbs.buildVariant;
+ var query = product.codesign.provisioningProfile;
+ var profilePlatform = product.codesign._provisioningProfilePlatform;
+
+ // Read all provisioning profiles on disk into plist objects in memory
+ var profiles = files.map(function(filePath) {
+ var plist = new PropertyList();
+ try {
+ plist.readFromData(Utilities.smimeMessageContent(filePath));
+ return {
+ data: plist.toObject(),
+ filePath: filePath
+ };
+ } finally {
+ plist.clear();
+ }
+ });
+
+ // Do a simple search by matching UUID or Name
+ if (query) {
+ for (var i = 0; i < profiles.length; ++i) {
+ var obj = profiles[i];
+ if (obj.data && (obj.data.UUID === query || obj.data.Name === query))
+ return obj;
+ }
+
+ // If we asked for a specific provisioning profile, don't select one automatically
+ return undefined;
+ }
+
+ // Provisioning profiles are not normally used with ad-hoc code signing or non-apps
+ // We do these checks down here only for the automatic selection but not above because
+ // if the user explicitly selects a provisioning profile it should be used no matter what
+ if (actualSigningIdentity.SHA1 === "-" || !product.type.contains("application"))
+ return undefined;
+
+ // Filter out any provisioning profiles we know to be unsuitable from the start
+ profiles = profiles.filter(function (profile) {
+ var data = profile.data;
+
+ if (actualSigningIdentity.subjectInfo) {
+ var certCommonNames = (data["DeveloperCertificates"] || []).map(function (cert) {
+ return Utilities.certificateInfo(cert).subjectInfo.CN;
+ });
+ if (!certCommonNames.contains(actualSigningIdentity.subjectInfo.CN)) {
+ console.log("Skipping provisioning profile with no matching certificate names for '"
+ + actualSigningIdentity.subjectInfo.CN
+ + "' (found " + certCommonNames.join(", ") + "): "
+ + profile.filePath);
+ return false;
+ }
+ }
+
+ var platforms = data["Platform"] || [];
+ if (platforms.length > 0 && profilePlatform && !platforms.contains(profilePlatform)) {
+ console.log("Skipping provisioning profile for platform " + platforms.join(", ")
+ + " (current platform " + profilePlatform + ")"
+ + ": " + profile.filePath);
+ return false;
+ }
+
+ if (teamIdentifier
+ && !data["TeamIdentifier"].contains(teamIdentifier)
+ && data["TeamName"] !== teamIdentifier) {
+ console.log("Skipping provisioning profile for team " + data["TeamIdentifier"]
+ + " (" + data["TeamName"] + ") (current team " + teamIdentifier + ")"
+ + ": " + profile.filePath);
+ return false;
+ }
+
+ if (Date.parse(data["ExpirationDate"]) <= Date.now()) {
+ console.log("Skipping expired provisioning profile: " + profile.filePath);
+ return false;
+ }
+
+ // Filter development vs distribution profiles;
+ // though the certificate common names check should have been sufficient
+ var isDebug = buildVariant === "debug";
+ if (data["Entitlements"]["get-task-allow"] !== isDebug) {
+ console.log("Skipping provisioning profile for wrong debug mode: " + profile.filePath);
+ return false;
+ }
+
+ var prefix = data["ApplicationIdentifierPrefix"];
+ var fullAppId = data["Entitlements"]["application-identifier"];
+ if ([prefix, bundleIdentifier].join(".") !== fullAppId
+ && [prefix, "*"].join(".") !== fullAppId) {
+ console.log("Skipping provisioning profile not matching full ("
+ + [prefix, bundleIdentifier].join(".") + ") or wildcard ("
+ + [prefix, "*"].join(".") + ") app ID (found " + fullAppId + "): "
+ + profile.filePath);
+ return false;
+ }
+
+ return true;
+ });
+
+ // Sort by expiration date - sooner expiration dates come last
+ profiles.sort(function(profileA, profileB) {
+ var expA = Date.parse(profileA.data["ExpirationDate"]);
+ var expB = Date.parse(profileB.data["ExpirationDate"]);
+ if (expA < expB)
+ return -1;
+ if (expA > expB)
+ return 1;
+ return 0;
+ });
+
+ // Sort by application identifier - wildcard profiles come last
+ profiles.sort(function(profileA, profileB) {
+ var idA = profileA.data["Entitlements"]["application-identifier"];
+ var idB = profileB.data["Entitlements"]["application-identifier"];
+ if (!idA.endsWith(".*") && idB.endsWith(".*"))
+ return -1;
+ if (idA.endsWith(".*") && !idB.endsWith(".*"))
+ return 1;
+ return 0;
+ });
+
+ if (profiles.length) {
+ console.log("Automatic provisioning using profile "
+ + profiles[0].data.UUID
+ + " ("
+ + profiles[0].data.TeamName
+ + " - "
+ + profiles[0].data.Name
+ + ") in product "
+ + product.name);
+ return profiles[0];
+ }
+}
+
+function prepareSign(project, product, inputs, outputs, input, output) {
+ var cmd, cmds = [];
+
+ if (!product.codesign.enableCodeSigning)
+ return cmds;
+
+ var isBundle = "bundle.content" in outputs;
+ var outputFilePath = isBundle
+ ? FileInfo.joinPaths(product.destinationDirectory, product.bundle.bundleName)
+ : outputs["codesign.signed_artifact"][0].filePath;
+ var outputFileName = isBundle
+ ? product.bundle.bundleName
+ : outputs["codesign.signed_artifact"][0].fileName;
+ var isProductBundle = product.bundle && product.bundle.isBundle;
+
+ // If the product is a bundle, just sign the bundle
+ // instead of signing the bundle and executable separately
+ var shouldSignArtifact = !isProductBundle || isBundle;
+
+ var enableCodeSigning = product.codesign.enableCodeSigning;
+ if (enableCodeSigning && shouldSignArtifact) {
+ var actualSigningIdentity = product.codesign._actualSigningIdentity;
+ if (!actualSigningIdentity) {
+ throw "No codesigning identities (i.e. certificate and private key pairs) matching “"
+ + product.codesign.signingIdentity + "” were found.";
+ }
+
+ // If this is a framework, we need to sign its versioned directory
+ var subpath = "";
+ if (isBundle) {
+ var frameworkVersion = product.bundle.frameworkVersion;
+ if (frameworkVersion) {
+ subpath = product.bundle.contentsFolderPath;
+ subpath = subpath.substring(product.bundle.bundleName.length);
+ }
+ }
+
+ var args = product.codesign.codesignFlags || [];
+ args.push("--force");
+ args.push("--sign", actualSigningIdentity.SHA1);
+
+ // If signingTimestamp is undefined, do not specify the flag at all -
+ // this uses the system-specific default behavior
+ var signingTimestamp = product.codesign.signingTimestamp;
+ if (signingTimestamp !== undefined) {
+ // If signingTimestamp is an empty string, specify the flag but do
+ // not specify a value - this uses a default Apple-provided server
+ var flag = "--timestamp";
+ if (signingTimestamp)
+ flag += "=" + signingTimestamp;
+ args.push(flag);
+ }
+
+ for (var j in inputs["codesign.xcent"]) {
+ args.push("--entitlements", inputs["codesign.xcent"][j].filePath);
+ break; // there should only be one
+ }
+ args.push(outputFilePath + subpath);
+ cmd = new Command(product.codesign.codesignPath, args);
+ cmd.description = "codesign " + outputFileName
+ + " (" + actualSigningIdentity.subjectInfo.CN + ")";
+ cmd.outputFilePath = outputFilePath;
+ cmd.stderrFilterFunction = function(stderr) {
+ return stderr.replace(outputFilePath + ": replacing existing signature\n", "");
+ };
+ cmds.push(cmd);
+ }
+
+ if (isBundle) {
+ cmd = new Command("touch", ["-c", outputFilePath]);
+ cmd.silent = true;
+ cmds.push(cmd);
+ }
+
+ return cmds;
+}
diff --git a/share/qbs/modules/codesign/noop.qbs b/share/qbs/modules/codesign/noop.qbs
new file mode 100644
index 000000000..3234d7476
--- /dev/null
+++ b/share/qbs/modules/codesign/noop.qbs
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2021 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs
+
+CodeSignModule {
+ condition: true
+ priority: -100
+}
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index 9f4e6be99..ca89bbd63 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -145,6 +145,12 @@ Module {
be set."
}
+ property string toolchainInstallPath
+ PropertyOptions {
+ name: "toolchainInstallPath"
+ description: "a path to the directory where the toolchain executable files are located."
+ }
+
property pathList includePaths
property pathList systemIncludePaths
property pathList distributionIncludePaths
diff --git a/share/qbs/modules/cpp/DarwinGCC.qbs b/share/qbs/modules/cpp/DarwinGCC.qbs
index 9332603ec..efdd97f1d 100644
--- a/share/qbs/modules/cpp/DarwinGCC.qbs
+++ b/share/qbs/modules/cpp/DarwinGCC.qbs
@@ -98,7 +98,7 @@ UnixGCC {
setupBuildEnvironment: {
for (var key in product.cpp.buildEnv) {
- v = new ModUtils.EnvironmentVariable(key);
+ var v = new ModUtils.EnvironmentVariable(key);
v.value = product.cpp.buildEnv[key];
v.set();
}
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index b69f26739..34a0b47de 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -44,6 +44,8 @@ CppModule {
condition: qbs.toolchain && qbs.toolchain.contains("gcc")
priority: -100
+ Depends { name: "codesign" }
+
Probes.GccBinaryProbe {
id: compilerPathProbe
condition: !toolchainInstallPath && !_skipAllChecks
@@ -134,8 +136,7 @@ CppModule {
property string toolchainPrefix: compilerPathProbe.found
? compilerPathProbe.tcPrefix
: undefined
- property string toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path
- : undefined
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
property string binutilsPath: binutilsProbe.found ? binutilsProbe.path : toolchainInstallPath
assemblerName: 'as' + compilerExtension
@@ -401,12 +402,15 @@ CppModule {
"bundle.input",
"dynamiclibrary", "dynamiclibrary_symlink", "dynamiclibrary_symbols", "debuginfo_dll",
"debuginfo_bundle","dynamiclibrary_import", "debuginfo_plist",
+ "codesign.signed_artifact",
]
outputArtifacts: {
var artifacts = [{
filePath: product.destinationDirectory + "/"
+ PathTools.dynamicLibraryFilePath(product),
- fileTags: ["bundle.input", "dynamiclibrary"],
+ fileTags: ["bundle.input", "dynamiclibrary"]
+ .concat(product.codesign.enableCodeSigning
+ ? ["codesign.signed_artifact"] : []),
bundle: {
_bundleFilePath: product.destinationDirectory + "/"
+ PathTools.bundleExecutableFilePath(product)
@@ -511,12 +515,14 @@ CppModule {
inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
outputFileTags: ["bundle.input", "loadablemodule", "debuginfo_loadablemodule",
- "debuginfo_bundle","debuginfo_plist"]
+ "debuginfo_bundle", "debuginfo_plist", "codesign.signed_artifact"]
outputArtifacts: {
var app = {
filePath: FileInfo.joinPaths(product.destinationDirectory,
PathTools.loadableModuleFilePath(product)),
- fileTags: ["bundle.input", "loadablemodule"],
+ fileTags: ["bundle.input", "loadablemodule"]
+ .concat(product.codesign.enableCodeSigning
+ ? ["codesign.signed_artifact"] : []),
bundle: {
_bundleFilePath: FileInfo.joinPaths(product.destinationDirectory,
PathTools.bundleExecutableFilePath(product))
@@ -548,13 +554,14 @@ CppModule {
}
inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
- outputFileTags: ["bundle.input", "application", "debuginfo_app","debuginfo_bundle",
- "debuginfo_plist", "mem_map"]
+ outputFileTags: ["bundle.input", "application", "debuginfo_app", "debuginfo_bundle",
+ "debuginfo_plist", "mem_map", "codesign.signed_artifact"]
outputArtifacts: {
var app = {
filePath: FileInfo.joinPaths(product.destinationDirectory,
PathTools.applicationFilePath(product)),
- fileTags: ["bundle.input", "application"],
+ fileTags: ["bundle.input", "application"].concat(
+ product.codesign.enableCodeSigning ? ["codesign.signed_artifact"] : []),
bundle: {
_bundleFilePath: FileInfo.joinPaths(product.destinationDirectory,
PathTools.bundleExecutableFilePath(product))
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 9b6a074d2..99452b6da 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -28,6 +28,7 @@
**
****************************************************************************/
+var Codesign = require("../codesign/codesign.js");
var Cpp = require("cpp.js");
var File = require("qbs.File");
var FileInfo = require("qbs.FileInfo");
@@ -132,7 +133,7 @@ function collectLibraryDependencies(product, isDarwin) {
if (!obj.cpp)
return;
function ensureArray(a) {
- return Array.isArray(a) ? a : [];
+ return (a instanceof Array) ? a : [];
}
function sanitizedModuleListProperty(obj, moduleName, propertyName) {
return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
@@ -355,11 +356,12 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
return rpath;
}
+ function isNotSystemRunPath(p) {
+ return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p)
+ && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)));
+ };
+
if (!product.qbs.targetOS.contains("windows")) {
- function isNotSystemRunPath(p) {
- return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p)
- && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)));
- };
for (i in rpaths) {
if (isNotSystemRunPath(rpaths[i]))
escapableLinkerFlags.push("-rpath", fixupRPath(rpaths[i]));
@@ -1383,28 +1385,8 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
}
}
- if (product.xcode && product.bundle) {
- var actualSigningIdentity = product.xcode.actualSigningIdentity;
- var codesignDisplayName = product.xcode.actualSigningIdentityDisplayName;
- if (actualSigningIdentity && !product.bundle.isBundle) {
- args = product.xcode.codesignFlags || [];
- args.push("--force");
- args.push("--sign", actualSigningIdentity);
- args = args.concat(DarwinTools._codeSignTimestampFlags(product));
-
- for (var j in inputs.xcent) {
- args.push("--entitlements", inputs.xcent[j].filePath);
- break; // there should only be one
- }
- args.push(primaryOutput.filePath);
- cmd = new Command(product.xcode.codesignPath, args);
- cmd.description = "codesign "
- + primaryOutput.fileName
- + " using " + codesignDisplayName
- + " (" + actualSigningIdentity + ")";
- commands.push(cmd);
- }
- }
+ Array.prototype.push.apply(
+ commands, Codesign.prepareSign(project, product, inputs, outputs, input, output));
return commands;
}
diff --git a/share/qbs/modules/cpp/iar.js b/share/qbs/modules/cpp/iar.js
index f1c41fe64..d25b74324 100644
--- a/share/qbs/modules/cpp/iar.js
+++ b/share/qbs/modules/cpp/iar.js
@@ -38,35 +38,138 @@ var TemporaryDir = require("qbs.TemporaryDir");
var TextFile = require("qbs.TextFile");
function supportXLinker(architecture) {
- return architecture === "78k" || architecture === "avr"
- || architecture === "avr32" || architecture === "mcs51"
- || architecture === "msp430" || architecture === "v850"
- || architecture === "m68k" || architecture === "m32c"
- || architecture === "r32c" || architecture === "m16c"
- || architecture === "cr16";
+ return architecture === "78k"
+ || architecture === "avr"
+ || architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "hcs12"
+ || architecture === "hcs8"
+ || architecture === "m16c"
+ || architecture === "m32c"
+ || architecture === "m68k"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "r32c"
+ || architecture === "v850";
}
function supportILinker(architecture) {
return architecture.startsWith("arm")
- || architecture === "rh850" || architecture === "rl78"
- || architecture === "rx" || architecture === "stm8"
- || architecture === "sh" || architecture === "riscv";
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "sh"
+ || architecture === "stm8";
}
function supportXArchiver(architecture) {
- return architecture === "mcs51" || architecture === "avr"
- || architecture === "msp430" || architecture === "v850"
- || architecture === "78k" || architecture === "avr32"
- || architecture === "m68k" || architecture === "m32c"
- || architecture === "r32c" || architecture === "m16c"
- || architecture === "cr16";
+ return architecture === "78k"
+ || architecture === "avr"
+ || architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "hcs12"
+ || architecture === "hcs8"
+ || architecture === "m16c"
+ || architecture === "m32c"
+ || architecture === "m68k"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "r32c"
+ || architecture === "v850";
}
function supportIArchiver(architecture) {
return architecture.startsWith("arm")
- || architecture === "stm8" || architecture === "rl78"
- || architecture === "rx" || architecture === "rh850"
- || architecture === "sh" || architecture === "riscv";
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "sh"
+ || architecture === "stm8";
+}
+
+function supportXAssembler(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "78k"
+ || architecture === "avr"
+ || architecture === "hcs12"
+ || architecture === "m16c"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "m32c"
+ || architecture === "v850";
+}
+
+function supportIAssembler(architecture) {
+ return architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "hcs8"
+ || architecture === "r32c"
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "sh"
+ || architecture === "stm8"
+ || architecture === "m68k";
+}
+
+function supportEndianness(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "rx";
+}
+
+function supportCppExceptions(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx";
+}
+
+function supportCppRtti(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx";
+}
+
+function supportCppWarningAboutCStyleCast(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "avr"
+ || architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "rh850"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "stm8"
+ || architecture === "v850";
+}
+
+function supportDeprecatedFeatureWarnings(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "avr"
+ || architecture === "cr16"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "rh850"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "stm8"
+ || architecture === "v850";
+}
+
+function supportCLanguageVersion(architecture) {
+ return architecture !== "78k";
+}
+
+function supportCppLanguage(compilerFilePath) {
+ var baseName = FileInfo.baseName(compilerFilePath);
+ return baseName !== "iccs08";
}
// It is a 'magic' IAR-specific target architecture code.
@@ -94,7 +197,11 @@ function architectureCode(architecture) {
return "34";
case "cr16":
return "45";
- case "rh850": case "rl78": case "rx": case "stm8": case "sh": case "riscv":
+ case "hcs12":
+ return "12";
+ case "hcs8":
+ return "78";
+ case "rh850": case "riscv": case "rl78": case "rx": case "sh": case "stm8":
return "";
default:
if (architecture.startsWith("arm"))
@@ -107,40 +214,44 @@ function compilerName(qbs) {
var architecture = qbs.architecture;
if (architecture.startsWith("arm"))
return "iccarm";
- else if (architecture === "mcs51")
- return "icc8051";
+ else if (architecture === "78k")
+ return "icc78k";
else if (architecture === "avr")
return "iccavr";
- else if (architecture === "stm8")
- return "iccstm8";
+ else if (architecture === "avr32")
+ return "iccavr32";
+ else if (architecture === "cr16")
+ return "icccr16c";
+ else if (architecture === "hcs12")
+ return "icchcs12";
+ else if (architecture === "hcs8")
+ return "iccs08";
+ else if (architecture === "m16c")
+ return "iccm16c";
+ else if (architecture === "m32c")
+ return "iccm32c";
+ else if (architecture === "m68k")
+ return "icccf";
+ else if (architecture === "mcs51")
+ return "icc8051";
else if (architecture === "msp430")
return "icc430";
- else if (architecture === "v850")
- return "iccv850";
- else if (architecture === "78k")
- return "icc78k";
+ else if (architecture === "r32c")
+ return "iccr32c";
+ else if (architecture === "rh850")
+ return "iccrh850";
+ else if (architecture === "riscv")
+ return "iccriscv";
else if (architecture === "rl78")
return "iccrl78";
else if (architecture === "rx")
return "iccrx";
- else if (architecture === "rh850")
- return "iccrh850";
- else if (architecture === "avr32")
- return "iccavr32";
else if (architecture === "sh")
return "iccsh";
- else if (architecture === "riscv")
- return "iccriscv";
- else if (architecture === "m68k")
- return "icccf";
- else if (architecture === "m32c")
- return "iccm32c";
- else if (architecture === "r32c")
- return "iccr32c";
- else if (architecture === "m16c")
- return "iccm16c";
- else if (architecture === "cr16")
- return "icccr16c";
+ else if (architecture === "stm8")
+ return "iccstm8";
+ else if (architecture === "v850")
+ return "iccv850";
throw "Unable to deduce compiler name for unsupported architecture: '"
+ architecture + "'";
}
@@ -149,40 +260,44 @@ function assemblerName(qbs) {
var architecture = qbs.architecture;
if (architecture.startsWith("arm"))
return "iasmarm";
- else if (architecture === "rl78")
- return "iasmrl78";
- else if (architecture === "rx")
- return "iasmrx";
- else if (architecture === "rh850")
- return "iasmrh850";
- else if (architecture === "mcs51")
- return "a8051";
- else if (architecture === "avr")
- return "aavr";
- else if (architecture === "stm8")
- return "iasmstm8";
- else if (architecture === "msp430")
- return "a430";
- else if (architecture === "v850")
- return "av850";
else if (architecture === "78k")
return "a78k";
+ else if (architecture === "avr")
+ return "aavr";
else if (architecture === "avr32")
return "aavr32";
- else if (architecture === "sh")
- return "iasmsh";
- else if (architecture === "riscv")
- return "iasmriscv";
- else if (architecture === "m68k")
- return "acf";
+ else if (architecture === "cr16")
+ return "acr16c";
+ else if (architecture === "hcs12")
+ return "ahcs12";
+ else if (architecture === "hcs8")
+ return "as08";
+ else if (architecture === "m16c")
+ return "am16c";
else if (architecture === "m32c")
return "am32c";
+ else if (architecture === "m68k")
+ return "acf";
+ else if (architecture === "mcs51")
+ return "a8051";
+ else if (architecture === "msp430")
+ return "a430";
else if (architecture === "r32c")
return "ar32c";
- else if (architecture === "m16c")
- return "am16c";
- else if (architecture === "cr16")
- return "acr16c";
+ else if (architecture === "rh850")
+ return "iasmrh850";
+ else if (architecture === "riscv")
+ return "iasmriscv";
+ else if (architecture === "rl78")
+ return "iasmrl78";
+ else if (architecture === "rx")
+ return "iasmrx";
+ else if (architecture === "sh")
+ return "iasmsh";
+ else if (architecture === "stm8")
+ return "iasmstm8";
+ else if (architecture === "v850")
+ return "av850";
throw "Unable to deduce assembler name for unsupported architecture: '"
+ architecture + "'";
}
@@ -253,16 +368,16 @@ function guessArmArchitecture(core) {
arch += "v4m";
else if (core === "__ARM4TM__")
arch += "v4tm";
- else if (core === "__ARM5__")
- arch += "v5";
else if (core === "__ARM5E__")
arch += "v5e";
- else if (core === "__ARM6__")
- arch += "v6";
+ else if (core === "__ARM5__")
+ arch += "v5";
else if (core === "__ARM6M__")
arch += "v6m";
else if (core === "__ARM6SM__")
arch += "v6sm";
+ else if (core === "__ARM6__")
+ arch += "v6";
else if (core === "__ARM7M__")
arch += "v7m";
else if (core === "__ARM7R__")
@@ -271,42 +386,46 @@ function guessArmArchitecture(core) {
}
function guessArchitecture(macros) {
- if (macros["__ICCARM__"] === "1")
- return guessArmArchitecture(macros["__CORE__"]);
- else if (macros["__ICC8051__"] === "1")
- return "mcs51";
- else if (macros["__ICCAVR__"] === "1")
- return "avr";
- else if (macros["__ICCSTM8__"] === "1")
- return "stm8";
- else if (macros["__ICC430__"] === "1")
+ if (macros["__ICC430__"] === "1")
return "msp430";
- else if (macros["__ICCRL78__"] === "1")
- return "rl78";
- else if (macros["__ICCRX__"] === "1")
- return "rx";
- else if (macros["__ICCRH850__"] === "1")
- return "rh850";
- else if (macros["__ICCV850__"] === "1")
- return "v850";
else if (macros["__ICC78K__"] === "1")
return "78k";
+ else if (macros["__ICC8051__"] === "1")
+ return "mcs51";
+ else if (macros["__ICCARM__"] === "1")
+ return guessArmArchitecture(macros["__CORE__"]);
else if (macros["__ICCAVR32__"] === "1")
return "avr32";
- else if (macros["__ICCSH__"] === "1")
- return "sh";
- else if (macros["__ICCRISCV__"] === "1")
- return "riscv";
+ else if (macros["__ICCAVR__"] === "1")
+ return "avr";
else if (macros["__ICCCF__"] === "1")
return "m68k";
+ else if (macros["__ICCCR16C__"] === "1")
+ return "cr16";
+ else if (macros["__ICCHCS12__"] === "1")
+ return "hcs12";
+ else if (macros["__ICCM16C__"] === "1")
+ return "m16c";
else if (macros["__ICCM32C__"] === "1")
return "m32c";
else if (macros["__ICCR32C__"] === "1")
return "r32c";
- else if (macros["__ICCM16C__"] === "1")
- return "m16c";
- else if (macros["__ICCCR16C__"] === "1")
- return "cr16";
+ else if (macros["__ICCRH850__"] === "1")
+ return "rh850";
+ else if (macros["__ICCRISCV__"] === "1")
+ return "riscv";
+ else if (macros["__ICCRL78__"] === "1")
+ return "rl78";
+ else if (macros["__ICCRX__"] === "1")
+ return "rx";
+ else if (macros["__ICCS08__"] === "1")
+ return "hcs8";
+ else if (macros["__ICCSH__"] === "1")
+ return "sh";
+ else if (macros["__ICCSTM8__"] === "1")
+ return "stm8";
+ else if (macros["__ICCV850__"] === "1")
+ return "v850";
}
function guessEndianness(macros) {
@@ -315,19 +434,31 @@ function guessEndianness(macros) {
return "big"
}
-function guessVersion(macros, architecture)
-{
+function guessVersion(macros, architecture) {
var version = parseInt(macros["__VER__"], 10);
if (architecture.startsWith("arm")) {
return { major: parseInt(version / 1000000),
minor: parseInt(version / 1000) % 1000,
patch: parseInt(version) % 1000 }
- } else if (architecture === "mcs51" || architecture === "avr" || architecture === "stm8"
- || architecture === "msp430" || architecture === "rl78" || architecture === "rx"
- || architecture === "rh850" || architecture === "v850" || architecture === "78k"
- || architecture === "avr32" || architecture === "sh" || architecture === "riscv"
- || architecture === "m68k" || architecture === "m32c" || architecture === "r32c"
- || architecture === "m16c" || architecture === "cr16") {
+ } else if (architecture === "78k"
+ || architecture === "avr"
+ || architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "hcs12"
+ || architecture === "hcs8"
+ || architecture === "m16c"
+ || architecture === "m32c"
+ || architecture === "m68k"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "r32c"
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "sh"
+ || architecture === "stm8"
+ || architecture === "v850") {
return { major: parseInt(version / 100),
minor: parseInt(version % 100),
patch: 0 }
@@ -338,24 +469,25 @@ function cppLanguageOption(compilerFilePath) {
var baseName = FileInfo.baseName(compilerFilePath);
switch (baseName) {
case "iccarm":
- case "iccrl78":
- case "iccrx":
case "iccrh850":
case "iccriscv":
+ case "iccrl78":
+ case "iccrx":
return "--c++";
- case "icc8051":
- case "iccavr":
- case "iccstm8":
case "icc430":
- case "iccv850":
case "icc78k":
+ case "icc8051":
+ case "iccavr":
case "iccavr32":
- case "iccsh":
case "icccf":
+ case "icccr16c":
+ case "icchcs12":
+ case "iccm16c":
case "iccm32c":
case "iccr32c":
- case "iccm16c":
- case "icccr16c":
+ case "iccsh":
+ case "iccstm8":
+ case "iccv850":
return "--ec++";
}
throw "Unable to deduce C++ language option for unsupported compiler: '"
@@ -369,7 +501,7 @@ function dumpMacros(compilerFilePath, tag) {
var outFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/iar-macros.predef");
var args = [ inFilePath, "--predef_macros", outFilePath ];
- if (tag && tag === "cpp")
+ if (tag === "cpp" && supportCppLanguage(compilerFilePath))
args.push(cppLanguageOption(compilerFilePath));
var p = new Process();
@@ -378,45 +510,47 @@ function dumpMacros(compilerFilePath, tag) {
return ModUtils.extractMacros(outFile.readAll());
}
-function dumpDefaultPaths(compilerFilePath, tag) {
+function dumpCompilerIncludePaths(compilerFilePath, tag) {
+ // We can dump the compiler include paths using the undocumented `--IDE3` flag,
+ // e.g. which also is used in the IAR extension for the VSCode. In this case the
+ // compiler procuces the console output in the following format:
+ // `$$TOOL_BEGIN $$VERSION "3" $$INC_BEGIN $$FILEPATH "<path\\to\\directory>" $$TOOL_END`
+
var tempDir = new TemporaryDir();
var inFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/empty-source.c");
var inFile = new TextFile(inFilePath, TextFile.WriteOnly);
- var args = [ inFilePath, "--preinclude", "." ];
- if (tag === "cpp")
+ var args = ["--IDE3", inFilePath];
+ if (tag === "cpp" && supportCppLanguage(compilerFilePath))
args.push(cppLanguageOption(compilerFilePath));
+ var includePaths = [];
var p = new Process();
- // This process should return an error, don't throw
- // an error in this case.
+ // It is possible that the process can return an error code in case the
+ // compiler does not support the `--IDE3` flag. So, don't throw an error in this case.
p.exec(compilerFilePath, args, false);
- var output = p.readStdErr();
-
- var includePaths = [];
- var pass = 0;
- for (var pos = 0; pos < output.length; ++pos) {
- var searchIndex = output.indexOf("searched:", pos);
- if (searchIndex === -1)
- break;
- var startQuoteIndex = output.indexOf('"', searchIndex + 1);
- if (startQuoteIndex === -1)
- break;
- var endQuoteIndex = output.indexOf('"', startQuoteIndex + 1);
- if (endQuoteIndex === -1)
- break;
- pos = endQuoteIndex + 1;
-
- // Ignore the first path as it is not a compiler include path.
- ++pass;
- if (pass === 1)
- continue;
+ p.readStdOut().trim().split(/\r?\n/g).map(function(line) {
+ var m = line.match(/\$\$INC_BEGIN\s\$\$FILEPATH\s\"([^"]*)/);
+ if (m) {
+ var includePath = m[1].replace(/\\\\/g, '/');
+ if (includePath)
+ includePaths.push(includePath);
+ }
+ });
- var path = output.substring(startQuoteIndex + 1, endQuoteIndex)
- .replace(/[\s]{2,}/g, ' ');
- includePaths.push(path);
+ if (includePaths.length === 0) {
+ // This can happen if the compiler does not support the `--IDE3` flag,
+ // e.g. IAR for S08 architecture. In this case we use fallback to the
+ // detection of the `inc` directory.
+ var includePath = FileInfo.joinPaths(FileInfo.path(compilerFilePath), "../inc/");
+ includePaths.push(includePath);
}
+ return includePaths;
+}
+
+function dumpDefaultPaths(compilerFilePath, tag) {
+ var includePaths = dumpCompilerIncludePaths(compilerFilePath, tag);
return {
"includePaths": includePaths
};
@@ -441,7 +575,7 @@ function collectLibraryDependencies(product) {
if (!obj.cpp)
return;
function ensureArray(a) {
- return Array.isArray(a) ? a : [];
+ return (a instanceof Array) ? a : [];
}
function sanitizedModuleListProperty(obj, moduleName, propertyName) {
return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
@@ -521,9 +655,6 @@ function staticLibraryLinkerOutputArtifacts(product) {
}
function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
- // Determine which C-language we're compiling.
- var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
-
var args = [];
// Input.
@@ -580,6 +711,7 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
}
var architecture = input.qbs.architecture;
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
// Warning level flags.
switch (input.cpp.warningLevel) {
@@ -587,24 +719,21 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("--no_warnings");
break;
case "all":
- if (architecture !== "78k") {
- if (architecture !== "avr32" && architecture !== "r32c"
- && architecture !== "sh" && architecture !== "m16c") {
+ if (supportDeprecatedFeatureWarnings(architecture)) {
args.push("--deprecated_feature_warnings="
+"+attribute_syntax,"
+"+preprocessor_extensions,"
+"+segment_pragmas");
}
- if (tag === "cpp")
+ if (tag === "cpp" && supportCppWarningAboutCStyleCast(architecture))
args.push("--warn_about_c_style_casts");
- }
break;
}
if (input.cpp.treatWarningsAsErrors)
args.push("--warnings_are_errors");
// C language version flags.
- if (tag === "c" && (architecture !== "78k")) {
+ if (tag === "c" && supportCLanguageVersion(architecture)) {
var knownValues = ["c89"];
var cLanguageVersion = Cpp.languageVersion(
input.cpp.cLanguageVersion, knownValues, "C");
@@ -620,35 +749,27 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
}
// C++ language version flags.
- if (tag === "cpp") {
- if (architecture.startsWith("arm")
- || architecture === "rl78" || architecture === "rx"
- || architecture === "rh850" || architecture === "riscv") {
- // Enable C++ language flags.
- args.push("--c++");
- // Exceptions flags.
- if (!input.cpp.enableExceptions)
- args.push("--no_exceptions");
- // RTTI flags.
- if (!input.cpp.enableRtti)
- args.push("--no_rtti");
- } else if (architecture === "stm8" || architecture === "mcs51"
- || architecture === "avr" || architecture === "msp430"
- || architecture === "v850" || architecture === "78k"
- || architecture === "avr32" || architecture === "sh"
- || architecture === "m68k" || architecture === "m32c"
- || architecture === "r32c" || architecture === "m16c"
- || architecture === "cr16") {
- args.push("--ec++");
- }
+ var compilerFilePath = input.cpp.compilerPath;
+ if (tag === "cpp" && supportCppLanguage(compilerFilePath)) {
+ // C++ language flag.
+ var cppOption = cppLanguageOption(compilerFilePath);
+ args.push(cppOption);
+
+ // Exceptions flag.
+ var enableExceptions = input.cpp.enableExceptions;
+ if (!enableExceptions && supportCppExceptions(architecture))
+ args.push("--no_exceptions");
+
+ // RTTI flag.
+ var enableRtti = input.cpp.enableRtti;
+ if (!enableRtti && supportCppRtti(architecture))
+ args.push("--no_rtti");
}
// Byte order flags.
- if (architecture.startsWith("arm") || architecture === "rx") {
- var endianness = input.cpp.endianness;
- if (endianness)
- args.push("--endian=" + endianness);
- }
+ var endianness = input.cpp.endianness;
+ if (endianness && supportEndianness(architecture))
+ args.push("--endian=" + endianness);
// Listing files generation flag.
if (input.cpp.generateCompilerListingFiles)
@@ -675,6 +796,16 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
// Output.
args.push("-o", outputs.obj[0].filePath);
+ var architecture = input.qbs.architecture;
+
+ // The `--preinclude` flag is only supported for a certain
+ // set of assemblers, not for all.
+ if (supportIAssembler(architecture)) {
+ var prefixHeaders = input.cpp.prefixHeaders;
+ for (var i in prefixHeaders)
+ args.push("--preinclude", prefixHeaders[i]);
+ }
+
// Includes.
var allIncludePaths = [];
var systemIncludePaths = input.cpp.systemIncludePaths;
@@ -690,12 +821,7 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("-r");
// Architecture specific flags.
- var architecture = input.qbs.architecture;
- if (architecture === "stm8" || architecture === "rl78"
- || architecture === "rx" || architecture === "rh850"
- || architecture === "avr32" || architecture === "sh"
- || architecture === "riscv" || architecture === "m68k"
- || architecture === "r32c" || architecture === "cr16") {
+ if (supportIAssembler(architecture)) {
// Silent output generation flag.
args.push("--silent");
// Warning level flags.
@@ -703,13 +829,18 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("--no_warnings");
if (input.cpp.treatWarningsAsErrors)
args.push("--warnings_are_errors");
- } else {
+ } else if (supportXAssembler(architecture)){
// Silent output generation flag.
args.push("-S");
// Warning level flags.
args.push("-w" + (input.cpp.warningLevel === "none" ? "-" : "+"));
}
+ // Byte order flags.
+ var endianness = input.cpp.endianness;
+ if (endianness && supportEndianness(architecture))
+ args.push("--endian=" + endianness);
+
// Listing files generation flag.
if (input.cpp.generateAssemblerListingFiles)
args.push("-l", outputs.lst[0].filePath);
diff --git a/share/qbs/modules/cpp/iar.qbs b/share/qbs/modules/cpp/iar.qbs
index 519d30f2a..26f7b96f3 100644
--- a/share/qbs/modules/cpp/iar.qbs
+++ b/share/qbs/modules/cpp/iar.qbs
@@ -64,8 +64,7 @@ CppModule {
compilerDefinesByLanguage: iarProbe.compilerDefinesByLanguage
compilerIncludePaths: iarProbe.includePaths
- property string toolchainInstallPath: compilerPathProbe.found
- ? compilerPathProbe.path : undefined
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
diff --git a/share/qbs/modules/cpp/keil.js b/share/qbs/modules/cpp/keil.js
index 1e8169853..7303a5453 100644
--- a/share/qbs/modules/cpp/keil.js
+++ b/share/qbs/modules/cpp/keil.js
@@ -534,7 +534,7 @@ function collectLibraryDependencies(product) {
if (!obj.cpp)
return;
function ensureArray(a) {
- return Array.isArray(a) ? a : [];
+ return (a instanceof Array) ? a : [];
}
function sanitizedModuleListProperty(obj, moduleName, propertyName) {
return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
diff --git a/share/qbs/modules/cpp/keil.qbs b/share/qbs/modules/cpp/keil.qbs
index eba52adff..66233fc84 100644
--- a/share/qbs/modules/cpp/keil.qbs
+++ b/share/qbs/modules/cpp/keil.qbs
@@ -62,8 +62,7 @@ CppModule {
compilerDefinesByLanguage: keilProbe.compilerDefinesByLanguage
compilerIncludePaths: keilProbe.includePaths
- property string toolchainInstallPath: compilerPathProbe.found
- ? compilerPathProbe.path : undefined
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index df1f5eb5b..566059610 100644
--- a/share/qbs/modules/cpp/msvc.js
+++ b/share/qbs/modules/cpp/msvc.js
@@ -354,7 +354,7 @@ function collectLibraryDependencies(product) {
if (!obj.cpp)
return;
function ensureArray(a) {
- return Array.isArray(a) ? a : [];
+ return (a instanceof Array) ? a : [];
}
function sanitizedModuleListProperty(obj, moduleName, propertyName) {
return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
diff --git a/share/qbs/modules/cpp/sdcc.js b/share/qbs/modules/cpp/sdcc.js
index 36454031e..6f5fcc3d6 100644
--- a/share/qbs/modules/cpp/sdcc.js
+++ b/share/qbs/modules/cpp/sdcc.js
@@ -50,6 +50,8 @@ function assemblerName(qbs) {
return "sdas8051";
case "stm8":
return "sdasstm8";
+ case "hcs8":
+ return "sdas6808";
}
throw "Unable to deduce assembler name for unsupported architecture: '"
+ qbs.architecture + "'";
@@ -61,6 +63,8 @@ function linkerName(qbs) {
return "sdld";
case "stm8":
return "sdldstm8";
+ case "hcs8":
+ return "sdld6808";
}
throw "Unable to deduce linker name for unsupported architecture: '"
+ qbs.architecture + "'";
@@ -75,6 +79,8 @@ function targetArchitectureFlag(architecture) {
return "-mmcs51";
if (architecture === "stm8")
return "-mstm8";
+ if (architecture === "hcs8")
+ return "-mhc08";
}
function guessArchitecture(macros) {
@@ -82,6 +88,8 @@ function guessArchitecture(macros) {
return "mcs51";
if (macros["__SDCC_stm8"] === "1")
return "stm8";
+ if (macros["__SDCC_hc08"] === "1")
+ return "hcs8";
}
function guessEndianness(macros) {
@@ -142,7 +150,8 @@ function dumpDefaultPaths(compilerFilePath, architecture) {
|| line.startsWith("libpath:")) {
addIncludePaths = false;
} else if (addIncludePaths) {
- includePaths.push(line);
+ if (File.exists(line))
+ includePaths.push(line);
}
}
@@ -193,7 +202,7 @@ function collectLibraryDependencies(product) {
if (!obj.cpp)
return;
function ensureArray(a) {
- return Array.isArray(a) ? a : [];
+ return (a instanceof Array) ? a : [];
}
function sanitizedModuleListProperty(obj, moduleName, propertyName) {
return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
diff --git a/share/qbs/modules/cpp/sdcc.qbs b/share/qbs/modules/cpp/sdcc.qbs
index da1b89402..a44cee808 100644
--- a/share/qbs/modules/cpp/sdcc.qbs
+++ b/share/qbs/modules/cpp/sdcc.qbs
@@ -63,8 +63,7 @@ CppModule {
compilerDefinesByLanguage: sdccProbe.compilerDefinesByLanguage
compilerIncludePaths: sdccProbe.includePaths
- property string toolchainInstallPath: compilerPathProbe.found
- ? compilerPathProbe.path : undefined
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs
index e88c3f15f..c103ee691 100644
--- a/share/qbs/modules/cpp/windows-msvc-base.qbs
+++ b/share/qbs/modules/cpp/windows-msvc-base.qbs
@@ -81,7 +81,6 @@ CppModule {
separateDebugInformation: true
property bool generateManifestFile: true
- property string toolchainInstallPath
architecture: qbs.architecture
endianness: "little"
diff --git a/share/qbs/modules/ico/ico.js b/share/qbs/modules/ico/ico.js
index 997a6dc23..a61d585ab 100644
--- a/share/qbs/modules/ico/ico.js
+++ b/share/qbs/modules/ico/ico.js
@@ -29,6 +29,7 @@
****************************************************************************/
var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
var Process = require("qbs.Process");
function prepareIconset(project, product, inputs, outputs, input, output) {
diff --git a/share/qbs/modules/java/JavaModule.qbs b/share/qbs/modules/java/JavaModule.qbs
index ad055fe34..ceb29f36f 100644
--- a/share/qbs/modules/java/JavaModule.qbs
+++ b/share/qbs/modules/java/JavaModule.qbs
@@ -240,7 +240,7 @@ Module {
if (!product.java._tagJniHeaders) {
for (var i = 0; i < artifacts.length; ++i) {
var a = artifacts[i];
- if (Array.isArray(a.fileTags))
+ if (a.fileTags instanceof Array)
a.fileTags = a.fileTags.map(function(tag) {
if (tag === "hpp")
return "java.jni-hpp";
diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
index 47d1a60c1..12d4e159f 100644
--- a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
+++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
@@ -12,6 +12,8 @@ ProtobufBase {
property bool useGrpc: false
+ property bool _linkLibraries: true
+
property string grpcIncludePath: grpcIncludeProbe.path
property string grpcLibraryPath: grpcLibraryProbe.path
@@ -33,6 +35,9 @@ ProtobufBase {
}
cpp.libraryPaths: {
+ if (!_linkLibraries)
+ return [];
+
var result = [];
if (libraryPath)
result.push(libraryPath);
@@ -41,6 +46,9 @@ ProtobufBase {
return result;
}
cpp.dynamicLibraries: {
+ if (!_linkLibraries)
+ return [];
+
var result = [];
if (_libraryName)
result.push(_libraryName)
@@ -51,6 +59,9 @@ ProtobufBase {
return result;
}
cpp.includePaths: {
+ if (!_linkLibraries)
+ return [outputDir];
+
var result = [outputDir];
if (includePath)
result.push(includePath);
@@ -118,17 +129,17 @@ ProtobufBase {
validate: {
HelperFunctions.validateCompiler(compilerName, compilerPath);
- if (!HelperFunctions.checkPath(includePath))
+ if (_linkLibraries && !HelperFunctions.checkPath(includePath))
throw "Can't find cpp protobuf include files. Please set the includePath property.";
- if (!HelperFunctions.checkPath(libraryPath))
+ if (_linkLibraries && !HelperFunctions.checkPath(libraryPath))
throw "Can't find cpp protobuf library. Please set the libraryPath property.";
if (useGrpc) {
if (!File.exists(grpcPluginPath))
throw "Can't find grpc_cpp_plugin plugin. Please set the grpcPluginPath property.";
- if (!HelperFunctions.checkPath(grpcIncludePath))
+ if (_linkLibraries && !HelperFunctions.checkPath(grpcIncludePath))
throw "Can't find grpc++ include files. Please set the grpcIncludePath property.";
- if (!HelperFunctions.checkPath(grpcLibraryPath))
+ if (_linkLibraries && !HelperFunctions.checkPath(grpcLibraryPath))
throw "Can't find grpc++ library. Please set the grpcLibraryPath property.";
}
}
diff --git a/share/qbs/modules/xcode/xcode.js b/share/qbs/modules/xcode/xcode.js
index 9c87e09dc..1060894d4 100644
--- a/share/qbs/modules/xcode/xcode.js
+++ b/share/qbs/modules/xcode/xcode.js
@@ -93,6 +93,16 @@ var XcodeArchSpecsReader = (function () {
return XcodeArchSpecsReader;
}());
+function platformInfo(platformInfoPlist) {
+ var propertyList = new PropertyList();
+ try {
+ propertyList.readFromFile(platformInfoPlist);
+ return propertyList.toObject();
+ } finally {
+ propertyList.clear();
+ }
+}
+
function sdkInfoList(sdksPath) {
var sdkInfo = [];
var sdks = File.directoryEntries(sdksPath, File.Dirs | File.NoDotAndDotDot);
@@ -181,6 +191,17 @@ function provisioningProfilePlistContents(filePath) {
}
}
+function boolFromSdkOrPlatform(varName, sdkProps, platformProps, defaultValue) {
+ var values = [(sdkProps || {})[varName], (platformProps || {})[varName]];
+ for (var i = 0; i < values.length; ++i) {
+ if (values[i] === "YES")
+ return true;
+ if (values[i] === "NO")
+ return false;
+ }
+ return defaultValue;
+}
+
function archsSpecsPath(version, targetOS, platformType, platformPath, devicePlatformPath) {
var _specsPluginBaseName;
if (Utilities.versionCompare(version, "12") >= 0) {
diff --git a/share/qbs/modules/xcode/xcode.qbs b/share/qbs/modules/xcode/xcode.qbs
index aeb0760ac..6c0584c81 100644
--- a/share/qbs/modules/xcode/xcode.qbs
+++ b/share/qbs/modules/xcode/xcode.qbs
@@ -7,7 +7,6 @@ import qbs.ModUtils
import qbs.Probes
import qbs.PropertyList
import qbs.Utilities
-import 'xcode.js' as Xcode
Module {
id: xcodeModule
@@ -87,31 +86,6 @@ Module {
}
}
- property string signingIdentity
- readonly property string actualSigningIdentity: {
- if (_actualSigningIdentity && _actualSigningIdentity.length === 2)
- return _actualSigningIdentity[0];
- }
-
- readonly property string actualSigningIdentityDisplayName: {
- if (_actualSigningIdentity && _actualSigningIdentity.length === 2)
- return _actualSigningIdentity[1];
- }
-
- property string signingTimestamp: "none"
-
- property string provisioningProfile
-
- property string xcodebuildName: "xcodebuild"
- property string xcodebuildPath: FileInfo.joinPaths(developerPath, "usr", "bin", xcodebuildName)
-
- property string securityName: "security"
- property string securityPath: securityName
-
- property string codesignName: "codesign"
- property string codesignPath: codesignName
- property stringList codesignFlags
-
readonly property path toolchainPath: FileInfo.joinPaths(toolchainsPath,
"XcodeDefault" + ".xctoolchain")
readonly property path platformPath: FileInfo.joinPaths(platformsPath,
@@ -143,35 +117,11 @@ Module {
readonly property path toolchainInfoPlist: FileInfo.joinPaths(toolchainPath,
"ToolchainInfo.plist")
- readonly property stringList _actualSigningIdentity: {
- if (/^[A-Fa-f0-9]{40}$/.test(signingIdentity)) {
- return [signingIdentity, signingIdentity];
- }
-
- var result = [];
+ readonly property var _platformSettings: xcodeProbe.platformSettings
- if (signingIdentity) {
- var identities = Utilities.signingIdentities();
- for (var key in identities) {
- if (identities[key].subjectInfo.CN === signingIdentity) {
- result.push([key, signingIdentity]);
- }
- }
-
- if (result.length == 0) {
- throw "Unable to find signingIdentity '" + signingIdentity + "'";
- }
-
- if (result.length > 1) {
- throw "Signing identity '" + signingIdentity + "' is ambiguous";
- }
- }
-
- return result[0];
- }
-
- property path provisioningProfilesPath: {
- return FileInfo.joinPaths(Environment.getEnv("HOME"), "Library/MobileDevice/Provisioning Profiles");
+ readonly property var _platformProps: {
+ if (_platformSettings)
+ return _platformSettings["DefaultProperties"];
}
readonly property stringList standardArchitectures: _architectureSettings["ARCHS_STANDARD"]
@@ -197,6 +147,12 @@ Module {
}
}
+ readonly property var _sdkProps: {
+ if (_sdkSettings) {
+ return _sdkSettings["DefaultProperties"];
+ }
+ }
+
qbs.sysroot: sdkPath
validate: {
@@ -231,23 +187,10 @@ Module {
validator.validate();
}
- property var buildEnv: {
- var env = {
- "DEVELOPER_DIR": developerPath,
- "SDKROOT": sdkPath
- };
-
- var prefixes = [platformPath + "/Developer", toolchainPath, developerPath];
- for (var i = 0; i < prefixes.length; ++i) {
- var codesign_allocate = prefixes[i] + "/usr/bin/codesign_allocate";
- if (File.exists(codesign_allocate)) {
- env["CODESIGN_ALLOCATE"] = codesign_allocate;
- break;
- }
- }
-
- return env;
- }
+ property var buildEnv: ({
+ "DEVELOPER_DIR": developerPath,
+ "SDKROOT": sdkPath
+ })
setupBuildEnvironment: {
var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, false);
@@ -261,191 +204,4 @@ Module {
v.set();
}
}
-
- Group {
- name: "Provisioning Profiles"
- prefix: xcode.provisioningProfilesPath + "/"
- files: ["*.mobileprovision", "*.provisionprofile"]
- fileTags: ["xcode.provisioningprofile"]
- }
-
- FileTagger {
- fileTags: ["xcode.entitlements"]
- patterns: ["*.entitlements"]
- }
-
- FileTagger {
- fileTags: ["xcode.provisioningprofile"]
- patterns: ["*.mobileprovision", "*.provisionprofile"]
- }
-
- Rule {
- inputs: ["xcode.provisioningprofile"]
-
- Artifact {
- filePath: FileInfo.joinPaths("provisioning-profiles", input.fileName + ".xml")
- fileTags: ["xcode.provisioningprofile.data"]
- }
-
- prepare: {
- var cmds = [];
-
- var cmd = new Command("openssl", ["smime", "-verify", "-noverify", "-inform", "DER",
- "-in", input.filePath, "-out", output.filePath]);
- cmd.silent = true;
- cmd.stderrFilterFunction = function (output) {
- return output.replace("Verification successful\n", "");
- };
- cmds.push(cmd);
-
- cmd = new JavaScriptCommand();
- cmd.silent = true;
- cmd.inputFilePath = input.filePath;
- cmd.outputFilePath = output.filePath;
- cmd.sourceCode = function() {
- var propertyList = new PropertyList();
- try {
- propertyList.readFromFile(outputFilePath);
- propertyList.readFromObject({
- data: propertyList.toObject(),
- fileName: FileInfo.fileName(inputFilePath),
- filePath: inputFilePath
- });
- propertyList.writeToFile(outputFilePath, "xml1");
- } finally {
- propertyList.clear();
- }
- };
- cmds.push(cmd);
-
- return cmds;
- }
- }
-
- Rule {
- multiplex: true
- inputs: ["xcode.provisioningprofile.data"]
- outputFileTags: ["xcode.provisioningprofile.main", "xcode.provisioningprofile.data.main"]
-
- outputArtifacts: {
- var artifacts = [];
- for (var i = 0; i < inputs["xcode.provisioningprofile.data"].length; ++i) {
- var dataFile = inputs["xcode.provisioningprofile.data"][i].filePath;
- var query = product.moduleProperty("xcode", "provisioningProfile");
- var obj = Xcode.provisioningProfilePlistContents(dataFile);
- if (obj && obj.data && (obj.data.UUID === query || obj.data.Name === query)) {
- console.log("Using provisioning profile: " + obj.filePath);
- artifacts.push({
- filePath: obj.fileName,
- fileTags: ["xcode.provisioningprofile.main"],
- qbs: { _inputFilePath: obj.filePath }
- });
-
- artifacts.push({
- filePath: obj.fileName + ".xml",
- fileTags: ["xcode.provisioningprofile.data.main"],
- qbs: { _inputFilePath: dataFile }
- });
- }
- }
- return artifacts;
- }
-
- prepare: {
- var cmds = [];
- for (var tag in outputs) {
- for (var i = 0; i < outputs[tag].length; ++i) {
- var output = outputs[tag][i];
- var cmd = new JavaScriptCommand();
- cmd.silent = true;
- cmd.inputFilePath = output.qbs._inputFilePath; // there's no such prop in qbs, see QBS-754
- cmd.outputFilePath = output.filePath;
- cmd.sourceCode = function() {
- File.copy(inputFilePath, outputFilePath);
- };
- cmds.push(cmd);
- }
- }
- return cmds;
- }
- }
-
- Rule {
- inputs: ["xcode.entitlements", "xcode.provisioningprofile.data.main"]
-
- Artifact {
- filePath: FileInfo.joinPaths(product.destinationDirectory,
- product.targetName + ".xcent")
- fileTags: ["xcent"]
- }
-
- prepare: {
- var cmd = new JavaScriptCommand();
- cmd.description = "generating entitlements";
- cmd.highlight = "codegen";
- cmd.bundleIdentifier = product.moduleProperty("bundle", "identifier");
- cmd.signingEntitlements = inputs["xcode.entitlements"]
- ? inputs["xcode.entitlements"].map(function (a) { return a.filePath; })
- : [];
- cmd.platformPath = ModUtils.moduleProperty(product, "platformPath");
- cmd.sdkPath = ModUtils.moduleProperty(product, "sdkPath");
- cmd.sourceCode = function() {
- var i;
- var provData = Xcode.provisioningProfilePlistContents(input.filePath);
- if (provData)
- provData = provData.data;
-
- var aggregateEntitlements = {};
-
- // Start building up an aggregate entitlements plist from the files in the SDKs,
- // which contain placeholders in the same manner as Info.plist
- function entitlementsFileContents(path) {
- return File.exists(path) ? BundleTools.infoPlistContents(path) : undefined;
- }
- var entitlementsSources = [
- entitlementsFileContents(FileInfo.joinPaths(platformPath, "Entitlements.plist")),
- entitlementsFileContents(FileInfo.joinPaths(sdkPath, "Entitlements.plist"))
- ];
-
- for (i = 0; i < signingEntitlements.length; ++i) {
- entitlementsSources.push(entitlementsFileContents(signingEntitlements[i]));
- }
-
- for (i = 0; i < entitlementsSources.length; ++i) {
- var contents = entitlementsSources[i];
- for (var key in contents) {
- if (contents.hasOwnProperty(key))
- aggregateEntitlements[key] = contents[key];
- }
- }
-
- contents = provData["Entitlements"];
- for (key in contents) {
- if (contents.hasOwnProperty(key) && !aggregateEntitlements.hasOwnProperty(key))
- aggregateEntitlements[key] = contents[key];
- }
-
- // Expand entitlements variables with data from the provisioning profile
- var env = {
- "AppIdentifierPrefix": provData["ApplicationIdentifierPrefix"] + ".",
- "CFBundleIdentifier": bundleIdentifier
- };
- DarwinTools.expandPlistEnvironmentVariables(aggregateEntitlements, env, true);
-
- // Anything with an undefined or otherwise empty value should be removed
- // Only JSON-formatted plists can have null values, other formats error out
- // This also follows Xcode behavior
- DarwinTools.cleanPropertyList(aggregateEntitlements);
-
- var plist = new PropertyList();
- try {
- plist.readFromObject(aggregateEntitlements);
- plist.writeToFile(outputs.xcent[0].filePath, "xml1");
- } finally {
- plist.clear();
- }
- };
- return [cmd];
- }
- }
}