aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java51
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/Platform.java48
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java107
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java26
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java67
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java14
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java4
11 files changed, 271 insertions, 72 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 3977caf460..9c0c47426d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -459,7 +459,8 @@ public final class RuleContext extends TargetContext
* <p>If the name of the attribute starts with <code>$</code>
* it is replaced with a string <code>(an implicit dependency)</code>.
*/
- public void throwWithAttributeError(String attrName, String message) throws RuleErrorException {
+ public RuleErrorException throwWithAttributeError(String attrName, String message)
+ throws RuleErrorException {
reporter.attributeError(attrName, message);
throw new RuleErrorException();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
index a691d9bbf9..379068dc09 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
@@ -87,6 +87,12 @@ public class AppleCommandLineOptions extends FragmentOptions {
@VisibleForTesting public static final String DEFAULT_WATCHOS_SDK_VERSION = "2.0";
@VisibleForTesting public static final String DEFAULT_MACOSX_SDK_VERSION = "10.10";
@VisibleForTesting public static final String DEFAULT_APPLETVOS_SDK_VERSION = "1.0";
+ @VisibleForTesting static final String DEFAULT_IOS_CPU = "x86_64";
+
+ /**
+ * The default watchos CPU value.
+ */
+ public static final String DEFAULT_WATCHOS_CPU = "i386";
@Option(name = "ios_cpu",
defaultValue = DEFAULT_IOS_CPU,
@@ -131,7 +137,12 @@ public class AppleCommandLineOptions extends FragmentOptions {
+ "is a universal binary containing all specified architectures.")
public List<String> iosMultiCpus;
- @VisibleForTesting static final String DEFAULT_IOS_CPU = "x86_64";
+ @Option(name = "watchos_cpus",
+ converter = CommaSeparatedOptionListConverter.class,
+ defaultValue = DEFAULT_WATCHOS_CPU,
+ category = "flags",
+ help = "Comma-separated list of architectures for which to build apple watchos binaries.")
+ public List<String> watchosCpus;
@Option(name = "default_ios_provisioning_profile",
defaultValue = "",
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 3b9745f8d5..ebc8c9831f 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
@@ -76,6 +76,7 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
private final ConfigurationDistinguisher configurationDistinguisher;
private final Optional<DottedVersion> xcodeVersion;
private final ImmutableList<String> iosMultiCpus;
+ private final ImmutableList<String> watchosCpus;
private final AppleBitcodeMode bitcodeMode;
private final Label xcodeConfigLabel;
@Nullable private final Label defaultProvisioningProfileLabel;
@@ -102,6 +103,9 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
this.configurationDistinguisher = appleOptions.configurationDistinguisher;
this.iosMultiCpus = ImmutableList.copyOf(
Preconditions.checkNotNull(appleOptions.iosMultiCpus, "iosMultiCpus"));
+ this.watchosCpus = (appleOptions.watchosCpus == null || appleOptions.watchosCpus.isEmpty())
+ ? ImmutableList.of(AppleCommandLineOptions.DEFAULT_WATCHOS_CPU)
+ : ImmutableList.copyOf(appleOptions.watchosCpus);
this.bitcodeMode = appleOptions.appleBitcodeMode;
this.xcodeConfigLabel =
Preconditions.checkNotNull(appleOptions.xcodeVersionConfig, "xcodeConfigLabel");
@@ -201,11 +205,13 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
public Map<String, String> appleTargetPlatformEnv(Platform platform) {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
- // TODO(bazel-team): Handle non-ios platforms.
- if (platform == Platform.IOS_DEVICE || platform == Platform.IOS_SIMULATOR) {
- String sdkVersion = getSdkVersionForPlatform(platform).toString();
- builder.put(AppleConfiguration.APPLE_SDK_VERSION_ENV_NAME, sdkVersion)
- .put(AppleConfiguration.APPLE_SDK_PLATFORM_ENV_NAME, platform.getNameInPlist());
+ // TODO(cparsons): Avoid setting SDK version for macosx. Until SDK version is
+ // evaluated for the current configuration xcode version, this would break users who build
+ // cc_* rules without specifying both xcode_version and macosx_sdk_version build options.
+ if (platform != Platform.MACOS_X) {
+ String sdkVersion = getSdkVersionForPlatform(platform).toString();
+ builder.put(AppleConfiguration.APPLE_SDK_VERSION_ENV_NAME, sdkVersion)
+ .put(AppleConfiguration.APPLE_SDK_PLATFORM_ENV_NAME, platform.getNameInPlist());
}
return builder.build();
}
@@ -246,7 +252,9 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
} else {
return getIosCpu();
}
- // TODO(cparsons): Support platform types other than iOS.
+ case WATCHOS:
+ return watchosCpus.get(0);
+ // TODO(cparsons): Handle all platform types.
default:
throw new IllegalArgumentException("Unhandled platform type " + applePlatformType);
}
@@ -286,7 +294,8 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
} else {
return getIosMultiCpus();
}
- // TODO(cparsons): Support other platform types.
+ case WATCHOS:
+ return watchosCpus;
default:
throw new IllegalArgumentException("Unhandled platform type " + platformType);
}
@@ -313,12 +322,24 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
// TODO(bazel-team): This should support returning multiple platforms.
public Platform getMultiArchPlatform(PlatformType platformType) {
List<String> architectures = getMultiArchitectures(platformType);
- for (String arch : architectures) {
- if (Platform.forTarget(PlatformType.IOS, arch) == Platform.IOS_DEVICE) {
- return Platform.IOS_DEVICE;
- }
+ switch (platformType) {
+ case IOS:
+ for (String arch : architectures) {
+ if (Platform.forTarget(PlatformType.IOS, arch) == Platform.IOS_DEVICE) {
+ return Platform.IOS_DEVICE;
+ }
+ }
+ return Platform.IOS_SIMULATOR;
+ case WATCHOS:
+ for (String arch : architectures) {
+ if (Platform.forTarget(PlatformType.WATCHOS, arch) == Platform.WATCHOS_DEVICE) {
+ return Platform.WATCHOS_DEVICE;
+ }
+ }
+ return Platform.WATCHOS_SIMULATOR;
+ default:
+ throw new IllegalArgumentException("Unsupported platform type " + platformType);
}
- return Platform.IOS_SIMULATOR;
}
/**
@@ -498,7 +519,9 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
FRAMEWORK,
/** Split transition distinguisher for {@code apple_watch1_extension} rule. */
WATCH_OS1_EXTENSION,
- /** Split transition distinguisher for {@code apple_binary} rule. */
- APPLEBIN_IOS
+ /** Distinguisher for {@code apple_binary} rule with "ios" platform_type. */
+ APPLEBIN_IOS,
+ /** Distinguisher for {@code apple_binary} rule with "watchos" platform_type. */
+ APPLEBIN_WATCHOS,
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
index 097f24f90d..15e0622914 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
@@ -140,6 +140,10 @@ public class AppleToolchain {
case MACOS_X:
relativePath = DEVELOPER_FRAMEWORK_PATH;
break;
+ case WATCHOS_DEVICE:
+ case WATCHOS_SIMULATOR:
+ relativePath = SYSTEM_FRAMEWORK_PATH;
+ break;
default:
throw new IllegalArgumentException("Unhandled platform " + targetPlatform);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/Platform.java b/src/main/java/com/google/devtools/build/lib/rules/apple/Platform.java
index 21c17550bf..7a8b1d1990 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/Platform.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/Platform.java
@@ -29,25 +29,39 @@ import javax.annotation.Nullable;
*/
@SkylarkModule(name = "platform", doc = "Distinguishes between various apple platforms.")
public enum Platform {
- IOS_DEVICE("iPhoneOS"),
- IOS_SIMULATOR("iPhoneSimulator"),
- MACOS_X("MacOSX"),
- TVOS_DEVICE("AppleTVOS"),
- TVOS_SIMULATOR("AppleTVSimulator"),
- WATCHOS_DEVICE("WatchOS"),
- WATCHOS_SIMULATOR("WatchSimulator");
+
+ IOS_DEVICE("iPhoneOS", PlatformType.IOS),
+ IOS_SIMULATOR("iPhoneSimulator", PlatformType.IOS),
+ MACOS_X("MacOSX", PlatformType.MACOSX),
+ TVOS_DEVICE("AppleTVOS", PlatformType.TVOS),
+ TVOS_SIMULATOR("AppleTVSimulator", PlatformType.TVOS),
+ WATCHOS_DEVICE("WatchOS", PlatformType.WATCHOS),
+ WATCHOS_SIMULATOR("WatchSimulator", PlatformType.WATCHOS);
private static final Set<String> IOS_SIMULATOR_TARGET_CPUS =
ImmutableSet.of("ios_x86_64", "ios_i386");
+ private static final Set<String> WATCHOS_SIMULATOR_TARGET_CPUS =
+ ImmutableSet.of("watchos_i386");
+ private static final Set<String> WATCHOS_DEVICE_TARGET_CPUS =
+ ImmutableSet.of("watchos_armv7k");
private static final Set<String> IOS_DEVICE_TARGET_CPUS =
ImmutableSet.of("ios_armv6", "ios_arm64", "ios_armv7", "ios_armv7s");
private static final Set<String> MACOSX_TARGET_CPUS =
ImmutableSet.of("darwin_x86_64");
private final String nameInPlist;
+ private final PlatformType platformType;
- Platform(String nameInPlist) {
+ Platform(String nameInPlist, PlatformType platformType) {
this.nameInPlist = Preconditions.checkNotNull(nameInPlist);
+ this.platformType = platformType;
+ }
+
+ /**
+ * Returns the platform type of this platform.
+ */
+ public PlatformType getType() {
+ return platformType;
}
/**
@@ -75,6 +89,10 @@ public enum Platform {
return IOS_SIMULATOR;
} else if (IOS_DEVICE_TARGET_CPUS.contains(targetCpu)) {
return IOS_DEVICE;
+ } else if (WATCHOS_SIMULATOR_TARGET_CPUS.contains(targetCpu)) {
+ return WATCHOS_SIMULATOR;
+ } else if (WATCHOS_DEVICE_TARGET_CPUS.contains(targetCpu)) {
+ return WATCHOS_DEVICE;
} else if (MACOSX_TARGET_CPUS.contains(targetCpu)) {
return MACOS_X;
} else {
@@ -131,5 +149,19 @@ public enum Platform {
public String toString() {
return name().toLowerCase();
}
+
+ /**
+ * Returns the {@link PlatformType} with given name (case insensitive).
+ *
+ * @throws IllegalArgumentException if the name does not match a valid platform type.
+ */
+ public static PlatformType fromString(String name) {
+ for (PlatformType platformType : PlatformType.values()) {
+ if (name.equalsIgnoreCase(platformType.toString())) {
+ return platformType;
+ }
+ }
+ throw new IllegalArgumentException(String.format("Unsupported platform type \"%s\"", name));
+ }
}
}
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();
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 33920dec84..e69834d2f3 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
@@ -18,6 +18,7 @@ import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
+import static com.google.devtools.build.lib.syntax.Type.STRING;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
@@ -27,6 +28,7 @@ import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplic
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.apple.Platform.PlatformType;
/**
* Rule definition for apple_binary.
@@ -34,6 +36,12 @@ 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).
*/
@@ -60,6 +68,24 @@ public class AppleBinaryRule implements RuleDefinition {
.add(attr(":cc_toolchain", LABEL)
.cfg(AppleBinary.SPLIT_TRANSITION_PROVIDER)
.value(ObjcRuleClasses.APPLE_TOOLCHAIN))
+ /* <!-- #BLAZE_RULE(apple_binary).ATTRIBUTE(platform_type) -->
+ The type of platform for which to create multi-architecture "fat" binaries in this rule.
+ For example, if <code>ios</code> is selected, then fat binaries will be created
+ combining all architectures specified in <code>--ios_multi_cpus</code>.
+
+ Options are:
+ <ul>
+ <li>
+ <code>ios</code> (default): architectures gathered from <code>--ios_multi_cpus</code>.
+ </li>
+ <li>
+ <code>watchos</code>: architectures gathered from <code>--watchos_multi_cpus</code>
+ </li>
+ </ul>
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr(PLATFORM_TYPE_ATTR_NAME, STRING)
+ .value(PlatformType.IOS.toString())
+ .nonconfigurable("Determines the configuration transition on deps"))
/*<!-- #BLAZE_RULE(apple_binary).IMPLICIT_OUTPUTS -->
<ul>
<li><code><var>name</var>_lipobin</code>: the 'lipo'ed potentially multi-architecture
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 995a65d502..8e1fb4b147 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
@@ -64,7 +64,6 @@ import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts;
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.ActionConstructionContext;
import com.google.devtools.build.lib.analysis.actions.CommandLine;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
@@ -81,6 +80,7 @@ import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.AppleToolchain;
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.cpp.CppModuleMap;
import com.google.devtools.build.lib.rules.cpp.CppModuleMapAction;
import com.google.devtools.build.lib.rules.cpp.LinkerInputs;
@@ -131,7 +131,7 @@ public final class CompilationSupport {
// These are added by Xcode when building, because the simulator is built on OSX
// frameworks so we aim compile to match the OSX objc runtime.
@VisibleForTesting
- static final ImmutableList<String> IOS_SIMULATOR_COMPILE_FLAGS =
+ static final ImmutableList<String> SIMULATOR_COMPILE_FLAGS =
ImmutableList.of(
"-fexceptions", "-fasm-blocks", "-fobjc-abi-version=2", "-fobjc-legacy-dispatch");
@@ -567,7 +567,7 @@ public final class CompilationSupport {
// TODO(bazel-team): Remote private headers from inputs once they're added to the provider.
ruleContext.registerAction(
ObjcRuleClasses.spawnAppleEnvActionBuilder(
- ruleContext, appleConfiguration.getSingleArchPlatform())
+ appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("ObjcCompile")
.setExecutable(xcrunwrapper(ruleContext))
.setCommandLine(commandLine.build())
@@ -696,7 +696,7 @@ public final class CompilationSupport {
ruleContext.registerAction(
ObjcRuleClasses.spawnAppleEnvActionBuilder(
- ruleContext, appleConfiguration.getSingleArchPlatform())
+ appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("SwiftCompile")
.setExecutable(xcrunwrapper(ruleContext))
.setCommandLine(commandLine.build())
@@ -766,7 +766,7 @@ public final class CompilationSupport {
commandLine.add(commonFrameworkFlags(objcProvider, appleConfiguration));
ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder(
- ruleContext, appleConfiguration.getSingleArchPlatform())
+ appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("SwiftModuleMerge")
.setExecutable(xcrunwrapper(ruleContext))
.setCommandLine(commandLine.build())
@@ -780,13 +780,12 @@ public final class CompilationSupport {
private void registerArchiveActions(ImmutableList.Builder<Artifact> objFiles, Artifact archive) {
for (Action action :
- archiveActions(ruleContext, objFiles.build(), archive, intermediateArtifacts.objList())) {
+ archiveActions(objFiles.build(), archive, intermediateArtifacts.objList())) {
ruleContext.registerAction(action);
}
}
private Iterable<Action> archiveActions(
- ActionConstructionContext context,
Iterable<Artifact> objFiles,
Artifact archive,
Artifact objList) {
@@ -794,13 +793,13 @@ public final class CompilationSupport {
ImmutableList.Builder<Action> actions = new ImmutableList.Builder<>();
actions.add(new FileWriteAction(
- context.getActionOwner(),
+ ruleContext.getActionOwner(),
objList,
Artifact.joinExecPaths("\n", objFiles),
/*makeExecutable=*/ false));
actions.add(ObjcRuleClasses.spawnAppleEnvActionBuilder(
- ruleContext, appleConfiguration.getSingleArchPlatform())
+ appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("ObjcLink")
.setExecutable(libtool(ruleContext))
.setCommandLine(new CustomCommandLine.Builder()
@@ -813,7 +812,7 @@ public final class CompilationSupport {
.addInputs(objFiles)
.addInput(objList)
.addOutput(archive)
- .build(context));
+ .build(ruleContext));
return actions.build();
}
@@ -831,7 +830,7 @@ public final class CompilationSupport {
ImmutableList<Artifact> objcLibraries = objcLibraries(objcProvider);
ImmutableList<Artifact> ccLibraries = ccLibraries(objcProvider);
ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder(
- ruleContext, appleConfiguration.getSingleArchPlatform())
+ appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("ObjcLink")
.setExecutable(libtool(ruleContext))
.setCommandLine(new CustomCommandLine.Builder()
@@ -1033,7 +1032,7 @@ public final class CompilationSupport {
linkmap);
ruleContext.registerAction(
ObjcRuleClasses.spawnAppleEnvActionBuilder(
- ruleContext, appleConfiguration.getSingleArchPlatform())
+ appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("ObjcLink")
.setShellCommand(ImmutableList.of("/bin/bash", "-c"))
.setCommandLine(new SingleArgCommandLine(commandLine))
@@ -1067,7 +1066,7 @@ public final class CompilationSupport {
ruleContext.registerAction(
ObjcRuleClasses.spawnAppleEnvActionBuilder(
- ruleContext, appleConfiguration.getSingleArchPlatform())
+ appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("ObjcBinarySymbolStrip")
.setExecutable(xcrunwrapper(ruleContext))
.setCommandLine(symbolStripCommandLine(stripArgs, binaryToLink, strippedBinary))
@@ -1337,7 +1336,7 @@ public final class CompilationSupport {
commandLine,
ParameterFile.ParameterFileType.UNQUOTED, ISO_8859_1));
ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder(
- ruleContext, appleConfiguration.getSingleArchPlatform())
+ appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("DummyPruner")
.setExecutable(pruner)
.addInput(dummyArchive)
@@ -1561,17 +1560,29 @@ public final class CompilationSupport {
/**
* Returns a list of clang flags used for all link and compile actions executed through clang.
*/
- private static List<String> commonLinkAndCompileFlagsForClang(
+ private List<String> commonLinkAndCompileFlagsForClang(
ObjcProvider provider, ObjcConfiguration objcConfiguration,
AppleConfiguration appleConfiguration) {
ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
Platform platform = appleConfiguration.getSingleArchPlatform();
- if (platform == Platform.IOS_SIMULATOR) {
- builder.add("-mios-simulator-version-min=" + objcConfiguration.getMinimumOs());
- } else {
- builder.add("-miphoneos-version-min=" + objcConfiguration.getMinimumOs());
+ switch (platform) {
+ case IOS_SIMULATOR:
+ builder.add("-mios-simulator-version-min=" + objcConfiguration.getMinimumOs());
+ break;
+ case IOS_DEVICE:
+ builder.add("-miphoneos-version-min=" + objcConfiguration.getMinimumOs());
+ break;
+ case WATCHOS_SIMULATOR:
+ builder.add("-mwatchos-simulator-version-min="
+ + appleConfiguration.getSdkVersionForPlatform(platform));
+ break;
+ case WATCHOS_DEVICE:
+ builder.add("-mwatchos-version-min="
+ + appleConfiguration.getSdkVersionForPlatform(platform));
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled platform " + platform);
}
-
if (objcConfiguration.generateDebugSymbols() || objcConfiguration.generateDsym()) {
builder.add("-g");
}
@@ -1589,7 +1600,8 @@ public final class CompilationSupport {
*/
static Iterable<String> commonFrameworkFlags(
ObjcProvider provider, AppleConfiguration appleConfiguration) {
- return Interspersing.beforeEach("-F", commonFrameworkNames(provider, appleConfiguration));
+ return Interspersing.beforeEach("-F",
+ commonFrameworkNames(provider, appleConfiguration));
}
/**
@@ -1599,10 +1611,13 @@ public final class CompilationSupport {
ObjcProvider provider, AppleConfiguration appleConfiguration) {
Platform platform = appleConfiguration.getSingleArchPlatform();
- return new ImmutableList.Builder<String>()
- .add(AppleToolchain.sdkFrameworkDir(platform, appleConfiguration))
+ ImmutableList.Builder<String> frameworkNames = new ImmutableList.Builder<String>()
+ .add(AppleToolchain.sdkFrameworkDir(platform, appleConfiguration));
+ if (platform.getType() == PlatformType.IOS) {
// As of sdk8.1, XCTest is in a base Framework dir
- .add(AppleToolchain.platformDeveloperFrameworkDir(appleConfiguration))
+ frameworkNames.add(AppleToolchain.platformDeveloperFrameworkDir(appleConfiguration));
+ }
+ return frameworkNames
// Add custom (non-SDK) framework search paths. For each framework foo/bar.framework,
// include "foo" as a search path.
.addAll(PathFragment.safePathStrings(uniqueParentDirectories(provider.get(FRAMEWORK_DIR))))
@@ -1627,9 +1642,11 @@ public final class CompilationSupport {
AppleConfiguration configuration) {
switch (configuration.getSingleArchPlatform()) {
case IOS_DEVICE:
+ case WATCHOS_DEVICE:
return ImmutableList.of();
case IOS_SIMULATOR:
- return IOS_SIMULATOR_COMPILE_FLAGS;
+ case WATCHOS_SIMULATOR:
+ return SIMULATOR_COMPILE_FLAGS;
default:
throw new AssertionError();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
index e6a720b619..8e8f309d77 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
@@ -79,10 +79,10 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory {
}
private void addFrameworkVariables(Builder builder) {
- ValueSequence.Builder frameworkSequence = new ValueSequence.Builder();
+ ValueSequence.Builder frameworkSequence = new ValueSequence.Builder();
+ AppleConfiguration appleConfig = ruleContext.getFragment(AppleConfiguration.class);
for (String framework :
- CompilationSupport.commonFrameworkNames(
- objcProvider, ruleContext.getFragment(AppleConfiguration.class))) {
+ CompilationSupport.commonFrameworkNames(objcProvider, appleConfig)) {
frameworkSequence.addValue(framework);
}
builder.addSequence(FRAMEWORKS_VARIABLE_NAME, frameworkSequence.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 47cd99374b..a9edec73a5 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
@@ -201,8 +201,18 @@ public class ObjcRuleClasses {
// retrieving it from the rule context.
static SpawnAction.Builder spawnAppleEnvActionBuilder(RuleContext ruleContext,
Platform targetPlatform) {
- AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
-
+ return spawnAppleEnvActionBuilder(
+ ruleContext.getFragment(AppleConfiguration.class), targetPlatform);
+ }
+
+ /**
+ * Creates a new spawn action builder with apple environment variables set that are typically
+ * needed by the apple toolchain. This should be used to start to build spawn actions that, in
+ * order to run, require both a darwin architecture and a collection of environment variables
+ * which contain information about the target and host architectures.
+ */
+ static SpawnAction.Builder spawnAppleEnvActionBuilder(AppleConfiguration appleConfiguration,
+ Platform targetPlatform) {
ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.<String, String>builder()
.putAll(appleConfiguration.getTargetAppleEnvironment(targetPlatform))
.putAll(appleConfiguration.getAppleHostSystemEnv());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java
index 4719bfce58..5e6b227895 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java
@@ -30,7 +30,6 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
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.XcodeProvider.Builder;
import com.google.devtools.build.lib.rules.objc.XcodeProvider.Project;
import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos;
@@ -272,7 +271,8 @@ public final class XcodeSupport {
this.project = project;
this.pbxproj = pbxproj;
this.workspaceRoot = objcConfiguration.getXcodeWorkspaceRoot();
- this.appleCpus = appleConfiguration.getMultiArchitectures(PlatformType.IOS);
+ this.appleCpus = appleConfiguration.getMultiArchitectures(
+ appleConfiguration.getSingleArchPlatform().getType());
this.minimumOs = objcConfiguration.getMinimumOs().toString();
this.generateDebugSymbols =
objcConfiguration.generateDebugSymbols() || objcConfiguration.generateDsym();