aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Peter Schmitt <schmitt@google.com>2016-03-21 18:35:30 +0000
committerGravatar Lukacs Berki <lberki@google.com>2016-03-22 08:08:59 +0000
commit604b7a615ac9af7475e0155abff2ab387e6a1487 (patch)
tree0300461fb1f334d1ac606494b9618642fa034800 /src
parenteab1ce2b95555ad506e21aa6a565a628fab4c331 (diff)
Allow passing custom entitlements for iOS signing.
RELNOTES[NEW]: --extra_entitlements allows passing additional entitlements for iOS signing -- MOS_MIGRATED_REVID=117735783
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/PlMergeControlBytes.java96
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java77
6 files changed, 184 insertions, 30 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java
index afbfb93c0b..3900c701a0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java
@@ -117,8 +117,8 @@ final class BundleSupport {
if (bundling.needsToMergeInfoplist()) {
NestedSet<Artifact> mergingContentArtifacts = bundling.getMergingContentArtifacts();
Artifact mergedPlist = bundling.getBundleInfoplist().get();
- PlMergeControlBytes plMergeControlBytes = new PlMergeControlBytes(bundling, mergedPlist);
- registerMergeInfoplistAction(mergingContentArtifacts, plMergeControlBytes);
+ registerMergeInfoplistAction(
+ mergingContentArtifacts, PlMergeControlBytes.fromBundling(bundling, mergedPlist));
}
return this;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
index 9aa540d837..123a7f84da 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
@@ -16,8 +16,10 @@ package com.google.devtools.build.lib.rules.objc;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration.LabelConverter;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
import com.google.devtools.build.lib.rules.apple.DottedVersion;
import com.google.devtools.build.lib.rules.apple.DottedVersionConverter;
@@ -181,6 +183,17 @@ public class ObjcCommandLineOptions extends FragmentOptions {
+ " GLIBCXX_DEBUG_PEDANTIC and GLIBCPP_CONCEPT_CHECKS."
)
public boolean debugWithGlibcxx;
+
+ @Option(
+ name = "extra_entitlements",
+ defaultValue = "null",
+ category = "flags",
+ converter = LabelConverter.class,
+ help =
+ "Location of a .entitlements file that is merged into any iOS signing action in this "
+ + "build."
+ )
+ public Label extraEntitlements;
@VisibleForTesting static final String DEFAULT_MINIMUM_IOS = "7.0";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
index a45dc41b11..6f12170998 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.rules.apple.DottedVersion;
import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.SplitArchTransition.ConfigurationDistinguisher;
@@ -69,6 +70,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment {
private final boolean useAbsolutePathsForActions;
private final boolean prioritizeStaticLibs;
private final boolean debugWithGlibcxx;
+ @Nullable private final Label extraEntitlements;
ObjcConfiguration(ObjcCommandLineOptions objcOptions, BuildConfiguration.Options options,
@Nullable BlazeDirectories directories) {
@@ -92,6 +94,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment {
this.useAbsolutePathsForActions = objcOptions.useAbsolutePathsForActions;
this.prioritizeStaticLibs = objcOptions.prioritizeStaticLibs;
this.debugWithGlibcxx = objcOptions.debugWithGlibcxx;
+ this.extraEntitlements = objcOptions.extraEntitlements;
}
/**
@@ -244,4 +247,12 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment {
public boolean shouldPrioritizeStaticLibs() {
return this.prioritizeStaticLibs;
}
+
+ /**
+ * Returns the extra entitlements plist specified as a flag or {@code null} if none was given.
+ */
+ @Nullable
+ public Label getExtraEntitlements() {
+ return extraEntitlements;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index 461c06d11f..4ffe5589a5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -797,6 +797,19 @@ public class ObjcRuleClasses {
$(AppIdentifierPrefix) and $(CFBundleIdentifier).
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("entitlements", LABEL).legacyAllowAnyFileType())
+ .add(
+ attr(":extra_entitlements", LABEL)
+ .singleArtifact()
+ .value(
+ new LateBoundLabel<BuildConfiguration>(ObjcConfiguration.class) {
+ @Override
+ public Label getDefault(
+ Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
+ return configuration
+ .getFragment(ObjcConfiguration.class)
+ .getExtraEntitlements();
+ }
+ }))
/* <!-- #BLAZE_RULE($objc_release_bundling_rule).ATTRIBUTE(provisioning_profile) -->
The provisioning profile (.mobileprovision file) to use when bundling
the application.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/PlMergeControlBytes.java b/src/main/java/com/google/devtools/build/lib/rules/objc/PlMergeControlBytes.java
index 4f2e0c15cf..548f6b6d04 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/PlMergeControlBytes.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/PlMergeControlBytes.java
@@ -14,61 +14,115 @@
package com.google.devtools.build.lib.rules.objc;
+import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteSource;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.xcode.plmerge.proto.PlMergeProtos;
import com.google.devtools.build.xcode.plmerge.proto.PlMergeProtos.Control;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Map;
+
+import javax.annotation.Nullable;
/**
* A byte source that can be used the generate a control file for the tool plmerge.
*/
public final class PlMergeControlBytes extends ByteSource {
- private final Bundling bundling;
+ private final NestedSet<Artifact> inputPlists;
+ private final NestedSet<Artifact> immutableInputPlists;
+ @Nullable private final String primaryBundleId;
+ @Nullable private final String fallbackBundleId;
+ @Nullable private final Map<String, String> variableSubstitutions;
+ @Nullable private final String executableName;
private final Artifact mergedPlist;
/**
- * @param bundling the {@code Bundling} instance describing the bundle
- * for which to create a merged plist
- * @param mergedPlist the merged plist that should be bundled as Info.plist
+ * Creates a control based on the passed bundling's plists and values.
+ *
+ * @param bundling bundle for which to create a merged plist
+ * @param mergedPlist the plist that should be created as an output
*/
- public PlMergeControlBytes(Bundling bundling, Artifact mergedPlist) {
- this.bundling = bundling;
+ static PlMergeControlBytes fromBundling(Bundling bundling, Artifact mergedPlist) {
+
+ NestedSetBuilder<Artifact> immutableInputPlists = NestedSetBuilder.stableOrder();
+ if (bundling.getAutomaticInfoPlist() != null) {
+ immutableInputPlists.add(bundling.getAutomaticInfoPlist());
+ }
+
+ return new PlMergeControlBytes(
+ NestedSetBuilder.<Artifact>stableOrder()
+ .addTransitive(bundling.getBundleInfoplistInputs())
+ .build(),
+ immutableInputPlists.build(),
+ bundling.getPrimaryBundleId(),
+ bundling.getFallbackBundleId(),
+ bundling.variableSubstitutions(),
+ bundling.getName(),
+ mergedPlist);
+ }
+
+ /**
+ * Creates a control that merges the given plists into the merged plist.
+ */
+ static PlMergeControlBytes fromPlists(NestedSet<Artifact> inputPlists, Artifact mergedPlist) {
+ return new PlMergeControlBytes(
+ inputPlists,
+ NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER),
+ null,
+ null,
+ ImmutableMap.<String, String>of(),
+ null,
+ mergedPlist);
+ }
+
+ private PlMergeControlBytes(
+ NestedSet<Artifact> inputPlists,
+ NestedSet<Artifact> immutableInputPlists,
+ @Nullable String primaryBundleId,
+ @Nullable String fallbackBundleId,
+ @Nullable Map<String, String> variableSubstitutions,
+ @Nullable String executableName,
+ Artifact mergedPlist) {
+ this.inputPlists = inputPlists;
+ this.immutableInputPlists = immutableInputPlists;
+ this.primaryBundleId = primaryBundleId;
+ this.fallbackBundleId = fallbackBundleId;
+ this.variableSubstitutions = variableSubstitutions;
+ this.executableName = executableName;
this.mergedPlist = mergedPlist;
}
@Override
public InputStream openStream() throws IOException {
- return control(bundling).toByteString().newInput();
+ return control().toByteString().newInput();
}
- private Control control(Bundling bundling) {
+ private Control control() {
PlMergeProtos.Control.Builder control =
PlMergeProtos.Control.newBuilder()
- .addAllSourceFile(Artifact.toExecPaths(bundling.getBundleInfoplistInputs()))
+ .addAllSourceFile(Artifact.toExecPaths(inputPlists))
+ .addAllImmutableSourceFile(Artifact.toExecPaths(immutableInputPlists))
+ .putAllVariableSubstitutionMap(variableSubstitutions)
.setOutFile(mergedPlist.getExecPathString());
- if (bundling.getAutomaticInfoPlist() != null) {
- control.addImmutableSourceFile(bundling.getAutomaticInfoPlist().getExecPathString());
+ if (primaryBundleId != null) {
+ control.setPrimaryBundleId(primaryBundleId);
}
- if (bundling.getPrimaryBundleId() != null) {
- control.setPrimaryBundleId(bundling.getPrimaryBundleId());
+ if (fallbackBundleId != null) {
+ control.setFallbackBundleId(fallbackBundleId);
}
- if (bundling.getFallbackBundleId() != null) {
- control.setFallbackBundleId(bundling.getFallbackBundleId());
+ if (executableName != null) {
+ control.setExecutableName(executableName);
}
- if (bundling.variableSubstitutions() != null) {
- control.putAllVariableSubstitutionMap(bundling.variableSubstitutions());
- }
-
- control.setExecutableName(bundling.getName());
-
return control.build();
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
index 795b967369..c6dc2740a8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
@@ -254,7 +254,6 @@ public final class ReleaseBundlingSupport {
* multi-architecture binary.
*
* @return this application support
- * @throws InterruptedException
*/
ReleaseBundlingSupport registerActions() throws InterruptedException {
bundleSupport.registerActions(objcProvider);
@@ -467,6 +466,23 @@ public final class ReleaseBundlingSupport {
return codesignCommandLineBuilder.toString();
}
+ /**
+ * Creates entitlement actions such that an entitlements file is generated in
+ * {@link IntermediateArtifacts#entitlements()} which can be used for signing in this bundle.
+ *
+ * <p>Entitlements are generated based on a plist-format entitlements file passed to this bundle's
+ * {@code entitlements} attribute or, if that is not set, entitlements extracted from the provided
+ * mobile provisioning profile. The team prefix is extracted from the provisioning profile and
+ * the following substitutions performed (assuming the prefix extracted was {@code PREFIX}):
+ * <ol>
+ * <li>"PREFIX.*" -> "PREFIX.BUNDLE_ID" (where BUNDLE_ID is this bundle's id)
+ * <li>"$(AppIdentifierPrefix)" -> "PREFIX."
+ * <li>"$(CFBundleIdentifier)" -> "BUNDLE_ID" (where BUNDLE_ID is this bundle's id)
+ * </ol>
+ *
+ * <p>Finally, if an entitlements file was provided via {@code --extra_entitlements} it is merged
+ * into the substituted entitlements.
+ */
private void registerEntitlementsActions() throws InterruptedException {
Artifact teamPrefixFile =
intermediateArtifacts.appendExtensionForEntitlementArtifact(".team_prefix_file");
@@ -479,7 +495,46 @@ public final class ReleaseBundlingSupport {
".entitlements_with_variables");
registerExtractEntitlementsAction(entitlementsNeedingSubstitution);
}
- registerEntitlementsVariableSubstitutionAction(entitlementsNeedingSubstitution, teamPrefixFile);
+
+ Artifact substitutedEntitlements = intermediateArtifacts.entitlements();
+ if (attributes.extraEntitlements() != null) {
+ substitutedEntitlements =
+ intermediateArtifacts.appendExtensionForEntitlementArtifact(".substituted");
+ registerMergeEntitlementsAction(substitutedEntitlements, attributes.extraEntitlements());
+ }
+
+ registerEntitlementsVariableSubstitutionAction(
+ entitlementsNeedingSubstitution, teamPrefixFile, substitutedEntitlements);
+ }
+
+ private void registerMergeEntitlementsAction(
+ Artifact substitutedEntitlements, Artifact extraEntitlements) {
+
+ PlMergeControlBytes controlBytes =
+ PlMergeControlBytes.fromPlists(
+ NestedSetBuilder.create(Order.STABLE_ORDER, substitutedEntitlements, extraEntitlements),
+ intermediateArtifacts.entitlements());
+
+ Artifact plMergeControlArtifact =
+ ObjcRuleClasses.artifactByAppendingToBaseName(ruleContext, ".merge-entitlements-control");
+
+ ruleContext.registerAction(
+ new BinaryFileWriteAction(
+ ruleContext.getActionOwner(),
+ plMergeControlArtifact,
+ controlBytes,
+ /*makeExecutable=*/ false));
+
+ ruleContext.registerAction(
+ new SpawnAction.Builder()
+ .setMnemonic("MergeEntitlementsFiles")
+ .setExecutable(attributes.plmerge())
+ .addArgument("--control")
+ .addInputArgument(plMergeControlArtifact)
+ .addInput(substitutedEntitlements)
+ .addInput(extraEntitlements)
+ .addOutput(intermediateArtifacts.entitlements())
+ .build(ruleContext));
}
/**
@@ -501,7 +556,6 @@ public final class ReleaseBundlingSupport {
* top level target in a blaze invocation.
*
* @return this application support
- * @throws InterruptedException
*/
ReleaseBundlingSupport addFilesToBuild(NestedSetBuilder<Artifact> filesToBuild)
throws InterruptedException {
@@ -532,7 +586,6 @@ public final class ReleaseBundlingSupport {
/**
* Creates the {@link XcTestAppProvider} that can be used if this application is used as an
* {@code xctest_app}.
- * @throws InterruptedException
*/
XcTestAppProvider xcTestAppProvider() throws InterruptedException {
// We want access to #import-able things from our test rig's dependency graph, but we don't
@@ -581,7 +634,6 @@ public final class ReleaseBundlingSupport {
/**
* Returns a {@link RunfilesSupport} that uses the provided runner script as the executable.
- * @throws InterruptedException
*/
RunfilesSupport runfilesSupport(Artifact runnerScript) throws InterruptedException {
Artifact ipaFile = ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA);
@@ -831,8 +883,7 @@ public final class ReleaseBundlingSupport {
}
private void registerEntitlementsVariableSubstitutionAction(
- Artifact inputEntitlements, Artifact prefix) {
- Artifact substitutedEntitlements = intermediateArtifacts.entitlements();
+ Artifact inputEntitlements, Artifact prefix, Artifact substitutedEntitlements) {
String escapedBundleId = ShellUtils.shellEscape(attributes.bundleId());
String shellCommand =
"set -e && "
@@ -990,6 +1041,11 @@ public final class ReleaseBundlingSupport {
return ruleContext.getPrerequisiteArtifact("entitlements", Mode.TARGET);
}
+ @Nullable
+ Artifact extraEntitlements() {
+ return ruleContext.getPrerequisiteArtifact(":extra_entitlements", Mode.TARGET);
+ }
+
NestedSet<? extends Artifact> dependentLinkedBinaries() {
if (ruleContext.attributes().getAttributeDefinition("binary") == null) {
return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
@@ -1008,6 +1064,13 @@ public final class ReleaseBundlingSupport {
return checkNotNull(ruleContext.getExecutablePrerequisite("$bundlemerge", Mode.HOST));
}
+ /**
+ * Returns a reference to the plmerge executable.
+ */
+ FilesToRunProvider plmerge() {
+ return ruleContext.getExecutablePrerequisite("$plmerge", Mode.HOST);
+ }
+
Artifact iossim() {
return checkNotNull(ruleContext.getPrerequisiteArtifact("$iossim", Mode.HOST));
}