aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java196
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BundleableFile.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java72
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompiledResourceFile.java70
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java137
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java53
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java17
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java21
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ResourceSupport.java67
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodel.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodels.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java35
20 files changed, 345 insertions, 403 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
index 2608a9c0ab..67b4fb07de 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
@@ -98,6 +98,7 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
.registerActions()
.addXcodeSettings(xcodeProviderBuilder)
.addFilesToBuild(filesToBuild)
+ .validateResources()
.validateAttributes();
xcTestAppProvider = Optional.of(releaseBundlingSupport.xcTestAppProvider());
if (ObjcRuleClasses.objcConfiguration(ruleContext).getPlatform() == Platform.SIMULATOR) {
@@ -115,7 +116,6 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
}
new ResourceSupport(ruleContext)
- .registerActions(common.getStoryboards())
.validateAttributes()
.addXcodeSettings(xcodeProviderBuilder);
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
index 24c5f58660..38a1b332f3 100644
--- 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
@@ -16,7 +16,6 @@ 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;
@@ -80,12 +79,6 @@ final class BundleMergeControlBytes extends ByteSource {
.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());
}
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 4e20ddc6ee..822f53b781 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
@@ -14,14 +14,25 @@
package com.google.devtools.build.lib.rules.objc;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STRINGS;
+
import com.google.common.base.Optional;
+import com.google.common.base.Verify;
+import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
+import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraActoolArgs;
import com.google.devtools.build.lib.rules.objc.XcodeProvider.Builder;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
import java.util.Set;
/**
@@ -36,6 +47,7 @@ final class BundleSupport {
private final Set<TargetDeviceFamily> targetDeviceFamilies;
private final ExtraActoolArgs extraActoolArgs;
private final Bundling bundling;
+ private final Attributes attributes;
/**
* Returns merging instructions for a bundle's {@code Info.plist}.
@@ -87,6 +99,7 @@ final class BundleSupport {
this.targetDeviceFamilies = targetDeviceFamilies;
this.extraActoolArgs = extraActoolArgs;
this.bundling = bundling;
+ this.attributes = new Attributes(ruleContext);
}
/**
@@ -94,10 +107,13 @@ final class BundleSupport {
* Info.plist} files and generating asset catalogues.
*
* @param objcProvider source of information from this rule's attributes and its dependencies
- *
* @return this bundle support
*/
BundleSupport registerActions(ObjcProvider objcProvider) {
+ registerConvertStringsActions(objcProvider);
+ registerConvertXibsActions(objcProvider);
+ registerMomczipActions(objcProvider);
+ registerInterfaceBuilderActions(objcProvider);
registerMergeInfoplistAction();
registerActoolActionIfNecessary(objcProvider);
@@ -114,6 +130,153 @@ final class BundleSupport {
return this;
}
+ /**
+ * Validates that resources defined in this rule and its dependencies and written to this bundle
+ * are legal (for example that they are not mapped to the same bundle location).
+ *
+ * @return this bundle support
+ */
+ BundleSupport validateResources(ObjcProvider objcProvider) {
+ Map<String, Artifact> bundlePathToFile = new HashMap<>();
+ for (Artifact stringsFile : objcProvider.get(STRINGS)) {
+ String bundlePath = BundleableFile.flatBundlePath(stringsFile.getExecPath());
+
+ // Normally any two resources mapped to the same path in the bundle are illegal. However, we
+ // currently don't have a good solution for resources generated by a genrule in
+ // multi-architecture builds: They map to the same bundle path but have different owners (the
+ // genrules targets in the various configurations) and roots (one for each architecture).
+ // Since we know that architecture shouldn't matter for strings file generation we silently
+ // ignore cases like this and pick one of the outputs at random to put in the bundle (see also
+ // related filtering code in Bundling.Builder.build()).
+ if (bundlePathToFile.containsKey(bundlePath)) {
+ Artifact original = bundlePathToFile.get(bundlePath);
+ if (!Objects.equals(original.getOwner(), stringsFile.getOwner())) {
+ ruleContext.ruleError(String.format(
+ "Two string files map to the same path [%s] in this bundle but come from different "
+ + "locations: %s and %s",
+ bundlePath, original.getOwner(), stringsFile.getOwner()));
+ } else {
+ Verify.verify(!original.getRoot().equals(stringsFile.getRoot()),
+ "%s and %s should have different roots but have %s and %s",
+ original, stringsFile, original.getRoot(), stringsFile.getRoot());
+ }
+
+ } else {
+ bundlePathToFile.put(bundlePath, stringsFile);
+ }
+ }
+
+ // TODO(bazel-team): Do the same validation for storyboards and datamodels which could also be
+ // generated by genrules or doubly defined.
+
+ return this;
+ }
+
+ private void registerInterfaceBuilderActions(ObjcProvider objcProvider) {
+ IntermediateArtifacts intermediateArtifacts =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext);
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ String minimumOs = objcConfiguration.getMinimumOs();
+ for (Artifact storyboardInput : objcProvider.get(ObjcProvider.STORYBOARD)) {
+ String archiveRoot = BundleableFile.flatBundlePath(storyboardInput.getExecPath()) + "c";
+ Artifact zipOutput = intermediateArtifacts.compiledStoryboardZip(storyboardInput);
+
+ ruleContext.registerAction(
+ ObjcActionsBuilder.spawnJavaOnDarwinActionBuilder(attributes.ibtoolzipDeployJar())
+ .setMnemonic("StoryboardCompile")
+ .setCommandLine(CustomCommandLine.builder()
+ // The next three arguments are positional,
+ // i.e. they don't have flags before them.
+ .addPath(zipOutput.getExecPath())
+ .add(archiveRoot)
+ .addPath(ObjcActionsBuilder.IBTOOL)
+
+ .add("--minimum-deployment-target").add(minimumOs)
+ .addPath(storyboardInput.getExecPath())
+ .build())
+ .addOutput(zipOutput)
+ .addInput(storyboardInput)
+ .build(ruleContext));
+ }
+ }
+
+ private void registerMomczipActions(ObjcProvider objcProvider) {
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ IntermediateArtifacts intermediateArtifacts =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext);
+ Iterable<Xcdatamodel> xcdatamodels = Xcdatamodels.xcdatamodels(
+ intermediateArtifacts, objcProvider.get(ObjcProvider.XCDATAMODEL));
+ for (Xcdatamodel datamodel : xcdatamodels) {
+ Artifact outputZip = datamodel.getOutputZip();
+ ruleContext.registerAction(
+ ObjcActionsBuilder.spawnJavaOnDarwinActionBuilder(attributes.momczipDeployJar())
+ .setMnemonic("MomCompile")
+ .addOutput(outputZip)
+ .addInputs(datamodel.getInputs())
+ .setCommandLine(CustomCommandLine.builder()
+ .addPath(outputZip.getExecPath())
+ .add(datamodel.archiveRootForMomczip())
+ .add(IosSdkCommands.MOMC_PATH)
+ .add(commonMomczipArguments(objcConfiguration))
+ .add(datamodel.getContainer().getSafePathString())
+ .build())
+ .build(ruleContext));
+ }
+ }
+
+ static Iterable<String> commonMomczipArguments(ObjcConfiguration configuration) {
+ return ImmutableList.of(
+ "-XD_MOMC_SDKROOT=" + IosSdkCommands.sdkDir(configuration),
+ "-XD_MOMC_IOS_TARGET_VERSION=" + configuration.getMinimumOs(),
+ "-MOMC_PLATFORMS", configuration.getPlatform().getLowerCaseNameInPlist(),
+ "-XD_MOMC_TARGET_VERSION=10.6");
+ }
+
+ private void registerConvertXibsActions(ObjcProvider objcProvider) {
+ IntermediateArtifacts intermediateArtifacts =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext);
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ for (Artifact original : objcProvider.get(ObjcProvider.XIB)) {
+ Artifact zipOutput = intermediateArtifacts.compiledXibFileZip(original);
+ String archiveRoot = BundleableFile.flatBundlePath(
+ FileSystemUtils.replaceExtension(original.getExecPath(), ".nib"));
+ ruleContext.registerAction(
+ ObjcActionsBuilder.spawnJavaOnDarwinActionBuilder(attributes.ibtoolzipDeployJar())
+ .setMnemonic("XibCompile")
+ .setCommandLine(CustomCommandLine.builder()
+ // The next three arguments are positional,
+ // i.e. they don't have flags before them.
+ .addPath(zipOutput.getExecPath())
+ .add(archiveRoot)
+ .addPath(ObjcActionsBuilder.IBTOOL)
+
+ .add("--minimum-deployment-target").add(objcConfiguration.getMinimumOs())
+ .addPath(original.getExecPath())
+ .build())
+ .addOutput(zipOutput)
+ .addInput(original)
+ .build(ruleContext));
+ }
+ }
+
+ private void registerConvertStringsActions(ObjcProvider objcProvider) {
+ IntermediateArtifacts intermediateArtifacts =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext);
+ for (Artifact strings : objcProvider.get(ObjcProvider.STRINGS)) {
+ Artifact bundled = intermediateArtifacts.convertedStringsFile(strings);
+ ruleContext.registerAction(new SpawnAction.Builder()
+ .setMnemonic("ConvertStringsPlist")
+ .setExecutable(attributes.plmerge())
+ .setCommandLine(CustomCommandLine.builder()
+ .addExecPath("--source_file", strings)
+ .addExecPath("--out_file", bundled)
+ .build())
+ .addInput(strings)
+ .addOutput(bundled)
+ .build(ruleContext));
+ }
+ }
+
private void registerMergeInfoplistAction() {
// TODO(bazel-team): Move action implementation from InfoplistMerging to this class.
ruleContext.registerAction(bundling.getInfoplistMerging().getMergeAction());
@@ -157,4 +320,35 @@ final class BundleSupport {
}
}
+ /**
+ * Common rule attributes used by a bundle support.
+ */
+ private static class Attributes {
+ private final RuleContext ruleContext;
+
+ private Attributes(RuleContext ruleContext) {
+ this.ruleContext = ruleContext;
+ }
+
+ /**
+ * Returns a reference to the plmerge executable.
+ */
+ FilesToRunProvider plmerge() {
+ return ruleContext.getExecutablePrerequisite("$plmerge", Mode.HOST);
+ }
+
+ /**
+ * Returns the location of the ibtoolzip deploy jar.
+ */
+ Artifact ibtoolzipDeployJar() {
+ return ruleContext.getPrerequisiteArtifact("$ibtoolzip_deploy", Mode.HOST);
+ }
+
+ /**
+ * Returns the location of the momczip deploy jar.
+ */
+ Artifact momczipDeployJar() {
+ return ruleContext.getPrerequisiteArtifact("$momczip_deploy", Mode.HOST);
+ }
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleableFile.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleableFile.java
index ab6d89874f..e82891e89e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleableFile.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleableFile.java
@@ -139,10 +139,10 @@ public final class BundleableFile extends Value<BundleableFile> {
}
/**
- * The artifact that is ultimately bundled.
+ * Returns the location into which this file should be put in, relative to the bundle root.
*/
- public Artifact getBundled() {
- return bundled;
+ public String getBundlePath() {
+ return bundlePath;
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java
index acf40675d8..8b5edfdabb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java
@@ -20,11 +20,15 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIB
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MERGE_ZIP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.NESTED_BUNDLE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STORYBOARD;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STRINGS;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCDATAMODEL;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XIB;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
@@ -33,7 +37,9 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
/**
* Contains information regarding the creation of an iOS bundle.
@@ -43,7 +49,8 @@ final class Bundling {
static final class Builder {
private String name;
private String bundleDirFormat;
- private ImmutableList<BundleableFile> extraBundleFiles = ImmutableList.of();
+ private ImmutableList.Builder<BundleableFile> extraBundleFilesBuilder =
+ new ImmutableList.Builder<>();
private ObjcProvider objcProvider;
private InfoplistMerging infoplistMerging;
private IntermediateArtifacts intermediateArtifacts;
@@ -70,8 +77,8 @@ final class Bundling {
return this;
}
- public Builder setExtraBundleFiles(ImmutableList<BundleableFile> extraBundleFiles) {
- this.extraBundleFiles = extraBundleFiles;
+ public Builder addExtraBundleFiles(ImmutableList<BundleableFile> extraBundleFiles) {
+ this.extraBundleFilesBuilder.addAll(extraBundleFiles);
return this;
}
@@ -108,6 +115,21 @@ final class Bundling {
return artifacts.build();
}
+ private NestedSet<Artifact> getMergeZips(Optional<Artifact> actoolzipOutput) {
+ NestedSetBuilder<Artifact> mergeZipBuilder = NestedSetBuilder.<Artifact>stableOrder()
+ .addAll(actoolzipOutput.asSet())
+ .addAll(Xcdatamodel.outputZips(
+ Xcdatamodels.xcdatamodels(intermediateArtifacts, objcProvider.get(XCDATAMODEL))))
+ .addTransitive(objcProvider.get(MERGE_ZIP));
+ for (Artifact xibFile : objcProvider.get(XIB)) {
+ mergeZipBuilder.add(intermediateArtifacts.compiledXibFileZip(xibFile));
+ }
+ for (Artifact storyboard : objcProvider.get(STORYBOARD)) {
+ mergeZipBuilder.add(intermediateArtifacts.compiledStoryboardZip(storyboard));
+ }
+ return mergeZipBuilder.build();
+ }
+
public Bundling build() {
Preconditions.checkNotNull(intermediateArtifacts, "intermediateArtifacts");
@@ -123,23 +145,37 @@ final class Bundling {
Optional.of(intermediateArtifacts.combinedArchitectureBinary());
}
- NestedSet<Artifact> mergeZips = NestedSetBuilder.<Artifact>stableOrder()
- .addAll(actoolzipOutput.asSet())
- .addTransitive(objcProvider.get(MERGE_ZIP))
- .build();
- NestedSet<Artifact> bundleContentArtifacts = NestedSetBuilder.<Artifact>stableOrder()
- .addTransitive(nestedBundleContentArtifacts(objcProvider.get(NESTED_BUNDLE)))
- .addAll(combinedArchitectureBinary.asSet())
- .addAll(infoplistMerging.getPlistWithEverything().asSet())
- .addTransitive(mergeZips)
- .addAll(BundleableFile.toArtifacts(extraBundleFiles))
- .addAll(BundleableFile.toArtifacts(objcProvider.get(BUNDLE_FILE)))
- .addAll(Xcdatamodel.outputZips(objcProvider.get(XCDATAMODEL)))
- .build();
+ NestedSet<Artifact> mergeZips = getMergeZips(actoolzipOutput);
+ NestedSetBuilder<Artifact> bundleContentArtifactsBuilder =
+ NestedSetBuilder.<Artifact>stableOrder()
+ .addTransitive(nestedBundleContentArtifacts(objcProvider.get(NESTED_BUNDLE)))
+ .addAll(combinedArchitectureBinary.asSet())
+ .addAll(infoplistMerging.getPlistWithEverything().asSet())
+ .addTransitive(mergeZips)
+ .addAll(BundleableFile.toArtifacts(objcProvider.get(BUNDLE_FILE)));
+
+ Set<String> bundlePaths = new HashSet<>();
+ for (Artifact stringsFile : objcProvider.get(STRINGS)) {
+ Artifact binaryStrings = intermediateArtifacts.convertedStringsFile(stringsFile);
+ BundleableFile bundleFile = new BundleableFile(
+ binaryStrings, BundleableFile.flatBundlePath(stringsFile.getExecPath()));
+ if (bundlePaths.add(bundleFile.getBundlePath())) {
+ // Filter files that would map to the same location. Files can have the same bundle path
+ // for various illegal reasons and errors are raised for that separately. Otherwise we
+ // only want a single file for a mapping in the bundle. See
+ // ReleaseBundlingSupport.validateResources for details.
+ extraBundleFilesBuilder.add(bundleFile);
+ bundleContentArtifactsBuilder.add(binaryStrings);
+ }
+ }
+
+ ImmutableList<BundleableFile> extraBundleFiles = extraBundleFilesBuilder.build();
+
+ bundleContentArtifactsBuilder.addAll(BundleableFile.toArtifacts(extraBundleFiles));
return new Bundling(name, bundleDirFormat, combinedArchitectureBinary, extraBundleFiles,
- objcProvider, infoplistMerging, actoolzipOutput, bundleContentArtifacts, mergeZips,
- primaryBundleId, fallbackBundleId, architecture);
+ objcProvider, infoplistMerging, actoolzipOutput, bundleContentArtifactsBuilder.build(),
+ mergeZips, primaryBundleId, fallbackBundleId, architecture);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompiledResourceFile.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompiledResourceFile.java
deleted file mode 100644
index df0d09b9f4..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompiledResourceFile.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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 com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.Artifact;
-
-/**
- * Represents a strings file.
- */
-public class CompiledResourceFile {
- private final Artifact original;
- private final BundleableFile bundled;
-
- private CompiledResourceFile(Artifact original, BundleableFile bundled) {
- this.original = Preconditions.checkNotNull(original);
- this.bundled = Preconditions.checkNotNull(bundled);
- }
-
- /**
- * The checked-in version of the bundled file.
- */
- public Artifact getOriginal() {
- return original;
- }
-
- public BundleableFile getBundled() {
- return bundled;
- }
-
- public static final Function<CompiledResourceFile, BundleableFile> TO_BUNDLED =
- new Function<CompiledResourceFile, BundleableFile>() {
- @Override
- public BundleableFile apply(CompiledResourceFile input) {
- return input.bundled;
- }
- };
-
- /**
- * Given a sequence of artifacts corresponding to {@code .strings} files, returns a sequence of
- * the same length of instances of this class. The value returned by {@link #getBundled()} of each
- * instance will be the plist file in binary form.
- */
- public static Iterable<CompiledResourceFile> fromStringsFiles(
- IntermediateArtifacts intermediateArtifacts, Iterable<Artifact> strings) {
- ImmutableList.Builder<CompiledResourceFile> result = new ImmutableList.Builder<>();
- for (Artifact originalFile : strings) {
- Artifact binaryFile = intermediateArtifacts.convertedStringsFile(originalFile);
- result.add(new CompiledResourceFile(
- originalFile,
- new BundleableFile(
- binaryFile, BundleableFile.flatBundlePath(originalFile.getExecPath()))));
- }
- return result.build();
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
index 348e771fed..0b4e5d6032 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
@@ -14,6 +14,9 @@
package com.google.devtools.build.lib.rules.objc;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STORYBOARD;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCDATAMODEL;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
@@ -78,9 +81,8 @@ public abstract class IosTest implements RuleConfiguredTargetFactory {
}
XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
- NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder()
- .addTransitive(common.getStoryboards().getOutputZips())
- .addAll(Xcdatamodel.outputZips(common.getDatamodels()));
+ NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
+ addResourceFilesToBuild(ruleContext, common.getObjcProvider(), filesToBuild);
XcodeProductType productType;
ExtraLinkArgs extraLinkArgs;
@@ -133,10 +135,10 @@ public abstract class IosTest implements RuleConfiguredTargetFactory {
.registerActions()
.addXcodeSettings(xcodeProviderBuilder)
.addFilesToBuild(filesToBuild)
+ .validateResources()
.validateAttributes();
new ResourceSupport(ruleContext)
- .registerActions(common.getStoryboards())
.validateAttributes()
.addXcodeSettings(xcodeProviderBuilder);
@@ -151,6 +153,20 @@ public abstract class IosTest implements RuleConfiguredTargetFactory {
return create(ruleContext, common, xcodeProviderBuilder.build(), filesToBuild.build());
}
+ private void addResourceFilesToBuild(
+ RuleContext ruleContext, ObjcProvider objcProvider, NestedSetBuilder<Artifact> filesToBuild) {
+ IntermediateArtifacts intermediateArtifacts =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext);
+
+ Iterable<Xcdatamodel> xcdatamodels =
+ Xcdatamodels.xcdatamodels(intermediateArtifacts, objcProvider.get(XCDATAMODEL));
+ filesToBuild.addAll(Xcdatamodel.outputZips(xcdatamodels));
+
+ for (Artifact storyboard : objcProvider.get(STORYBOARD)) {
+ filesToBuild.add(intermediateArtifacts.compiledStoryboardZip(storyboard));
+ }
+ }
+
protected static boolean isXcTest(RuleContext ruleContext) {
return ruleContext.attributes().get(IS_XCTEST, Type.BOOLEAN);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java
index ec7fc86f33..4b1868a21d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java
@@ -30,7 +30,6 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWOR
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCASSETS_DIR;
-import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
@@ -50,7 +49,6 @@ import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.util.LazyString;
-import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos;
@@ -98,8 +96,8 @@ final class ObjcActionsBuilder {
static final PathFragment IBTOOL = new PathFragment(IosSdkCommands.IBTOOL_PATH);
static final PathFragment DSYMUTIL = new PathFragment(BIN_DIR + "/dsymutil");
static final PathFragment LIPO = new PathFragment(BIN_DIR + "/lipo");
- static final ImmutableList<String> CLANG_COVERAGE_FLAGS = ImmutableList.<String>of(
- "-fprofile-arcs", "-ftest-coverage", "-fprofile-dir=./coverage_output");
+ static final ImmutableList<String> CLANG_COVERAGE_FLAGS =
+ ImmutableList.of("-fprofile-arcs", "-ftest-coverage", "-fprofile-dir=./coverage_output");
// TODO(bazel-team): Reference a rule target rather than a jar file when Darwin runfiles work
// better.
@@ -270,70 +268,6 @@ final class ObjcActionsBuilder {
.build(context));
}
- /**
- * Creates actions to convert all files specified by the strings attribute into binary format.
- */
- private static Iterable<Action> convertStringsActions(
- ActionConstructionContext context,
- ObjcRuleClasses.Tools baseTools,
- StringsFiles stringsFiles) {
- ImmutableList.Builder<Action> result = new ImmutableList.Builder<>();
- for (CompiledResourceFile stringsFile : stringsFiles) {
- final Artifact original = stringsFile.getOriginal();
- final Artifact bundled = stringsFile.getBundled().getBundled();
- result.add(new SpawnAction.Builder()
- .setMnemonic("ConvertStringsPlist")
- .setExecutable(baseTools.plmerge())
- .setCommandLine(new CommandLine() {
- @Override
- public Iterable<String> arguments() {
- return ImmutableList.of("--source_file", original.getExecPathString(),
- "--out_file", bundled.getExecPathString());
- }
- })
- .addInput(original)
- .addOutput(bundled)
- .build(context));
- }
- return result.build();
- }
-
- /**
- * Creates actions to convert all files specified by the xibs attribute into nib format.
- */
- private Iterable<Action> convertXibsActions(ObjcRuleClasses.Tools baseTools, XibFiles xibFiles) {
- ImmutableList.Builder<Action> result = new ImmutableList.Builder<>();
- for (Artifact original : xibFiles) {
- Artifact zipOutput = intermediateArtifacts.compiledXibFileZip(original);
- String archiveRoot = BundleableFile.flatBundlePath(
- FileSystemUtils.replaceExtension(original.getExecPath(), ".nib"));
- result.add(spawnJavaOnDarwinActionBuilder(baseTools.ibtoolzipDeployJar())
- .setMnemonic("XibCompile")
- .setCommandLine(new CustomCommandLine.Builder()
- // The next three arguments are positional, i.e. they don't have flags before them.
- .addPath(zipOutput.getExecPath())
- .add(archiveRoot)
- .addPath(IBTOOL)
-
- .add("--minimum-deployment-target").add(objcConfiguration.getMinimumOs())
- .addPath(original.getExecPath())
- .build())
- .addOutput(zipOutput)
- .addInput(original)
- .build(context));
- }
- return result.build();
- }
-
- /**
- * Outputs of an {@code actool} action besides the zip file.
- */
- static final class ExtraActoolOutputs extends IterableWrapper<Artifact> {
- ExtraActoolOutputs(Artifact... extraActoolOutputs) {
- super(extraActoolOutputs);
- }
- }
-
static final class ExtraActoolArgs extends IterableWrapper<String> {
ExtraActoolArgs(Iterable<String> args) {
super(args);
@@ -401,44 +335,6 @@ final class ObjcActionsBuilder {
};
}
- @VisibleForTesting
- static Iterable<String> commonMomczipArguments(ObjcConfiguration configuration) {
- return ImmutableList.of(
- "-XD_MOMC_SDKROOT=" + IosSdkCommands.sdkDir(configuration),
- "-XD_MOMC_IOS_TARGET_VERSION=" + configuration.getMinimumOs(),
- "-MOMC_PLATFORMS", configuration.getPlatform().getLowerCaseNameInPlist(),
- "-XD_MOMC_TARGET_VERSION=10.6");
- }
-
- private static Iterable<Action> momczipActions(ActionConstructionContext context,
- ObjcRuleClasses.Tools baseTools, final ObjcConfiguration objcConfiguration,
- Iterable<Xcdatamodel> datamodels) {
- ImmutableList.Builder<Action> result = new ImmutableList.Builder<>();
- for (Xcdatamodel datamodel : datamodels) {
- final Artifact outputZip = datamodel.getOutputZip();
- final String archiveRoot = datamodel.archiveRootForMomczip();
- final String container = datamodel.getContainer().getSafePathString();
- result.add(spawnJavaOnDarwinActionBuilder(baseTools.momczipDeployJar())
- .setMnemonic("MomCompile")
- .addOutput(outputZip)
- .addInputs(datamodel.getInputs())
- .setCommandLine(new CommandLine() {
- @Override
- public Iterable<String> arguments() {
- return new ImmutableList.Builder<String>()
- .add(outputZip.getExecPathString())
- .add(archiveRoot)
- .add(IosSdkCommands.MOMC_PATH)
- .addAll(commonMomczipArguments(objcConfiguration))
- .add(container)
- .build();
- }
- })
- .build(context));
- }
- return result.build();
- }
-
private static final String FRAMEWORK_SUFFIX = ".framework";
/**
@@ -473,15 +369,6 @@ final class ObjcActionsBuilder {
}
/*
- * Returns an ExtraLinkArgs with the parameter prepended to this instance's contents. This
- * function does not modify this instance.
- */
- @CheckReturnValue
- public ExtraLinkArgs prependedWith(Iterable<String> extraLinkArgs) {
- return new ExtraLinkArgs(Iterables.concat(extraLinkArgs, this));
- }
-
- /*
* Returns an ExtraLinkArgs with the parameter appended to this instance's contents. This
* function does not modify this instance.
*/
@@ -492,10 +379,6 @@ final class ObjcActionsBuilder {
}
static final class ExtraLinkInputs extends IterableWrapper<Artifact> {
- ExtraLinkInputs(Iterable<Artifact> inputs) {
- super(inputs);
- }
-
ExtraLinkInputs(Artifact... inputs) {
super(inputs);
}
@@ -593,22 +476,6 @@ final class ObjcActionsBuilder {
.build(context));
}
- static final class StringsFiles extends IterableWrapper<CompiledResourceFile> {
- StringsFiles(Iterable<CompiledResourceFile> files) {
- super(files);
- }
- }
-
- /**
- * Registers actions for resource conversion.
- */
- void registerResourceActions(ObjcRuleClasses.Tools baseTools, StringsFiles stringsFiles,
- XibFiles xibFiles, Iterable<Xcdatamodel> datamodels) {
- registerAll(convertStringsActions(context, baseTools, stringsFiles));
- registerAll(convertXibsActions(baseTools, xibFiles));
- registerAll(momczipActions(context, baseTools, objcConfiguration, datamodels));
- }
-
static LazyString joinExecPaths(final Iterable<Artifact> artifacts) {
return new LazyString() {
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
index 1de38f13a5..1c8f7c1faa 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
@@ -47,11 +47,11 @@ public class ObjcBundleLibrary implements RuleConfiguredTargetFactory {
// asset catalogs compilation (actool).
new BundleSupport(ruleContext, ImmutableSet.of(TargetDeviceFamily.IPHONE), bundling)
.registerActions(common.getObjcProvider())
+ .validateResources(common.getObjcProvider())
.addXcodeSettings(xcodeProviderBuilder);
new ResourceSupport(ruleContext)
.validateAttributes()
- .registerActions(common.getStoryboards())
.addXcodeSettings(xcodeProviderBuilder);
new XcodeSupport(ruleContext)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
index 65ddb991a6..50a080f26d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
@@ -31,13 +31,15 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIB
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LINKED_BINARY;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MERGE_ZIP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SOURCE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STORYBOARD;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STRINGS;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCASSETS_DIR;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCDATAMODEL;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XIB;
import static com.google.devtools.build.lib.vfs.PathFragment.TO_PATH_FRAGMENT;
import com.google.common.annotations.VisibleForTesting;
@@ -336,8 +338,6 @@ public final class ObjcCommon {
.addTransitiveAndPropagate(depObjcProviders)
.addTransitiveWithoutPropagating(directDepObjcProviders);
- Storyboards storyboards;
- Iterable<Xcdatamodel> datamodels;
if (compilationAttributes.isPresent()) {
CompilationAttributes attributes = compilationAttributes.get();
ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(context);
@@ -357,31 +357,21 @@ public final class ObjcCommon {
if (resourceAttributes.isPresent()) {
ResourceAttributes attributes = resourceAttributes.get();
- storyboards = Storyboards.fromInputs(attributes.storyboards(), intermediateArtifacts);
- datamodels = Xcdatamodels.xcdatamodels(intermediateArtifacts, attributes.datamodels());
- Iterable<CompiledResourceFile> compiledResources =
- CompiledResourceFile.fromStringsFiles(intermediateArtifacts, attributes.strings());
- XibFiles xibFiles = new XibFiles(attributes.xibs());
-
objcProvider
- .addTransitiveAndPropagate(MERGE_ZIP, storyboards.getOutputZips())
- .addAll(MERGE_ZIP, xibFiles.compiledZips(intermediateArtifacts))
- .addAll(GENERAL_RESOURCE_FILE, storyboards.getInputs())
+ .addAll(GENERAL_RESOURCE_FILE, attributes.storyboards())
.addAll(GENERAL_RESOURCE_FILE, attributes.resources())
.addAll(GENERAL_RESOURCE_FILE, attributes.strings())
.addAll(GENERAL_RESOURCE_FILE, attributes.xibs())
.addAll(BUNDLE_FILE, BundleableFile.flattenedRawResourceFiles(attributes.resources()))
.addAll(BUNDLE_FILE,
BundleableFile.structuredRawResourceFiles(attributes.structuredResources()))
- .addAll(BUNDLE_FILE,
- Iterables.transform(compiledResources, CompiledResourceFile.TO_BUNDLED))
.addAll(XCASSETS_DIR,
uniqueContainers(attributes.assetCatalogs(), ASSET_CATALOG_CONTAINER_TYPE))
.addAll(ASSET_CATALOG, attributes.assetCatalogs())
- .addAll(XCDATAMODEL, datamodels);
- } else {
- storyboards = Storyboards.empty();
- datamodels = ImmutableList.of();
+ .addAll(XCDATAMODEL, attributes.datamodels())
+ .addAll(XIB, attributes.xibs())
+ .addAll(STRINGS, attributes.strings())
+ .addAll(STORYBOARD, attributes.storyboards());
}
for (CompilationArtifacts artifacts : compilationArtifacts.asSet()) {
@@ -423,8 +413,7 @@ public final class ObjcCommon {
objcProvider.addAll(LINKED_BINARY, linkedBinary.asSet());
- return new ObjcCommon(
- context, objcProvider.build(), storyboards, datamodels, compilationArtifacts);
+ return new ObjcCommon(context, objcProvider.build(), compilationArtifacts);
}
}
@@ -436,21 +425,15 @@ public final class ObjcCommon {
static final FileType FRAMEWORK_CONTAINER_TYPE = FileType.of(".framework");
private final RuleContext context;
private final ObjcProvider objcProvider;
- private final Storyboards storyboards;
- private final Iterable<Xcdatamodel> datamodels;
private final Optional<CompilationArtifacts> compilationArtifacts;
private ObjcCommon(
RuleContext context,
ObjcProvider objcProvider,
- Storyboards storyboards,
- Iterable<Xcdatamodel> datamodels,
Optional<CompilationArtifacts> compilationArtifacts) {
this.context = Preconditions.checkNotNull(context);
this.objcProvider = Preconditions.checkNotNull(objcProvider);
- this.storyboards = Preconditions.checkNotNull(storyboards);
- this.datamodels = Preconditions.checkNotNull(datamodels);
this.compilationArtifacts = Preconditions.checkNotNull(compilationArtifacts);
}
@@ -463,22 +446,6 @@ public final class ObjcCommon {
}
/**
- * Returns all storyboards declared in this rule (not including others in the transitive
- * dependency tree).
- */
- public Storyboards getStoryboards() {
- return storyboards;
- }
-
- /**
- * Returns all datamodels declared in this rule (not including others in the transitive
- * dependency tree).
- */
- public Iterable<Xcdatamodel> getDatamodels() {
- return datamodels;
- }
-
- /**
* Returns an {@link Optional} containing the compiled {@code .a} file, or
* {@link Optional#absent()} if this object contains no {@link CompilationArtifacts} or the
* compilation information has no sources.
@@ -606,8 +573,6 @@ public final class ObjcCommon {
Optional<J2ObjcSrcsProvider> maybeJ2ObjcSrcsProvider) {
NestedSet<Artifact> allFilesToBuild = NestedSetBuilder.<Artifact>stableOrder()
.addTransitive(filesToBuild)
- .addTransitive(storyboards.getOutputZips())
- .addAll(Xcdatamodel.outputZips(datamodels))
.build();
RunfilesProvider runfilesProvider = RunfilesProvider.withData(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
index 631def29c4..6c4bf2290a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
@@ -52,7 +52,6 @@ public class ObjcImport implements RuleConfiguredTargetFactory {
.validateAttributes();
new ResourceSupport(ruleContext)
- .registerActions(common.getStoryboards())
.validateAttributes()
.addXcodeSettings(xcodeProviderBuilder);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
index 2271f4931f..36fed31bc3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
@@ -94,7 +94,6 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory {
.validateAttributes();
new ResourceSupport(ruleContext)
- .registerActions(common.getStoryboards())
.validateAttributes()
.addXcodeSettings(xcodeProviderBuilder);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
index c121980bed..e559ab4e35 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
@@ -125,7 +125,7 @@ public final class ObjcProvider implements TransitiveInfoProvider {
public static final Key<String> SDK_DYLIB = new Key<>(STABLE_ORDER);
public static final Key<SdkFramework> SDK_FRAMEWORK = new Key<>(STABLE_ORDER);
public static final Key<SdkFramework> WEAK_SDK_FRAMEWORK = new Key<>(STABLE_ORDER);
- public static final Key<Xcdatamodel> XCDATAMODEL = new Key<>(STABLE_ORDER);
+ public static final Key<Artifact> XCDATAMODEL = new Key<>(STABLE_ORDER);
public static final Key<Flag> FLAG = new Key<>(STABLE_ORDER);
/**
@@ -159,6 +159,21 @@ public final class ObjcProvider implements TransitiveInfoProvider {
public static final Key<Artifact> DEBUG_SYMBOLS = new Key<>(STABLE_ORDER);
/**
+ * Artifacts for storyboard sources.
+ */
+ public static final Key<Artifact> STORYBOARD = new Key<>(STABLE_ORDER);
+
+ /**
+ * Artifacts for .xib file sources.
+ */
+ public static final Key<Artifact> XIB = new Key<>(STABLE_ORDER);
+
+ /**
+ * Artifacts for strings source files.
+ */
+ public static final Key<Artifact> STRINGS = new Key<>(STABLE_ORDER);
+
+ /**
* Flags that apply to a transitive build dependency tree. Each item in the enum corresponds to a
* flag. If the item is included in the key {@link #FLAG}, then the flag is considered set.
*/
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 5167696e30..20567cbedb 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
@@ -406,8 +406,6 @@ public class ObjcRuleClasses {
.direct_compile_time_input()
.allowedRuleClasses("objc_bundle", "objc_bundle_library")
.allowedFileTypes())
- .add(attr("$momczip_deploy", LABEL).cfg(HOST)
- .value(env.getLabel("//tools/objc:momczip_deploy.jar")))
.build();
}
@Override
@@ -793,6 +791,8 @@ public class ObjcRuleClasses {
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("infoplist", LABEL)
.allowedFileTypes(PLIST_TYPE))
+ .add(attr("$momczip_deploy", LABEL).cfg(HOST)
+ .value(env.getLabel("//tools/objc:momczip_deploy.jar")))
.build();
}
@Override
@@ -954,21 +954,9 @@ public class ObjcRuleClasses {
return ruleContext.getPrerequisiteArtifact("$actoolzip_deploy", Mode.HOST);
}
- Artifact ibtoolzipDeployJar() {
- return ruleContext.getPrerequisiteArtifact("$ibtoolzip_deploy", Mode.HOST);
- }
-
- Artifact momczipDeployJar() {
- return ruleContext.getPrerequisiteArtifact("$momczip_deploy", Mode.HOST);
- }
-
FilesToRunProvider xcodegen() {
return ruleContext.getExecutablePrerequisite("$xcodegen", Mode.HOST);
}
-
- FilesToRunProvider plmerge() {
- return ruleContext.getExecutablePrerequisite("$plmerge", Mode.HOST);
- }
}
}
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 636eac4bab..2086298acd 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
@@ -197,6 +197,17 @@ public final class ReleaseBundlingSupport {
}
/**
+ * Validates that resources defined in this rule and its dependencies and written to this bundle
+ * are legal.
+ *
+ * @return this release bundling support
+ */
+ ReleaseBundlingSupport validateResources() {
+ bundleSupport.validateResources(objcProvider);
+ return this;
+ }
+
+ /**
* Registers actions required to build an application. This includes any
* {@link BundleSupport#registerActions(ObjcProvider) bundle} and bundle merge actions, signing
* this application if appropriate and combining several single-architecture binaries into one
@@ -231,8 +242,8 @@ public final class ReleaseBundlingSupport {
private Artifact registerBundleSigningActions(Artifact ipaOutput) {
PathFragment entitlementsDirectory = ruleContext.getUniqueDirectory("entitlements");
- Artifact teamPrefixFile = ruleContext.getRelatedArtifact(
- entitlementsDirectory, ".team_prefix_file");
+ Artifact teamPrefixFile =
+ ruleContext.getRelatedArtifact(entitlementsDirectory, ".team_prefix_file");
registerExtractTeamPrefixAction(teamPrefixFile);
Artifact entitlementsNeedingSubstitution = attributes.entitlements();
@@ -241,8 +252,8 @@ public final class ReleaseBundlingSupport {
entitlementsDirectory, ".entitlements_with_variables");
registerExtractEntitlementsAction(entitlementsNeedingSubstitution);
}
- Artifact entitlements = ruleContext.getRelatedArtifact(
- entitlementsDirectory, ".entitlements");
+ Artifact entitlements =
+ ruleContext.getRelatedArtifact(entitlementsDirectory, ".entitlements");
registerEntitlementsVariableSubstitutionAction(
entitlementsNeedingSubstitution, entitlements, teamPrefixFile);
Artifact ipaUnsigned = ObjcRuleClasses.artifactByAppendingToRootRelativePath(
@@ -382,7 +393,7 @@ public final class ReleaseBundlingSupport {
// Architecture that determines which nested bundles are kept.
.setArchitecture(objcConfiguration.getDependencySingleArchitecture())
.setBundleDirFormat(bundleDirFormat)
- .setExtraBundleFiles(extraBundleFiles)
+ .addExtraBundleFiles(extraBundleFiles)
.setObjcProvider(objcProvider)
.setInfoplistMerging(
BundleSupport.infoPlistMerging(ruleContext, objcProvider, optionsProvider))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
index 10a1f2e41a..af98af5dce 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
@@ -72,6 +72,7 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg
.registerActions()
.addXcodeSettings(xcodeProviderBuilder)
.addFilesToBuild(filesToBuild)
+ .validateResources()
.validateAttributes();
XcodeSupport xcodeSupport = new XcodeSupport(ruleContext)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ResourceSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ResourceSupport.java
index 4a279d2a72..d3614a56ad 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ResourceSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ResourceSupport.java
@@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
/**
* Support for resource processing on Objc rules.
@@ -28,8 +27,6 @@ import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
final class ResourceSupport {
private final RuleContext ruleContext;
private final Attributes attributes;
- private final IntermediateArtifacts intermediateArtifacts;
- private final Iterable<Xcdatamodel> datamodels;
/**
* Creates a new resource support for the given context.
@@ -37,57 +34,6 @@ final class ResourceSupport {
ResourceSupport(RuleContext ruleContext) {
this.ruleContext = ruleContext;
this.attributes = new Attributes(ruleContext);
- this.intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext);
- this.datamodels = Xcdatamodels.xcdatamodels(intermediateArtifacts, attributes.datamodels());
- }
-
- /**
- * Registers resource generating actions (strings, storyboards, ...).
- *
- * @param storyboards storyboards defined by this rule
- *
- * @return this resource support
- */
- ResourceSupport registerActions(Storyboards storyboards) {
- ObjcActionsBuilder actionsBuilder = ObjcRuleClasses.actionsBuilder(ruleContext);
-
- ObjcRuleClasses.Tools tools = new ObjcRuleClasses.Tools(ruleContext);
- actionsBuilder.registerResourceActions(
- tools,
- new ObjcActionsBuilder.StringsFiles(
- CompiledResourceFile.fromStringsFiles(intermediateArtifacts, attributes.strings())),
- new XibFiles(attributes.xibs()),
- datamodels);
-
- registerInterfaceBuilderActions(storyboards, tools);
- return this;
- }
-
- private void registerInterfaceBuilderActions(
- Storyboards storyboards, ObjcRuleClasses.Tools tools) {
- for (Artifact storyboardInput : storyboards.getInputs()) {
- String archiveRoot = BundleableFile.flatBundlePath(storyboardInput.getExecPath()) + "c";
- Artifact zipOutput = intermediateArtifacts.compiledStoryboardZip(storyboardInput);
-
- String minimumOs =
- ruleContext.getConfiguration().getFragment(ObjcConfiguration.class).getMinimumOs();
- ruleContext.registerAction(
- ObjcActionsBuilder.spawnJavaOnDarwinActionBuilder(tools.ibtoolzipDeployJar())
- .setMnemonic("StoryboardCompile")
- .setCommandLine(new CustomCommandLine.Builder()
- // The next three arguments are positional,
- // i.e. they don't have flags before them.
- .addPath(zipOutput.getExecPath())
- .add(archiveRoot)
- .addPath(ObjcActionsBuilder.IBTOOL)
-
- .add("--minimum-deployment-target").add(minimumOs)
- .addPath(storyboardInput.getExecPath())
- .build())
- .addOutput(zipOutput)
- .addInput(storyboardInput)
- .build(ruleContext));
- }
}
/**
@@ -96,7 +42,8 @@ final class ResourceSupport {
* @return this resource support
*/
ResourceSupport addXcodeSettings(XcodeProvider.Builder xcodeProviderBuilder) {
- xcodeProviderBuilder.addInputsToXcodegen(Xcdatamodel.inputsToXcodegen(datamodels));
+ xcodeProviderBuilder.addInputsToXcodegen(Xcdatamodel.inputsToXcodegen(attributes.datamodels()));
+ xcodeProviderBuilder.addDatamodelDirs(Xcdatamodels.datamodelDirs(attributes.datamodels()));
return this;
}
@@ -132,16 +79,6 @@ final class ResourceSupport {
return ruleContext.getPrerequisiteArtifacts("datamodels", Mode.TARGET).list();
}
- ImmutableList<Artifact> xibs() {
- return ruleContext.getPrerequisiteArtifacts("xibs", Mode.TARGET)
- .errorsForNonMatching(ObjcRuleClasses.XIB_TYPE)
- .list();
- }
-
- ImmutableList<Artifact> strings() {
- return ruleContext.getPrerequisiteArtifacts("strings", Mode.TARGET).list();
- }
-
ImmutableList<Artifact> assetCatalogs() {
return ruleContext.getPrerequisiteArtifacts("asset_catalogs", Mode.TARGET).list();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodel.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodel.java
index ef2c1fa5a5..ff8601cb96 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodel.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodel.java
@@ -64,15 +64,13 @@ class Xcdatamodel extends Value<Xcdatamodel> {
/**
* Returns the files that should be supplied to Xcodegen when generating a project that includes
- * all of the given xcdatamodels.
+ * all of the given xcdatamodel source files.
*/
- public static Iterable<Artifact> inputsToXcodegen(Iterable<Xcdatamodel> datamodels) {
+ public static Iterable<Artifact> inputsToXcodegen(Iterable<Artifact> datamodelFiles) {
ImmutableSet.Builder<Artifact> inputs = new ImmutableSet.Builder<>();
- for (Xcdatamodel datamodel : datamodels) {
- for (Artifact generalInput : datamodel.inputs) {
- if (generalInput.getExecPath().getBaseName().equals(".xccurrentversion")) {
- inputs.add(generalInput);
- }
+ for (Artifact generalInput : datamodelFiles) {
+ if (generalInput.getExecPath().getBaseName().equals(".xccurrentversion")) {
+ inputs.add(generalInput);
}
}
return inputs.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodels.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodels.java
index 32d48aa696..340c77533a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodels.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodels.java
@@ -34,6 +34,14 @@ class Xcdatamodels {
static final ImmutableList<FileType> CONTAINER_TYPES =
ImmutableList.of(FileType.of(".xcdatamodeld"), FileType.of(".xcdatamodel"));
+ static Iterable<PathFragment> datamodelDirs(Iterable<Artifact> xcdatamodels) {
+ ImmutableSet.Builder<PathFragment> result = new ImmutableSet.Builder<>();
+ for (Collection<Artifact> artifacts : byContainer(xcdatamodels).asMap().values()) {
+ result.addAll(ObjcCommon.uniqueContainers(artifacts, FileType.of(".xcdatamodel")));
+ }
+ return result.build();
+ }
+
static Iterable<Xcdatamodel> xcdatamodels(
IntermediateArtifacts intermediateArtifacts, Iterable<Artifact> xcdatamodels) {
ImmutableSet.Builder<Xcdatamodel> result = new ImmutableSet.Builder<>();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java
index ac20c8ea8a..07c61f2ed2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java
@@ -24,7 +24,6 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCASSETS_DIR;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCDATAMODEL;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
@@ -33,6 +32,7 @@ import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.actions.Artifact;
@@ -83,6 +83,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
private final NestedSetBuilder<Artifact> additionalSources = NestedSetBuilder.stableOrder();
private final ImmutableList.Builder<XcodeProvider> extensions = new ImmutableList.Builder<>();
private String architecture;
+ private ImmutableList.Builder<PathFragment> datamodelDirs = new ImmutableList.Builder<>();
/**
* Sets the label of the build target which corresponds to this Xcode target.
@@ -246,6 +247,11 @@ public final class XcodeProvider implements TransitiveInfoProvider {
return this;
}
+ public Builder addDatamodelDirs(Iterable<PathFragment> datamodelDirs) {
+ this.datamodelDirs.addAll(datamodelDirs);
+ return this;
+ }
+
public XcodeProvider build() {
Preconditions.checkState(
!testHost.isPresent() || (productType == XcodeProductType.UNIT_TEST),
@@ -324,6 +330,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
private final NestedSet<Artifact> additionalSources;
private final ImmutableList<XcodeProvider> extensions;
private final String architecture;
+ private final ImmutableList<PathFragment> datamodelDirs;
private XcodeProvider(Builder builder) {
this.label = Preconditions.checkNotNull(builder.label);
@@ -343,28 +350,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
this.additionalSources = builder.additionalSources.build();
this.extensions = builder.extensions.build();
this.architecture = Preconditions.checkNotNull(builder.architecture);
- }
-
- /**
- * Creates a builder whose values are all initialized to this provider.
- */
- public Builder toBuilder() {
- Builder builder = new Builder();
- builder.label = label;
- builder.userHeaderSearchPaths.addAll(userHeaderSearchPaths);
- builder.headerSearchPaths.addTransitive(headerSearchPaths);
- builder.infoplistMerging = infoplistMerging;
- builder.dependencies.addTransitive(dependencies);
- builder.xcodeprojBuildSettings.addAll(xcodeprojBuildSettings);
- builder.copts.addAll(copts);
- builder.productType = productType;
- builder.headers.addAll(headers);
- builder.compilationArtifacts = compilationArtifacts;
- builder.objcProvider = objcProvider;
- builder.testHost = testHost;
- builder.inputsToXcodegen.addTransitive(inputsToXcodegen);
- builder.extensions.addAll(extensions);
- return builder;
+ this.datamodelDirs = builder.datamodelDirs.build();
}
private void collectProviders(Set<XcodeProvider> allProviders) {
@@ -422,8 +408,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
.addAllSdkFramework(SdkFramework.names(objcProvider.get(SDK_FRAMEWORK)))
.addAllFramework(PathFragment.safePathStrings(objcProvider.get(FRAMEWORK_DIR)))
.addAllXcassetsDir(PathFragment.safePathStrings(objcProvider.get(XCASSETS_DIR)))
- .addAllXcdatamodel(PathFragment.safePathStrings(
- Xcdatamodel.xcdatamodelDirs(objcProvider.get(XCDATAMODEL))))
+ .addAllXcdatamodel(PathFragment.safePathStrings(datamodelDirs))
.addAllBundleImport(PathFragment.safePathStrings(objcProvider.get(BUNDLE_IMPORT_DIR)))
.addAllSdkDylib(objcProvider.get(SDK_DYLIB))
.addAllGeneralResourceFile(Artifact.toExecPaths(objcProvider.get(GENERAL_RESOURCE_FILE)))