diff options
Diffstat (limited to 'src/main/java/com/google/devtools')
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(); |