aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
authorGravatar Chris Parsons <cparsons@google.com>2016-09-29 20:34:28 +0000
committerGravatar Yun Peng <pcloudy@google.com>2016-09-30 08:14:34 +0000
commit8a46df7388ae37fcefa7e364ca0a320a20566658 (patch)
tree81290041c6fe6c19ecf4182334ebfe93a47a4ee2 /src/main/java
parentb35fe6960f6a7eea73221913dd90e72f5cb9a191 (diff)
Initial check-in of apple_static_library rule
RELNOTES: apple_static_library rule to create multi-architecture static archive files from Objc/C++/Swift dependencies on apple platforms -- MOS_MIGRATED_REVID=134701599
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java161
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java112
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java66
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java10
14 files changed, 363 insertions, 38 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 755c246f37..cedecad9d0 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -111,6 +111,7 @@ import com.google.devtools.build.lib.rules.java.JvmConfigurationLoader;
import com.google.devtools.build.lib.rules.java.ProguardLibraryRule;
import com.google.devtools.build.lib.rules.objc.AppleBinaryRule;
import com.google.devtools.build.lib.rules.objc.AppleSkylarkCommon;
+import com.google.devtools.build.lib.rules.objc.AppleStaticLibraryRule;
import com.google.devtools.build.lib.rules.objc.AppleWatch1ExtensionRule;
import com.google.devtools.build.lib.rules.objc.AppleWatch2ExtensionRule;
import com.google.devtools.build.lib.rules.objc.AppleWatchExtensionBinaryRule;
@@ -427,6 +428,7 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new IosTestRule());
builder.addRuleDefinition(new IosDeviceRule());
builder.addRuleDefinition(new AppleBinaryRule());
+ builder.addRuleDefinition(new AppleStaticLibraryRule());
builder.addRuleDefinition(new ObjcBinaryRule());
builder.addRuleDefinition(new ExperimentalObjcLibraryRule());
builder.addRuleDefinition(new ObjcBundleRule());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java
index bfa0aec72d..3289a34b0c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java
@@ -173,7 +173,8 @@ public abstract class AbstractJ2ObjcProtoAspect extends NativeAspectClass
new CompilationSupport(ruleContext)
.registerCompileAndArchiveActions(common)
- .registerFullyLinkAction(common.getObjcProvider());
+ .registerFullyLinkAction(common.getObjcProvider(),
+ ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB));
}
NestedSet<Artifact> j2ObjcTransitiveHeaderMappingFiles = j2ObjcTransitiveHeaderMappingFiles(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java
index d09c494322..17116f664f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java
@@ -33,12 +33,6 @@ import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
public class AppleBinaryRule implements RuleDefinition {
/**
- * Attribute name for {@code apple_binary}'s apple platform type (for which all dependencies and
- * sources of an {@code apple_binary} target will be built).
- */
- static final String PLATFORM_TYPE_ATTR_NAME = "platform_type";
-
- /**
* Template for the fat binary output (using Apple's "lipo" tool to combine binaries of
* multiple architectures).
*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java
new file mode 100644
index 0000000000..540418253c
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java
@@ -0,0 +1,161 @@
+// Copyright 2016 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.rules.objc;
+
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MULTI_ARCH_LINKED_ARCHIVES;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
+import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
+import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
+import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Implementation for the "apple_static_library" rule.
+ */
+public class AppleStaticLibrary implements RuleConfiguredTargetFactory {
+
+ @VisibleForTesting
+ static final String UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT =
+ "Unsupported platform type \"%s\"";
+
+ @Override
+ public final ConfiguredTarget create(RuleContext ruleContext)
+ throws InterruptedException, RuleErrorException {
+ PlatformType platformType = MultiArchSplitTransitionProvider.getPlatformType(ruleContext);
+ ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap =
+ ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT);
+ ImmutableListMultimap<BuildConfiguration, ObjcProvider> configToAvoidDepsMap =
+ ruleContext.getPrerequisitesByConfiguration("avoid_deps", Mode.SPLIT, ObjcProvider.class);
+
+ Set<BuildConfiguration> childConfigurations = getChildConfigurations(ruleContext);
+
+ IntermediateArtifacts ruleIntermediateArtifacts =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext);
+
+ NestedSetBuilder<Artifact> librariesToLipo =
+ NestedSetBuilder.<Artifact>stableOrder();
+ NestedSetBuilder<Artifact> filesToBuild =
+ NestedSetBuilder.<Artifact>stableOrder()
+ .add(ruleIntermediateArtifacts.combinedArchitectureArchive());
+
+ ObjcProvider.Builder objcProviderBuilder = new ObjcProvider.Builder();
+
+ for (BuildConfiguration childConfig : childConfigurations) {
+ ProtobufSupport protoSupport =
+ new ProtobufSupport(ruleContext, childConfig)
+ .registerGenerationActions()
+ .registerCompilationActions();
+
+ Optional<ObjcProvider> protosObjcProvider = protoSupport.getObjcProvider();
+
+ IntermediateArtifacts intermediateArtifacts =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext, childConfig);
+
+ ObjcCommon common =
+ common(
+ ruleContext,
+ childConfig,
+ intermediateArtifacts,
+ nullToEmptyList(configToDepsCollectionMap.get(childConfig)),
+ protosObjcProvider);
+
+ librariesToLipo.add(intermediateArtifacts.strippedSingleArchitectureLibrary());
+
+ new CompilationSupport(ruleContext, childConfig)
+ .registerCompileAndArchiveActions(common)
+ .registerFullyLinkActionWithAvoids(
+ common.getObjcProvider(),
+ intermediateArtifacts.strippedSingleArchitectureLibrary(),
+ configToAvoidDepsMap.get(childConfig))
+ .validateAttributes();
+ ruleContext.assertNoErrors();
+
+ objcProviderBuilder.addTransitiveAndPropagate(common.getObjcProvider());
+ }
+
+ AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
+
+ new LipoSupport(ruleContext)
+ .registerCombineArchitecturesAction(
+ librariesToLipo.build(),
+ ruleIntermediateArtifacts.combinedArchitectureArchive(),
+ appleConfiguration.getMultiArchPlatform(platformType));
+
+ RuleConfiguredTargetBuilder targetBuilder =
+ ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build());
+
+ objcProviderBuilder.add(
+ MULTI_ARCH_LINKED_ARCHIVES, ruleIntermediateArtifacts.combinedArchitectureArchive());
+
+ targetBuilder.addProvider(ObjcProvider.class, objcProviderBuilder.build());
+ return targetBuilder.build();
+ }
+
+ private ObjcCommon common(
+ RuleContext ruleContext,
+ BuildConfiguration buildConfiguration,
+ IntermediateArtifacts intermediateArtifacts,
+ List<TransitiveInfoCollection> propagatedDeps,
+ Optional<ObjcProvider> protosObjcProvider) {
+
+ CompilationArtifacts compilationArtifacts =
+ CompilationSupport.compilationArtifacts(ruleContext, intermediateArtifacts);
+
+ return new ObjcCommon.Builder(ruleContext, buildConfiguration)
+ .setCompilationAttributes(
+ CompilationAttributes.Builder.fromRuleContext(ruleContext).build())
+ .setCompilationArtifacts(compilationArtifacts)
+ .setResourceAttributes(new ResourceAttributes(ruleContext))
+ .addDefines(ruleContext.getTokenizedStringListAttr("defines"))
+ .addDeps(propagatedDeps)
+ .addDepObjcProviders(
+ ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
+ .addDepObjcProviders(protosObjcProvider.asSet())
+ .setIntermediateArtifacts(intermediateArtifacts)
+ .setAlwayslink(false)
+ .build();
+ }
+
+ private <T> List<T> nullToEmptyList(List<T> inputList) {
+ return inputList != null ? inputList : ImmutableList.<T>of();
+ }
+
+ private Set<BuildConfiguration> getChildConfigurations(RuleContext ruleContext) {
+ // This is currently a hack to obtain all child configurations regardless of the attribute
+ // values of this rule -- this rule does not currently use the actual info provided by
+ // this attribute. b/28403953 tracks cc toolchain usage.
+ ImmutableListMultimap<BuildConfiguration, CcToolchainProvider> configToProvider =
+ ruleContext.getPrerequisitesByConfiguration(":cc_toolchain", Mode.SPLIT,
+ CcToolchainProvider.class);
+
+ return configToProvider.keySet();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java
new file mode 100644
index 0000000000..5c78165f21
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java
@@ -0,0 +1,112 @@
+// Copyright 2016 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.rules.objc;
+
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
+import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
+import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.Builder;
+import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
+import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
+
+/**
+ * Rule definition for apple_static_library.
+ */
+public class AppleStaticLibraryRule implements RuleDefinition {
+
+ /**
+ * Template for the fat archive output (using Apple's "lipo" tool to combine .a archive files of
+ * multiple architectures).
+ */
+ static final SafeImplicitOutputsFunction LIPO_ARCHIVE = fromTemplates("%{name}_lipo.a");
+
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
+ MultiArchSplitTransitionProvider splitTransitionProvider =
+ new MultiArchSplitTransitionProvider();
+
+ return builder
+ .requiresConfigurationFragments(
+ ObjcConfiguration.class, J2ObjcConfiguration.class, AppleConfiguration.class,
+ CppConfiguration.class)
+ .override(builder.copy("deps").cfg(splitTransitionProvider))
+ /* <!-- #BLAZE_RULE(apple_static_library).ATTRIBUTE(avoid_deps) -->
+ <p>A list of targets which should not be included (nor their transitive dependencies
+ included) in the outputs of this rule -- even if they are otherwise transitively depended
+ on via the <code>deps</code> attribute.</p>
+
+ <p>This attribute effectively serves to remove portions of the dependency tree from a static
+ library, and is useful most commonly in scenarios where static libraries depend on each
+ other.</p>
+
+ <p>That is, suppose static libraries X and C are typically distributed to consumers
+ separately. C is a very-common base library, and X contains less-common functionality; X
+ depends on C, such that applications seeking to import library X must also import library
+ C. The target describing X would set C's target in <code>avoid_deps</code>. In this way,
+ X can depend on C without also containing C. Without this <code>avoid_deps</code> usage,
+ an application importing both X and C would have duplicate symbols for C.</p>
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(
+ attr("avoid_deps", LABEL_LIST)
+ .direct_compile_time_input()
+ .allowedRuleClasses(ObjcRuleClasses.CompilingRule.ALLOWED_DEPS_RULE_CLASSES)
+ .mandatoryNativeProviders(
+ ImmutableList.<Class<? extends TransitiveInfoProvider>>of(ObjcProvider.class))
+ .cfg(splitTransitionProvider)
+ .allowedFileTypes())
+ /*<!-- #BLAZE_RULE(apple_static_library).IMPLICIT_OUTPUTS -->
+ <ul>
+ <li><code><var>name</var>_lipo.a</code>: a 'lipo'ed archive file. All transitive
+ dependencies and <code>srcs</code> are linked, minus all transitive dependencies
+ specified in <code>avoid_deps</code>.</li>
+ </ul>
+ <!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
+ .setImplicitOutputsFunction(ImplicitOutputsFunction.fromFunctions(LIPO_ARCHIVE))
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("apple_static_library")
+ .factoryClass(AppleStaticLibrary.class)
+ .ancestors(BaseRuleClasses.BaseRule.class, ObjcRuleClasses.LinkingRule.class,
+ ObjcRuleClasses.MultiArchPlatformRule.class, ObjcRuleClasses.SimulatorRule.class)
+ .build();
+ }
+}
+
+/*<!-- #BLAZE_RULE (NAME = apple_static_library, TYPE = BINARY, FAMILY = Objective-C) -->
+
+<p>This rule produces single- or multi-architecture ("fat") Objective-C statically-linked libraries,
+typically used in creating static Apple Frameworks for distribution and re-use in
+multiple extensions or applications.</p>
+
+<p>The <code>lipo</code> tool is used to combine files of multiple architectures; a build flag
+controls which architectures are targeted. The build flag examined depends on the
+<code>platform_type</code> attribute for this rule (and is described in its documentation).</p>
+
+${IMPLICIT_OUTPUTS}
+
+<!-- #END_BLAZE_RULE -->*/
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 1381bb98b9..f214487e05 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
@@ -108,7 +108,8 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
CompilationSupport compilationSupport =
new CompilationSupport(ruleContext)
.registerCompileAndArchiveActions(common)
- .registerFullyLinkAction(common.getObjcProvider())
+ .registerFullyLinkAction(common.getObjcProvider(),
+ ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB))
.addXcodeSettings(xcodeProviderBuilder, common)
.registerLinkActions(
objcProvider,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
index 9b70d3f81c..31322dbb34 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
@@ -1027,18 +1027,8 @@ public final class CompilationSupport {
return this;
}
- /**
- * Registers an action to create an archive artifact by fully (statically) linking all
- * transitive dependencies of this rule.
- *
- * @param objcProvider provides all compiling and linking information to create this artifact
- */
- public CompilationSupport registerFullyLinkAction(ObjcProvider objcProvider)
- throws InterruptedException {
- Artifact outputArchive =
- ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB);
- ImmutableList<Artifact> objcLibraries = objcProvider.getObjcLibraries();
- ImmutableList<Artifact> ccLibraries = objcProvider.getCcLibraries();
+ private CompilationSupport registerFullyLinkAction(Iterable<Artifact> inputArtifacts,
+ Artifact outputArchive) {
ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder(
appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("ObjcLink")
@@ -1048,18 +1038,58 @@ public final class CompilationSupport {
.add("-arch_only").add(appleConfiguration.getSingleArchitecture())
.add("-syslibroot").add(AppleToolchain.sdkDir())
.add("-o").add(outputArchive.getExecPathString())
- .addExecPaths(objcLibraries)
- .addExecPaths(objcProvider.get(IMPORTED_LIBRARY))
- .addExecPaths(ccLibraries)
+ .addExecPaths(inputArtifacts)
.build())
- .addInputs(ccLibraries)
- .addInputs(objcLibraries)
- .addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY))
+ .addInputs(inputArtifacts)
.addOutput(outputArchive)
.build(ruleContext));
return this;
}
+ /**
+ * Registers an action to create an archive artifact by fully (statically) linking all
+ * transitive dependencies of this rule.
+ *
+ * @param objcProvider provides all compiling and linking information to create this artifact
+ * @param outputArchive the output artifact for this action
+ */
+ public CompilationSupport registerFullyLinkAction(ObjcProvider objcProvider,
+ Artifact outputArchive) {
+ ImmutableList<Artifact> inputArtifacts = ImmutableList.<Artifact>builder()
+ .addAll(objcProvider.getObjcLibraries())
+ .addAll(objcProvider.get(IMPORTED_LIBRARY))
+ .addAll(objcProvider.getCcLibraries()).build();
+ return registerFullyLinkAction(inputArtifacts, outputArchive);
+ }
+
+ /**
+ * Registers an action to create an archive artifact by fully (statically) linking all
+ * transitive dependencies of this rule *except* for dependencies given in {@code avoidsDeps}.
+ *
+ * @param objcProvider provides all compiling and linking information to create this artifact
+ * @param outputArchive the output artifact for this action
+ * @param avoidsDeps list of providers with dependencies that should not be linked into the
+ * output artifact
+ */
+ public CompilationSupport registerFullyLinkActionWithAvoids(ObjcProvider objcProvider,
+ Artifact outputArchive, Iterable<ObjcProvider> avoidsDeps) {
+ ImmutableSet.Builder<Artifact> avoidsDepsArtifacts = ImmutableSet.builder();
+
+ for (ObjcProvider avoidsProvider : avoidsDeps) {
+ avoidsDepsArtifacts.addAll(avoidsProvider.getObjcLibraries())
+ .addAll(avoidsProvider.get(IMPORTED_LIBRARY))
+ .addAll(avoidsProvider.getCcLibraries());
+ }
+ ImmutableList<Artifact> depsArtifacts = ImmutableList.<Artifact>builder()
+ .addAll(objcProvider.getObjcLibraries())
+ .addAll(objcProvider.get(IMPORTED_LIBRARY))
+ .addAll(objcProvider.getCcLibraries()).build();
+
+ Iterable<Artifact> inputArtifacts = Iterables.filter(depsArtifacts,
+ Predicates.not(Predicates.in(avoidsDepsArtifacts.build())));
+ return registerFullyLinkAction(inputArtifacts, outputArchive);
+ }
+
private NestedSet<Artifact> getGcovForObjectiveCIfNeeded() {
if (ruleContext.getConfiguration().isCodeCoverageEnabled()
&& ruleContext.attributes().has(IosTest.OBJC_GCOV_ATTR, BuildType.LABEL)) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
index 811e698ff7..454c06372a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
@@ -184,6 +184,14 @@ public final class IntermediateArtifacts {
}
/**
+ * The artifact which is the fully-linked static library comprised of statically linking compiled
+ * sources and dependencies together.
+ */
+ public Artifact strippedSingleArchitectureLibrary() {
+ return appendExtension("-fl.a");
+ }
+
+ /**
* The artifact which is the binary (or library) which is comprised of one or more .a files linked
* together. It also contains full debug symbol information, compared to the artifact returned
* by {@link #strippedSingleArchitectureBinary}. This artifact will serve as input for the symbol
@@ -201,6 +209,13 @@ public final class IntermediateArtifacts {
public Artifact combinedArchitectureBinary() {
return appendExtension("_lipobin");
}
+
+ /**
+ * Lipo archive generated by combining one or more linked archives.
+ */
+ public Artifact combinedArchitectureArchive() {
+ return appendExtension("_lipo.a");
+ }
private Artifact scopedArtifact(PathFragment scopeRelative, boolean inGenfiles) {
Root root =
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 de59c64c35..be3e6639ba 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
@@ -158,7 +158,8 @@ public final class IosTest implements RuleConfiguredTargetFactory {
extraLinkInputs,
DsymOutputType.TEST)
.registerCompileAndArchiveActions(common)
- .registerFullyLinkAction(common.getObjcProvider())
+ .registerFullyLinkAction(common.getObjcProvider(),
+ ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB))
.addXcodeSettings(xcodeProviderBuilder, common)
.validateAttributes();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
index 62168a4500..5c593c8a3d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
@@ -218,7 +218,8 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
new CompilationSupport(ruleContext)
.registerCompileAndArchiveActions(common, EXTRA_COMPILE_ARGS)
- .registerFullyLinkAction(common.getObjcProvider());
+ .registerFullyLinkAction(common.getObjcProvider(),
+ ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB));
} else {
common = common(
ruleContext,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
index b7764f7dc5..1425c597db 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
@@ -31,6 +31,8 @@ import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.
import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration.ConfigurationDistinguisher;
import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
+import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.MultiArchPlatformRule;
+
import java.util.List;
/**
@@ -38,7 +40,7 @@ import java.util.List;
* accept different apple platform types (such as ios or watchos).
*/
public class MultiArchSplitTransitionProvider implements SplitTransitionProvider {
-
+
@VisibleForTesting
static final String UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT =
"Unsupported platform type \"%s\"";
@@ -54,11 +56,11 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
*/
public static PlatformType getPlatformType(RuleContext ruleContext) throws RuleErrorException {
String attributeValue =
- ruleContext.attributes().get(AppleBinaryRule.PLATFORM_TYPE_ATTR_NAME, STRING);
+ ruleContext.attributes().get(MultiArchPlatformRule.PLATFORM_TYPE_ATTR_NAME, STRING);
try {
return getPlatformType(attributeValue);
} catch (IllegalArgumentException exception) {
- throw ruleContext.throwWithAttributeError(AppleBinaryRule.PLATFORM_TYPE_ATTR_NAME,
+ throw ruleContext.throwWithAttributeError(MultiArchPlatformRule.PLATFORM_TYPE_ATTR_NAME,
String.format(UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT, attributeValue));
}
}
@@ -90,7 +92,7 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
@Override
public SplitTransition<?> apply(Rule fromRule) {
String platformTypeString = NonconfigurableAttributeMapper.of(fromRule)
- .get(AppleBinaryRule.PLATFORM_TYPE_ATTR_NAME, STRING);
+ .get(MultiArchPlatformRule.PLATFORM_TYPE_ATTR_NAME, STRING);
PlatformType platformType;
try {
platformType = getPlatformType(platformTypeString);
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 6341a60178..56fa39db3f 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
@@ -107,7 +107,8 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory {
CompilationSupport compilationSupport =
new CompilationSupport(ruleContext)
.registerCompileAndArchiveActions(common)
- .registerFullyLinkAction(common.getObjcProvider())
+ .registerFullyLinkAction(common.getObjcProvider(),
+ ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB))
.addXcodeSettings(xcodeProviderBuilder, common)
.validateAttributes();
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 c6b83be728..d88c3bda3e 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
@@ -111,6 +111,10 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive
public static final Key<Artifact> MULTI_ARCH_LINKED_BINARIES =
new Key<>(STABLE_ORDER, "combined_arch_linked_binary", Artifact.class);
+ /** Combined-architecture archives to include in the final bundle. */
+ public static final Key<Artifact> MULTI_ARCH_LINKED_ARCHIVES =
+ new Key<>(STABLE_ORDER, "combined_arch_linked_archive", Artifact.class);
+
/**
* Indicates which libraries to load with {@code -force_load}. This is a subset of the union of
* the {@link #LIBRARY} and {@link #IMPORTED_LIBRARY} sets.
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 54edc474ed..a75dc4ae7d 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
@@ -913,16 +913,16 @@ public class ObjcRuleClasses {
}
/**
- * Attribute name for apple platform type (e.g. ios or watchos).
- */
- static final String PLATFORM_TYPE_ATTR_NAME = "platform_type";
-
- /**
* Common attributes for apple rules that build multi-architecture outputs for a given platform
* type (such as ios or watchos).
*/
public static class MultiArchPlatformRule implements RuleDefinition {
+ /**
+ * Attribute name for apple platform type (e.g. ios or watchos).
+ */
+ static final String PLATFORM_TYPE_ATTR_NAME = "platform_type";
+
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
MultiArchSplitTransitionProvider splitTransitionProvider =