aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java107
1 files changed, 91 insertions, 16 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
index 325c7bfc86..017d245b81 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
@@ -14,10 +14,14 @@
package com.google.devtools.build.lib.rules.objc;
+import static com.google.devtools.build.lib.syntax.Type.STRING;
+
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.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
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;
@@ -29,6 +33,7 @@ import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
import com.google.devtools.build.lib.packages.Attribute.SplitTransitionProvider;
+import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions;
@@ -59,9 +64,17 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
static final String REQUIRES_AT_LEAST_ONE_SOURCE_FILE =
"At least one source file is required (srcs, non_arc_srcs, or precompiled_srcs).";
+ @VisibleForTesting
+ static final String UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT =
+ "Unsupported platform type \"%s\"";
+
+ private static final ImmutableSet<PlatformType> SUPPORTED_APPLE_BINARY_PLATFORM_TYPES =
+ ImmutableSet.of(PlatformType.IOS, PlatformType.WATCHOS);
+
@Override
public final ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
+ PlatformType platformType = getPlatformType(ruleContext);
ImmutableListMultimap<BuildConfiguration, ObjcProvider> configurationToNonPropagatedObjcMap =
ruleContext.getPrerequisitesByConfiguration("non_propagated_deps", Mode.SPLIT,
ObjcProvider.class);
@@ -143,11 +156,11 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
.registerCombineArchitecturesAction(
binariesToLipo.build(),
ruleIntermediateArtifacts.combinedArchitectureBinary(),
- appleConfiguration.getMultiArchPlatform(PlatformType.IOS))
+ appleConfiguration.getMultiArchPlatform(platformType))
.registerCombineArchitecturesAction(
archivesToLipo.build(),
ruleContext.getImplicitOutputArtifact(AppleBinaryRule.LIPO_ARCHIVE),
- appleConfiguration.getMultiArchPlatform(PlatformType.IOS));
+ appleConfiguration.getMultiArchPlatform(platformType));
RuleConfiguredTargetBuilder targetBuilder =
ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build());
@@ -205,22 +218,59 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
return configToProvider.keySet();
}
+ private static PlatformType getPlatformType(RuleContext ruleContext) throws RuleErrorException {
+ try {
+ return getPlatformType(
+ ruleContext.attributes().get(AppleBinaryRule.PLATFORM_TYPE_ATTR_NAME, STRING));
+ } catch (IllegalArgumentException exception) {
+ throw ruleContext.throwWithAttributeError(AppleBinaryRule.PLATFORM_TYPE_ATTR_NAME,
+ String.format(UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT,
+ ruleContext.attributes().get(AppleBinaryRule.PLATFORM_TYPE_ATTR_NAME, STRING)));
+ }
+ }
+
+ private static PlatformType getPlatformType(String platformTypeString) {
+ PlatformType platformType = PlatformType.fromString(platformTypeString);
+
+ if (!SUPPORTED_APPLE_BINARY_PLATFORM_TYPES.contains(platformType)) {
+ throw new IllegalArgumentException(
+ String.format(UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT, platformTypeString));
+ } else {
+ return platformType;
+ }
+ }
+
/**
* {@link SplitTransitionProvider} implementation for the apple binary rule.
*/
public static class AppleBinaryTransitionProvider implements SplitTransitionProvider {
- private static final IosMultiCpusTransition IOS_MULTI_CPUS_SPLIT_TRANSITION =
- new IosMultiCpusTransition();
+ private static final ImmutableMap<PlatformType, AppleBinaryTransition>
+ SPLIT_TRANSITIONS_BY_TYPE = ImmutableMap.<PlatformType, AppleBinaryTransition>builder()
+ .put(PlatformType.IOS, new AppleBinaryTransition(PlatformType.IOS))
+ .put(PlatformType.WATCHOS, new AppleBinaryTransition(PlatformType.WATCHOS))
+ .build();
@Override
public SplitTransition<?> apply(Rule fromRule) {
- // TODO(cparsons): Support different split transitions based on rule attribute.
- return IOS_MULTI_CPUS_SPLIT_TRANSITION;
+ String platformTypeString = NonconfigurableAttributeMapper.of(fromRule)
+ .get(AppleBinaryRule.PLATFORM_TYPE_ATTR_NAME, STRING);
+ PlatformType platformType;
+ try {
+ platformType = getPlatformType(platformTypeString);
+ } catch (IllegalArgumentException exception) {
+ // There's no opportunity to propagate exception information up cleanly at the transition
+ // provider level. This will later be registered as a rule error during the initialization
+ // of the apple_binary target.
+ platformType = PlatformType.IOS;
+ }
+
+ return SPLIT_TRANSITIONS_BY_TYPE.get(platformType);
}
public List<SplitTransition<BuildOptions>> getPotentialSplitTransitions() {
- return ImmutableList.<SplitTransition<BuildOptions>>of(IOS_MULTI_CPUS_SPLIT_TRANSITION);
+ return ImmutableList.<SplitTransition<BuildOptions>>copyOf(
+ SPLIT_TRANSITIONS_BY_TYPE.values());
}
}
@@ -228,29 +278,54 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
* Transition that results in one configured target per architecture specified in {@code
* --ios_multi_cpus}.
*/
- protected static class IosMultiCpusTransition implements SplitTransition<BuildOptions> {
+ protected static class AppleBinaryTransition implements SplitTransition<BuildOptions> {
+
+ private final PlatformType platformType;
+
+ public AppleBinaryTransition(PlatformType platformType) {
+ this.platformType = platformType;
+ }
@Override
public final List<BuildOptions> split(BuildOptions buildOptions) {
- List<String> iosMultiCpus = buildOptions.get(AppleCommandLineOptions.class).iosMultiCpus;
+ List<String> cpus;
+ ConfigurationDistinguisher configurationDistinguisher;
+ switch (platformType) {
+ case IOS:
+ cpus = buildOptions.get(AppleCommandLineOptions.class).iosMultiCpus;
+ configurationDistinguisher = ConfigurationDistinguisher.APPLEBIN_IOS;
+ break;
+ case WATCHOS:
+ cpus = buildOptions.get(AppleCommandLineOptions.class).watchosCpus;
+ if (cpus.isEmpty()) {
+ cpus = ImmutableList.of(AppleCommandLineOptions.DEFAULT_WATCHOS_CPU);
+ }
+ configurationDistinguisher = ConfigurationDistinguisher.APPLEBIN_WATCHOS;
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported platform type " + platformType);
+ }
ImmutableList.Builder<BuildOptions> splitBuildOptions = ImmutableList.builder();
- for (String iosCpu : iosMultiCpus) {
+ for (String cpu : cpus) {
BuildOptions splitOptions = buildOptions.clone();
- splitOptions.get(AppleCommandLineOptions.class).iosMultiCpus = ImmutableList.of();
- splitOptions.get(AppleCommandLineOptions.class).applePlatformType = PlatformType.IOS;
- splitOptions.get(AppleCommandLineOptions.class).appleSplitCpu = iosCpu;
- splitOptions.get(AppleCommandLineOptions.class).iosCpu = iosCpu;
+ splitOptions.get(AppleCommandLineOptions.class).applePlatformType = platformType;
+ splitOptions.get(AppleCommandLineOptions.class).appleSplitCpu = cpu;
+ // Set for backwards compatibility with rules that depend on this flag, even when
+ // ios is not the platform type.
+ // TODO(b/28958783): Clean this up.
+ splitOptions.get(AppleCommandLineOptions.class).iosCpu = cpu;
if (splitOptions.get(ObjcCommandLineOptions.class).enableCcDeps) {
// Only set the (CC-compilation) CPU for dependencies if explicitly required by the user.
// This helps users of the iOS rules who do not depend on CC rules as these CPU values
// require additional flags to work (e.g. a custom crosstool) which now only need to be
// set if this feature is explicitly requested.
- splitOptions.get(BuildConfiguration.Options.class).cpu = "ios_" + iosCpu;
+ splitOptions.get(BuildConfiguration.Options.class).cpu =
+ String.format("%s_%s", platformType, cpu);
}
splitOptions.get(AppleCommandLineOptions.class).configurationDistinguisher =
- ConfigurationDistinguisher.APPLEBIN_IOS;
+ configurationDistinguisher;
splitBuildOptions.add(splitOptions);
}
return splitBuildOptions.build();