aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar cparsons <cparsons@google.com>2017-04-12 17:08:56 +0000
committerGravatar Jakob Buchgraber <buchgr@google.com>2017-04-13 09:36:47 +0200
commit7d0bcf93e518065f0458aa215db9487e25e1be4a (patch)
tree3e144be87d84e7f1d49c34ce62a518cf51acf362 /src
parent0fdc65e620fb746fc40b09a25e0c320b21a9ac78 (diff)
"minimum_os" attribute on multi-arch linking rules.
This issues a configuration transition on the dependencies of the rule, causing deps to be compiled with the appropriate minimum os version. RELNOTES: None. PiperOrigin-RevId: 152952168
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java89
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java14
5 files changed, 93 insertions, 17 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
index 36c0b903a2..da76148b03 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
@@ -184,6 +184,8 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
doc = "The minimum compatible OS version for target simulator and devices for a particular "
+ "platform type.")
public DottedVersion getMinimumOsForPlatformType(PlatformType platformType) {
+ // TODO(b/37240784): Look into using only a single minimum OS flag tied to the current
+ // apple_platform_type.
switch (platformType) {
case IOS:
return iosMinimumOs;
@@ -568,6 +570,7 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
if (!appleSplitCpu.isEmpty()) {
components.add(applePlatformType.toString().toLowerCase());
components.add(appleSplitCpu);
+ components.add("min" + getMinimumOsForPlatformType(applePlatformType));
}
if (shouldDistinguishOutputDirectory()) {
components.add(configurationDistinguisher.getFileSystemName());
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 124f3b97d5..9edc9b11e8 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
@@ -108,7 +108,9 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
@Override
public final ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
+ MultiArchSplitTransitionProvider.validateMinimumOs(ruleContext);
PlatformType platformType = MultiArchSplitTransitionProvider.getPlatformType(ruleContext);
+
AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
Platform platform = appleConfiguration.getMultiArchPlatform(platformType);
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
index 062f67229b..8e858bd0c2 100644
--- 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
@@ -73,7 +73,9 @@ public class AppleStaticLibrary implements RuleConfiguredTargetFactory {
@Override
public final ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
+ MultiArchSplitTransitionProvider.validateMinimumOs(ruleContext);
PlatformType platformType = MultiArchSplitTransitionProvider.getPlatformType(ruleContext);
+
ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap =
ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT);
ImmutableListMultimap<BuildConfiguration, ObjcProvider> configToObjcAvoidDepsMap =
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 36791eb025..de2c187328 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
@@ -17,8 +17,9 @@ 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.base.Strings;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
@@ -29,6 +30,7 @@ import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
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.DottedVersion;
import com.google.devtools.build.lib.rules.apple.Platform;
import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.MultiArchPlatformRule;
@@ -50,7 +52,7 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
/**
* Returns the apple platform type in the current rule context.
- *
+ *
* @throws RuleErrorException if the platform type attribute in the current rulecontext is
* an invalid value
*/
@@ -66,6 +68,28 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
}
/**
+ * Validates that minimum OS was set to a valid value on the current rule.
+
+ * @throws RuleErrorException if the platform type attribute in the current rulecontext is
+ * an invalid value
+ */
+ public static void validateMinimumOs(RuleContext ruleContext) throws RuleErrorException {
+ String attributeValue =
+ ruleContext.attributes().get(MultiArchPlatformRule.MINIMUM_OS_VERSION, STRING);
+ // TODO(b/37096178): This should be a mandatory attribute.
+ if (!Strings.isNullOrEmpty(attributeValue)) {
+ try {
+ // TODO(cparsons): Do more rigorous validation. For example, "8.2beta.3" is invalid, but
+ // will pass this validation.
+ DottedVersion.fromString(attributeValue);
+ } catch (IllegalArgumentException exception) {
+ throw ruleContext.throwWithAttributeError(MultiArchPlatformRule.PLATFORM_TYPE_ATTR_NAME,
+ String.format(UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT, attributeValue));
+ }
+ }
+ }
+
+ /**
* Returns the apple platform type for the given platform type string (corresponding directly
* with platform type attribute value).
*
@@ -82,29 +106,31 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
}
}
- 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))
- .put(PlatformType.TVOS, new AppleBinaryTransition(PlatformType.TVOS))
- .put(PlatformType.MACOS, new AppleBinaryTransition(PlatformType.MACOS))
- .build();
-
@Override
public SplitTransition<?> apply(Rule fromRule) {
String platformTypeString = NonconfigurableAttributeMapper.of(fromRule)
.get(MultiArchPlatformRule.PLATFORM_TYPE_ATTR_NAME, STRING);
+ String minimumOsVersionString = NonconfigurableAttributeMapper.of(fromRule)
+ .get(MultiArchPlatformRule.MINIMUM_OS_VERSION, STRING);
PlatformType platformType;
+ Optional<DottedVersion> minimumOsVersion;
try {
platformType = getPlatformType(platformTypeString);
+ // TODO(b/37096178): This should be a mandatory attribute.
+ if (Strings.isNullOrEmpty(minimumOsVersionString)) {
+ minimumOsVersion = Optional.absent();
+ } else {
+ minimumOsVersion = Optional.of(DottedVersion.fromString(minimumOsVersionString));
+ }
} catch (IllegalArgumentException exception) {
// There's no opportunity to propagate exception information up cleanly at the transition
// provider level. This should later be registered as a rule error during the initialization
// of the rule.
platformType = PlatformType.IOS;
+ minimumOsVersion = Optional.absent();
}
- return SPLIT_TRANSITIONS_BY_TYPE.get(platformType);
+ return new AppleBinaryTransition(platformType, minimumOsVersion);
}
/**
@@ -115,14 +141,19 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
protected static class AppleBinaryTransition implements SplitTransition<BuildOptions> {
private final PlatformType platformType;
+ // TODO(b/37096178): This should be a mandatory attribute.
+ private final Optional<DottedVersion> minimumOsVersion;
- public AppleBinaryTransition(PlatformType platformType) {
+ public AppleBinaryTransition(PlatformType platformType,
+ Optional<DottedVersion> minimumOsVersion) {
this.platformType = platformType;
+ this.minimumOsVersion = minimumOsVersion;
}
@Override
public final List<BuildOptions> split(BuildOptions buildOptions) {
List<String> cpus;
+ DottedVersion actualMinimumOsVersion;
ConfigurationDistinguisher configurationDistinguisher;
switch (platformType) {
case IOS:
@@ -131,6 +162,8 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
cpus = ImmutableList.of(buildOptions.get(AppleCommandLineOptions.class).iosCpu);
}
configurationDistinguisher = ConfigurationDistinguisher.APPLEBIN_IOS;
+ actualMinimumOsVersion = minimumOsVersion.isPresent() ? minimumOsVersion.get()
+ : buildOptions.get(AppleCommandLineOptions.class).iosMinimumOs;
break;
case WATCHOS:
cpus = buildOptions.get(AppleCommandLineOptions.class).watchosCpus;
@@ -138,6 +171,8 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
cpus = ImmutableList.of(AppleCommandLineOptions.DEFAULT_WATCHOS_CPU);
}
configurationDistinguisher = ConfigurationDistinguisher.APPLEBIN_WATCHOS;
+ actualMinimumOsVersion = minimumOsVersion.isPresent() ? minimumOsVersion.get()
+ : buildOptions.get(AppleCommandLineOptions.class).watchosMinimumOs;
break;
case TVOS:
cpus = buildOptions.get(AppleCommandLineOptions.class).tvosCpus;
@@ -145,6 +180,8 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
cpus = ImmutableList.of(AppleCommandLineOptions.DEFAULT_TVOS_CPU);
}
configurationDistinguisher = ConfigurationDistinguisher.APPLEBIN_TVOS;
+ actualMinimumOsVersion = minimumOsVersion.isPresent() ? minimumOsVersion.get()
+ : buildOptions.get(AppleCommandLineOptions.class).tvosMinimumOs;
break;
case MACOS:
cpus = buildOptions.get(AppleCommandLineOptions.class).macosCpus;
@@ -152,6 +189,8 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
cpus = ImmutableList.of(AppleCommandLineOptions.DEFAULT_MACOS_CPU);
}
configurationDistinguisher = ConfigurationDistinguisher.APPLEBIN_MACOS;
+ actualMinimumOsVersion = minimumOsVersion.isPresent() ? minimumOsVersion.get()
+ : buildOptions.get(AppleCommandLineOptions.class).macosMinimumOs;
break;
default:
throw new IllegalArgumentException("Unsupported platform type " + platformType);
@@ -160,13 +199,15 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
ImmutableList.Builder<BuildOptions> splitBuildOptions = ImmutableList.builder();
for (String cpu : cpus) {
BuildOptions splitOptions = buildOptions.clone();
+ AppleCommandLineOptions appleCommandLineOptions =
+ splitOptions.get(AppleCommandLineOptions.class);
- splitOptions.get(AppleCommandLineOptions.class).applePlatformType = platformType;
- splitOptions.get(AppleCommandLineOptions.class).appleSplitCpu = cpu;
+ appleCommandLineOptions.applePlatformType = platformType;
+ appleCommandLineOptions.appleSplitCpu = cpu;
// If the new configuration does not use the apple crosstool, then it needs ios_cpu to be
// to decide architecture.
// TODO(b/29355778, b/28403953): Use a crosstool for any apple rule. Deprecate ios_cpu.
- splitOptions.get(AppleCommandLineOptions.class).iosCpu = cpu;
+ appleCommandLineOptions.iosCpu = cpu;
if (splitOptions.get(ObjcCommandLineOptions.class).enableCcDeps) {
// Only set the (CC-compilation) CPU for dependencies if explicitly required by the user.
@@ -177,8 +218,22 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
AppleCrosstoolTransition.setAppleCrosstoolTransitionConfiguration(buildOptions,
splitOptions, platformCpu);
}
- splitOptions.get(AppleCommandLineOptions.class).configurationDistinguisher =
- configurationDistinguisher;
+ switch (platformType) {
+ case IOS:
+ appleCommandLineOptions.iosMinimumOs = actualMinimumOsVersion;
+ break;
+ case WATCHOS:
+ appleCommandLineOptions.watchosMinimumOs = actualMinimumOsVersion;
+ break;
+ case TVOS:
+ appleCommandLineOptions.tvosMinimumOs = actualMinimumOsVersion;
+ break;
+ case MACOS:
+ appleCommandLineOptions.macosMinimumOs = actualMinimumOsVersion;
+ break;
+ }
+
+ appleCommandLineOptions.configurationDistinguisher = configurationDistinguisher;
splitBuildOptions.add(splitOptions);
}
return splitBuildOptions.build();
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 b0d648dfb4..3a65932f9c 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
@@ -915,6 +915,11 @@ public class ObjcRuleClasses {
* Attribute name for apple platform type (e.g. ios or watchos).
*/
static final String PLATFORM_TYPE_ATTR_NAME = "platform_type";
+
+ /**
+ * Attribute name for the minimum OS version (e.g. "7.3").
+ */
+ static final String MINIMUM_OS_VERSION = "minimum_os_version";
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
@@ -945,6 +950,15 @@ public class ObjcRuleClasses {
.add(attr(PLATFORM_TYPE_ATTR_NAME, STRING)
.value(PlatformType.IOS.toString())
.nonconfigurable("Determines the configuration transition on deps"))
+ /* <!-- #BLAZE_RULE($apple_multiarch_rule).ATTRIBUTE(minimum_os) -->
+ The minimum OS version that this target and its dependencies should be built for.
+
+ This should be a dotted version string such as "7.3".
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ // TODO(b/37096178): This should be a mandatory attribute.
+ .add(
+ attr(MINIMUM_OS_VERSION, STRING)
+ .nonconfigurable("Determines the configuration transition on deps"))
.build();
}