aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java
new file mode 100644
index 0000000000..695dffc4d6
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java
@@ -0,0 +1,121 @@
+// Copyright 2014 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.rules.objc;
+
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.BUNDLE_FILE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.NESTED_BUNDLE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCDATAMODEL;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.ByteSource;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.xcode.bundlemerge.proto.BundleMergeProtos;
+import com.google.devtools.build.xcode.bundlemerge.proto.BundleMergeProtos.Control;
+import com.google.devtools.build.xcode.bundlemerge.proto.BundleMergeProtos.MergeZip;
+import com.google.devtools.build.xcode.bundlemerge.proto.BundleMergeProtos.VariableSubstitution;
+import com.google.devtools.build.xcode.common.TargetDeviceFamily;
+
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * A byte source that can be used to generate a control file for the tool:
+ * {@code //java/com/google/devtools/build/xcode/bundlemerge}. Note that this generates the control
+ * proto and bytes on-the-fly rather than eagerly. This is to prevent a copy of the bundle files and
+ * .xcdatamodels from being stored for each {@code objc_binary} (or any bundle) being built.
+ */
+final class BundleMergeControlBytes extends ByteSource {
+ private final Bundling rootBundling;
+ private final Artifact mergedIpa;
+ private final ObjcConfiguration objcConfiguration;
+ private final ImmutableSet<TargetDeviceFamily> families;
+
+ public BundleMergeControlBytes(
+ Bundling rootBundling, Artifact mergedIpa, ObjcConfiguration objcConfiguration,
+ ImmutableSet<TargetDeviceFamily> families) {
+ this.rootBundling = Preconditions.checkNotNull(rootBundling);
+ this.mergedIpa = Preconditions.checkNotNull(mergedIpa);
+ this.objcConfiguration = Preconditions.checkNotNull(objcConfiguration);
+ this.families = Preconditions.checkNotNull(families);
+ }
+
+ @Override
+ public InputStream openStream() {
+ return control("Payload/", "Payload/", rootBundling)
+ .toByteString()
+ .newInput();
+ }
+
+ private Control control(String mergeZipPrefix, String bundleDirPrefix, Bundling bundling) {
+ ObjcProvider objcProvider = bundling.getObjcProvider();
+ String bundleDir = bundleDirPrefix + bundling.getBundleDir();
+ mergeZipPrefix += bundling.getBundleDir() + "/";
+
+ BundleMergeProtos.Control.Builder control = BundleMergeProtos.Control.newBuilder()
+ .addAllBundleFile(BundleableFile.toBundleFiles(bundling.getExtraBundleFiles()))
+ .addAllBundleFile(BundleableFile.toBundleFiles(objcProvider.get(BUNDLE_FILE)))
+ .addAllSourcePlistFile(Artifact.toExecPaths(
+ bundling.getInfoplistMerging().getPlistWithEverything().asSet()))
+ // TODO(bazel-team): Add rule attribute for specifying targeted device family
+ .setMinimumOsVersion(objcConfiguration.getMinimumOs())
+ .setSdkVersion(objcConfiguration.getIosSdkVersion())
+ .setPlatform(objcConfiguration.getPlatform().name())
+ .setBundleRoot(bundleDir);
+
+ for (Artifact mergeZip : bundling.getMergeZips()) {
+ control.addMergeZip(MergeZip.newBuilder()
+ .setEntryNamePrefix(mergeZipPrefix)
+ .setSourcePath(mergeZip.getExecPathString())
+ .build());
+ }
+
+ for (Xcdatamodel datamodel : objcProvider.get(XCDATAMODEL)) {
+ control.addMergeZip(MergeZip.newBuilder()
+ .setEntryNamePrefix(mergeZipPrefix)
+ .setSourcePath(datamodel.getOutputZip().getExecPathString())
+ .build());
+ }
+ for (TargetDeviceFamily targetDeviceFamily : families) {
+ control.addTargetDeviceFamily(targetDeviceFamily.name());
+ }
+
+ Map<String, String> variableSubstitutions = bundling.variableSubstitutions();
+ for (String variable : variableSubstitutions.keySet()) {
+ control.addVariableSubstitution(VariableSubstitution.newBuilder()
+ .setName(variable)
+ .setValue(variableSubstitutions.get(variable))
+ .build());
+ }
+
+ control.setOutFile(mergedIpa.getExecPathString());
+
+ for (Artifact linkedBinary : bundling.getCombinedArchitectureBinary().asSet()) {
+ control
+ .addBundleFile(BundleMergeProtos.BundleFile.newBuilder()
+ .setSourceFile(linkedBinary.getExecPathString())
+ .setBundlePath(bundling.getName())
+ .setExternalFileAttribute(BundleableFile.EXECUTABLE_EXTERNAL_FILE_ATTRIBUTE)
+ .build())
+ .setExecutableName(bundling.getName());
+ }
+
+ for (Bundling nestedBundling : bundling.getObjcProvider().get(NESTED_BUNDLE)) {
+ control.addNestedBundle(control(mergeZipPrefix, "", nestedBundling));
+ }
+
+ return control.build();
+ }
+}