aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Peter Schmitt <schmitt@google.com>2015-03-24 16:05:47 +0000
committerGravatar Han-Wen Nienhuys <hanwen@google.com>2015-03-24 17:16:38 +0000
commit26bae084e93901c2b49c958107d8b5b890c38a47 (patch)
treed059b3a99e390008de4cd44ca95a1ff35d9fa2ea /src
parentc9a9f4c874aa29b446f48ee3da179ae1bf6f5435 (diff)
Compile objc resources when bundling, not at each target.
This change moves the resource compilation actions from each declaring target to the bundle in which they're stored. This bundle is (mostly, see below) the only thing that cares about the compiled resources. As a result, we avoid compiling each resource many times when in a multi-architecture context. Note that as a result of this change rules other than ios_test do no longer add the compiled datamodels and storyboards to files to build. There (should?) be no need for them anyhow. Also, Xcode targets will now no longer contain the transitive closure of datamodels, only their own. Note that in the case where the input resource is produced by a genrule the resource compilation still happens for each architecture but we ignore the results for all but one of the architectures to avoid bundling conflicts. There are also some more validation checks and nicer error messages for users when they specify illegal strings resources. -- MOS_MIGRATED_REVID=89404405
Diffstat (limited to 'src')
-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)))