aboutsummaryrefslogtreecommitdiffstats
path: root/share/qbs
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@theqtcompany.com>2015-09-20 01:11:22 -0700
committerJake Petroules <jake.petroules@theqtcompany.com>2015-09-25 07:37:42 +0000
commit010637125b556223fbb70f5c8ab49cea07220fe7 (patch)
tree08a2b1a20168cfcefcda02622b715184bd514b24 /share/qbs
parent8efec0f4a04058a728d18aac0ee8c34f1ba0f971 (diff)
Add support for entitlements to the code signing process.
Change-Id: I14111b46f0b0a864a27b86618ad716b35c074d64 Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
Diffstat (limited to 'share/qbs')
-rw-r--r--share/qbs/modules/bundle/BundleModule.qbs34
-rw-r--r--share/qbs/modules/cpp/gcc.js12
-rw-r--r--share/qbs/modules/xcode/xcode.qbs89
3 files changed, 118 insertions, 17 deletions
diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs
index e5b6c414c..414a55222 100644
--- a/share/qbs/modules/bundle/BundleModule.qbs
+++ b/share/qbs/modules/bundle/BundleModule.qbs
@@ -400,8 +400,9 @@ Module {
condition: qbs.targetOS.contains("darwin")
multiplex: true
inputs: ["infoplist", "pkginfo", "hpp",
- "icns", "resourcerules",
- "compiled_ibdoc", "compiled_assetcatalog"]
+ "icns", "resourcerules", "xcent",
+ "compiled_ibdoc", "compiled_assetcatalog",
+ "xcode.provisioningprofile"]
outputFileTags: ["bundle",
"bundle.symlink.headers", "bundle.symlink.private-headers",
@@ -416,14 +417,13 @@ Module {
fileTags: ["bundle"]
});
- var provisioningProfilePath = product.moduleProperty("xcode",
- "provisioningProfilePath");
- if (provisioningProfilePath) {
- var ext = product.moduleProperty("qbs", "targetOS").contains("osx")
- ? "provisionprofile"
- : "mobileprovision";
+ for (i in inputs["xcode.provisioningprofile"]) {
+ var ext = inputs["xcode.provisioningprofile"][i].fileName.split('.')[1];
artifacts.push({
- filePath: FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "contentsFolderPath"), "embedded." + ext),
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ ModUtils.moduleProperty(product,
+ "contentsFolderPath"),
+ "embedded." + ext),
fileTags: ["bundle.provisioningprofile"]
});
}
@@ -560,7 +560,7 @@ Module {
cmd = new JavaScriptCommand();
cmd.description = "copying provisioning profile";
cmd.highlight = "filegen";
- cmd.source = product.moduleProperty("xcode", "provisioningProfilePath");
+ cmd.source = inputs["xcode.provisioningprofile"][i].filePath;
cmd.destination = provisioningProfiles[i].filePath;
cmd.sourceCode = function() {
File.copy(source, destination);
@@ -623,10 +623,16 @@ Module {
subpath = subpath.substring(subpath.indexOf(ModUtils.moduleProperty("qbs", "pathSeparator")));
}
- cmd = new Command(product.moduleProperty("xcode", "codesignPath"),
- (product.moduleProperty("xcode", "codesignFlags") || [])
- .concat(["--force", "--sign", actualSigningIdentity,
- bundles[i].filePath + subpath]));
+ var args = product.moduleProperty("xcode", "codesignFlags") || [];
+ args.push("--force");
+ args.push("--sign", actualSigningIdentity);
+ for (var j in inputs.xcent) {
+ args.push("--entitlements", inputs.xcent[j].filePath);
+ break; // there should only be one
+ }
+ args.push(bundles[i].filePath + subpath);
+
+ cmd = new Command(product.moduleProperty("xcode", "codesignPath"), args);
cmd.description = "codesign "
+ ModUtils.moduleProperty(product, "bundleName")
+ " using " + codesignDisplayName
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 626bb588c..3f48c4dd1 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -762,9 +762,15 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var actualSigningIdentity = product.moduleProperty("xcode", "actualSigningIdentity");
var codesignDisplayName = product.moduleProperty("xcode", "actualSigningIdentityDisplayName");
if (actualSigningIdentity && !product.moduleProperty("bundle", "isBundle")) {
- cmd = new Command(product.moduleProperty("xcode", "codesignPath"),
- ["--force", "--sign", actualSigningIdentity,
- primaryOutput.filePath]);
+ var args = product.moduleProperty("xcode", "codesignFlags") || [];
+ args.push("--force");
+ args.push("--sign", actualSigningIdentity);
+ 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.moduleProperty("xcode", "codesignPath"), args);
cmd.description = "codesign "
+ primaryOutput.fileName
+ " using " + codesignDisplayName
diff --git a/share/qbs/modules/xcode/xcode.qbs b/share/qbs/modules/xcode/xcode.qbs
index 06e11c354..d1324bf3b 100644
--- a/share/qbs/modules/xcode/xcode.qbs
+++ b/share/qbs/modules/xcode/xcode.qbs
@@ -1,8 +1,10 @@
import qbs
+import qbs.BundleTools
import qbs.File
import qbs.FileInfo
import qbs.DarwinTools
import qbs.ModUtils
+import qbs.PropertyList
import 'xcode.js' as Utils
Module {
@@ -60,6 +62,8 @@ Module {
return _actualSigningIdentity[0][1];
}
+ property path signingEntitlements
+
property string provisioningProfile
property path provisioningProfilePath: {
var files = _availableProvisioningProfiles;
@@ -205,4 +209,89 @@ Module {
v.set();
}
}
+
+ Group {
+ name: "Provisioning Profile"
+ files: xcode.provisioningProfilePath
+ ? [xcode.provisioningProfilePath]
+ : []
+ }
+
+ FileTagger {
+ fileTags: ["xcode.provisioningprofile"]
+ patterns: ["*.mobileprovision", "*.provisionprofile"]
+ }
+
+ Rule {
+ multiplex: true
+ inputs: ["xcode.provisioningprofile"]
+
+ 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 = ModUtils.moduleProperty(product, "signingEntitlements");
+ cmd.platformPath = ModUtils.moduleProperty(product, "platformPath");
+ cmd.sdkPath = ModUtils.moduleProperty(product, "sdkPath");
+ cmd.sourceCode = function() {
+ var provData = Utils.readProvisioningProfileData(
+ inputs["xcode.provisioningprofile"][0].filePath);
+
+ 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")),
+ entitlementsFileContents(signingEntitlements)
+ ];
+
+ for (var 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];
+ }
+ }
}