diff options
author | 2015-04-23 13:21:02 +0000 | |
---|---|---|
committer | 2015-04-24 10:11:42 +0000 | |
commit | c9eb84311ab6281ac48ed6cbbe18544eecc9ec74 (patch) | |
tree | 0b9d5da2db156a6def6a6390bc70115f581d0361 /src | |
parent | 959ba5ec5f1d374fc0178906526c8c0459e03eed (diff) |
Description redacted.
--
MOS_MIGRATED_REVID=91881146
Diffstat (limited to 'src')
20 files changed, 149 insertions, 312 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java index 7475baf6f2..0566525aac 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java @@ -90,12 +90,10 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory Optional<RunfilesSupport> maybeRunfilesSupport = Optional.absent(); switch (hasReleaseBundlingSupport) { case YES: - ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); // TODO(bazel-team): Remove once all bundle users are migrated to ios_application. ReleaseBundlingSupport releaseBundlingSupport = new ReleaseBundlingSupport( ruleContext, objcProvider, optionsProvider, - LinkedBinary.LOCAL_AND_DEPENDENCIES, ReleaseBundlingSupport.APP_BUNDLE_DIR_FORMAT, - objcConfiguration.getMinimumOs()); + LinkedBinary.LOCAL_AND_DEPENDENCIES, ReleaseBundlingSupport.APP_BUNDLE_DIR_FORMAT); releaseBundlingSupport .registerActions() .addXcodeSettings(xcodeProviderBuilder) @@ -103,6 +101,7 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory .validateResources() .validateAttributes(); + ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); xcTestAppProvider = Optional.of(releaseBundlingSupport.xcTestAppProvider()); if (objcConfiguration.getBundlingPlatform() == Platform.SIMULATOR) { Artifact runnerScript = intermediateArtifacts.runnerScript(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java index a90e23b8e6..d0be20c12e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java @@ -67,7 +67,7 @@ final class BundleMergeControlBytes extends ByteSource { .addAllSourcePlistFile(Artifact.toExecPaths( bundling.getInfoplistMerging().getPlistWithEverything().asSet())) // TODO(bazel-team): Add rule attribute for specifying targeted device family - .setMinimumOsVersion(bundling.getMinimumOsVersion()) + .setMinimumOsVersion(objcConfiguration.getMinimumOs()) .setSdkVersion(objcConfiguration.getIosSdkVersion()) .setPlatform(objcConfiguration.getBundlingPlatform().name()) .setBundleRoot(bundling.getBundleDir()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java index 4b586c1e6a..8d51f5752d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java @@ -20,6 +20,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCASSETS_DIR import com.google.common.base.Optional; import com.google.common.base.Verify; +import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; @@ -191,6 +192,8 @@ final class BundleSupport { private void registerInterfaceBuilderActions(ObjcProvider objcProvider) { IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); + ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); + String minimumOs = objcConfiguration.getMinimumOs(); for (Artifact storyboardInput : objcProvider.get(ObjcProvider.STORYBOARD)) { String archiveRoot = BundleableFile.flatBundlePath(storyboardInput.getExecPath()) + "c"; Artifact zipOutput = intermediateArtifacts.compiledStoryboardZip(storyboardInput); @@ -205,7 +208,7 @@ final class BundleSupport { .add(archiveRoot) .addPath(ObjcActionsBuilder.IBTOOL) - .add("--minimum-deployment-target").add(bundling.getMinimumOsVersion()) + .add("--minimum-deployment-target").add(minimumOs) .addPath(storyboardInput.getExecPath()) .build()) .addOutput(zipOutput) @@ -231,21 +234,25 @@ final class BundleSupport { .addPath(outputZip.getExecPath()) .add(datamodel.archiveRootForMomczip()) .add(IosSdkCommands.MOMC_PATH) - - .add("-XD_MOMC_SDKROOT=" + IosSdkCommands.sdkDir(objcConfiguration)) - .add("-XD_MOMC_IOS_TARGET_VERSION=" + bundling.getMinimumOsVersion()) - .add("-MOMC_PLATFORMS") - .add(objcConfiguration.getBundlingPlatform().getLowerCaseNameInPlist()) - .add("-XD_MOMC_TARGET_VERSION=10.6") + .add(commonMomczipArguments(objcConfiguration)) .add(datamodel.getContainer().getSafePathString()) .build()) .build(ruleContext)); } } + static Iterable<String> commonMomczipArguments(ObjcConfiguration configuration) { + return ImmutableList.of( + "-XD_MOMC_SDKROOT=" + IosSdkCommands.sdkDir(configuration), + "-XD_MOMC_IOS_TARGET_VERSION=" + configuration.getMinimumOs(), + "-MOMC_PLATFORMS", configuration.getBundlingPlatform().getLowerCaseNameInPlist(), + "-XD_MOMC_TARGET_VERSION=10.6"); + } + private void registerConvertXibsActions(ObjcProvider objcProvider) { IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); + ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); for (Artifact original : objcProvider.get(ObjcProvider.XIB)) { Artifact zipOutput = intermediateArtifacts.compiledXibFileZip(original); String archiveRoot = BundleableFile.flatBundlePath( @@ -260,7 +267,7 @@ final class BundleSupport { .add(archiveRoot) .addPath(ObjcActionsBuilder.IBTOOL) - .add("--minimum-deployment-target").add(bundling.getMinimumOsVersion()) + .add("--minimum-deployment-target").add(objcConfiguration.getMinimumOs()) .addPath(original.getExecPath()) .build()) .addOutput(zipOutput) @@ -287,6 +294,15 @@ final class BundleSupport { } } + /** + * Validates any rule attributes and dependencies related to this bundle. + * + * @return this bundle support + */ + BundleSupport validateAttributes() { + return this; + } + private void registerMergeInfoplistAction() { // TODO(bazel-team): Move action implementation from InfoplistMerging to this class. ruleContext.registerAction(bundling.getInfoplistMerging().getMergeAction()); @@ -332,7 +348,7 @@ final class BundleSupport { .add("--platform").add(objcConfiguration.getBundlingPlatform().getLowerCaseNameInPlist()) .addExecPath("--output-partial-info-plist", partialInfoPlist) - .add("--minimum-deployment-target").add(bundling.getMinimumOsVersion()); + .add("--minimum-deployment-target").add(objcConfiguration.getMinimumOs()); for (TargetDeviceFamily targetDeviceFamily : targetDeviceFamilies) { commandLine.add("--target-device").add(targetDeviceFamily.name().toLowerCase(Locale.US)); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java index 1ddc16a749..8b5edfdabb 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java @@ -28,6 +28,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XIB; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; @@ -56,7 +57,6 @@ final class Bundling { private String primaryBundleId; private String fallbackBundleId; private String architecture; - private String minimumOsVersion; public Builder setName(String name) { this.name = name; @@ -107,15 +107,6 @@ final class Bundling { return this; } - /** - * Sets the minimum OS version for this bundle which will be used when constructing the bundle's - * plist. - */ - public Builder setMinimumOsVersion(String minimumOsVersion) { - this.minimumOsVersion = minimumOsVersion; - return this; - } - private static NestedSet<Artifact> nestedBundleContentArtifacts(Iterable<Bundling> bundles) { NestedSetBuilder<Artifact> artifacts = NestedSetBuilder.stableOrder(); for (Bundling bundle : bundles) { @@ -184,7 +175,7 @@ final class Bundling { return new Bundling(name, bundleDirFormat, combinedArchitectureBinary, extraBundleFiles, objcProvider, infoplistMerging, actoolzipOutput, bundleContentArtifactsBuilder.build(), - mergeZips, primaryBundleId, fallbackBundleId, architecture, minimumOsVersion); + mergeZips, primaryBundleId, fallbackBundleId, architecture); } } @@ -200,7 +191,6 @@ final class Bundling { private final NestedSet<Artifact> mergeZips; private final String primaryBundleId; private final String fallbackBundleId; - private final String minimumOsVersion; private Bundling( String name, @@ -214,8 +204,7 @@ final class Bundling { NestedSet<Artifact> mergeZips, String primaryBundleId, String fallbackBundleId, - String architecture, - String minimumOsVersion) { + String architecture) { this.name = Preconditions.checkNotNull(name); this.bundleDirFormat = Preconditions.checkNotNull(bundleDirFormat); this.combinedArchitectureBinary = Preconditions.checkNotNull(combinedArchitectureBinary); @@ -228,7 +217,6 @@ final class Bundling { this.fallbackBundleId = fallbackBundleId; this.primaryBundleId = primaryBundleId; this.architecture = Preconditions.checkNotNull(architecture); - this.minimumOsVersion = Preconditions.checkNotNull(minimumOsVersion); } /** @@ -340,12 +328,4 @@ final class Bundling { public String getArchitecture() { return architecture; } - - /** - * Returns the minimum iOS version this bundle's plist and resources should be generated for - * (does <b>not</b> affect the minimum OS version its binary is compiled with). - */ - public String getMinimumOsVersion() { - return minimumOsVersion; - } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java index ee1a3edf88..d852bb49cd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java @@ -43,7 +43,7 @@ final class IntermediateArtifacts { private final String archiveFileNameSuffix; /** - * Label to scope the output paths of generated artifacts, in addition to {@link #ownerLabel}. + * Label to scope the output paths of generated artifacts, in addition to {@link ownerLabel}. */ private final Optional<Label> scopingLabel; @@ -231,8 +231,9 @@ final class IntermediateArtifacts { * file. */ public Artifact compiledXibFileZip(Artifact originalFile) { - return appendExtension( - "/" + FileSystemUtils.replaceExtension(originalFile.getExecPath(), ".nib.zip")); + return analysisEnvironment.getDerivedArtifact( + FileSystemUtils.replaceExtension(originalFile.getExecPath(), ".nib.zip"), + binDirectory); } /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java index d76d1c0af5..4b8c7603aa 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java @@ -20,23 +20,12 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.analysis.config.BuildOptions; -import com.google.devtools.build.lib.packages.Attribute.SplitTransition; -import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.SplitArchTransition; /** * Implementation for {@code ios_application}. */ public class IosApplication extends ReleaseBundlingTargetFactory { - /** - * Transition that when applied to a target generates a configured target for each value in - * {@code --ios_multi_cpus}, such that {@code --ios_cpu} is set to a different one of those values - * in the configured targets. - */ - public static final SplitTransition<BuildOptions> SPLIT_ARCH_TRANSITION = - new SplitArchTransition(); - private static final ImmutableSet<Attribute> DEPENDENCY_ATTRIBUTES = ImmutableSet.of( new Attribute("binary", Mode.SPLIT), diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplicationRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplicationRule.java index 37a08c4530..898150baa9 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplicationRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplicationRule.java @@ -54,7 +54,7 @@ public class IosApplicationRule implements RuleDefinition { .allowedFileTypes() .mandatory() .direct_compile_time_input() - .cfg(IosApplication.SPLIT_ARCH_TRANSITION)) + .cfg(ReleaseBundlingSupport.SPLIT_ARCH_TRANSITION)) /* <!-- #BLAZE_RULE(ios_application).ATTRIBUTE(extensions) --> Any extensions to include in the final application. ${SYNOPSIS} diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java index c1ceab997c..fa2e8fbef6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java @@ -14,41 +14,18 @@ package com.google.devtools.build.lib.rules.objc; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.analysis.config.BuildOptions; -import com.google.devtools.build.lib.packages.Attribute.SplitTransition; -import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.SplitArchTransition; - -import java.io.Serializable; /** * Implementation for {@code ios_extension}. */ public class IosExtension extends ReleaseBundlingTargetFactory { - /** - * Transition that when applied to a target generates a configured target for each value in - * {@code --ios_multi_cpus}, such that {@code --ios_cpu} is set to a different one of those values - * in the configured targets. - * - * <p>Also ensures that, no matter whether {@code --ios_multi_cpus} is set, {@code - * --ios_minimum_os} is at least {@code 8.0} as Apple requires this for extensions. - */ - static final SplitTransition<BuildOptions> MINIMUM_OS_AND_SPLIT_ARCH_TRANSITION = - new ExtensionSplitArchTransition(); - - // Apple only accepts extensions starting at 8.0. - @VisibleForTesting - static final String EXTENSION_MINIMUM_OS_VERSION = "8.0"; - public IosExtension() { super(ReleaseBundlingSupport.EXTENSION_BUNDLE_DIR_FORMAT, XcodeProductType.EXTENSION, - ExposeAsNestedBundle.YES, ImmutableSet.of(new Attribute("binary", Mode.SPLIT)) - ); + ExposeAsNestedBundle.YES, ImmutableSet.of(new Attribute("binary", Mode.SPLIT))); } protected OptionsProvider optionsProvider(RuleContext ruleContext) { @@ -56,58 +33,4 @@ public class IosExtension extends ReleaseBundlingTargetFactory { .addInfoplists(ruleContext.getPrerequisiteArtifacts("infoplist", Mode.TARGET).list()) .build(); } - - @Override - protected String bundleMinimumOsVersion(RuleContext ruleContext) { - return determineMinimumOsVersion(ObjcRuleClasses.objcConfiguration(ruleContext).getMinimumOs()); - } - - private static String determineMinimumOsVersion(String fromFlag) { - if (Double.parseDouble(fromFlag) < Double.parseDouble(EXTENSION_MINIMUM_OS_VERSION)) { - // Extensions are not accepted by Apple below version 8.0. While applications built with a - // minimum iOS version of less than 8.0 may contain extensions in their bundle, the extension - // itself needs to be built with 8.0 or higher. This logic overrides (if necessary) any - // flag-set minimum iOS version for extensions only so that this requirement is not violated. - return EXTENSION_MINIMUM_OS_VERSION; - } - return fromFlag; - } - - /** - * Split transition that configures the minimum iOS version in addition to architecture splitting. - */ - private static class ExtensionSplitArchTransition extends SplitArchTransition - implements Serializable { - - @Override - protected ImmutableList<BuildOptions> defaultOptions(BuildOptions originalOptions) { - ObjcCommandLineOptions objcOptions = originalOptions.get(ObjcCommandLineOptions.class); - String newMinimumVersion = determineMinimumOsVersion(objcOptions.iosMinimumOs); - - if (newMinimumVersion.equals(objcOptions.iosMinimumOs)) { - return ImmutableList.of(); - } - - BuildOptions splitOptions = originalOptions.clone(); - setMinimumOsVersion(splitOptions, newMinimumVersion); - splitOptions.get(ObjcCommandLineOptions.class).configurationDistinguisher = - getConfigurationDistinguisher(); - return ImmutableList.of(splitOptions); - } - - @Override - protected void setAdditionalOptions(BuildOptions splitOptions, BuildOptions originalOptions) { - String fromFlag = originalOptions.get(ObjcCommandLineOptions.class).iosMinimumOs; - setMinimumOsVersion(splitOptions, determineMinimumOsVersion(fromFlag)); - } - - @Override - protected ConfigurationDistinguisher getConfigurationDistinguisher() { - return ConfigurationDistinguisher.EXTENSION; - } - - private void setMinimumOsVersion(BuildOptions splitOptions, String newMinimumVersion) { - splitOptions.get(ObjcCommandLineOptions.class).iosMinimumOs = newMinimumVersion; - } - } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java index 76d6290561..eaf0f0a8fd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java @@ -50,7 +50,7 @@ public class IosExtensionRule implements RuleDefinition { .allowedFileTypes() .mandatory() .direct_compile_time_input() - .cfg(IosExtension.MINIMUM_OS_AND_SPLIT_ARCH_TRANSITION)) + .cfg(ReleaseBundlingSupport.SPLIT_ARCH_TRANSITION)) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java index a76af46b61..17e8395789 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java @@ -122,10 +122,9 @@ public abstract class IosTest implements RuleConfiguredTargetFactory { .addXcodeSettings(xcodeProviderBuilder, common, optionsProvider) .validateAttributes(); - ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); ReleaseBundlingSupport releaseBundlingSupport = new ReleaseBundlingSupport( ruleContext, common.getObjcProvider(), optionsProvider, LinkedBinary.LOCAL_AND_DEPENDENCIES, - ReleaseBundlingSupport.APP_BUNDLE_DIR_FORMAT, objcConfiguration.getMinimumOs()); + ReleaseBundlingSupport.APP_BUNDLE_DIR_FORMAT); releaseBundlingSupport .registerActions() .addXcodeSettings(xcodeProviderBuilder) diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java index 005eb67a36..7e4c48c15a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java @@ -82,17 +82,15 @@ public class ObjcBundleLibrary implements RuleConfiguredTargetFactory { RuleContext ruleContext, ObjcCommon common, OptionsProvider optionsProvider) { IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); - ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); return new Bundling.Builder() .setName(ruleContext.getLabel().getName()) - .setArchitecture(objcConfiguration.getIosCpu()) + .setArchitecture(ObjcRuleClasses.objcConfiguration(ruleContext).getIosCpu()) .setBundleDirFormat("%s.bundle") .setObjcProvider(common.getObjcProvider()) .setInfoplistMerging( BundleSupport.infoPlistMerging(ruleContext, common.getObjcProvider(), optionsProvider, new BundleSupport.ExtraMergePlists())) .setIntermediateArtifacts(intermediateArtifacts) - .setMinimumOsVersion(objcConfiguration.getMinimumOs()) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java index 9d9d1735bb..b835e7a416 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java @@ -21,10 +21,8 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration.LabelCon import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.FragmentOptions; import com.google.devtools.build.lib.packages.Attribute.SplitTransition; -import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.SplitArchTransition.ConfigurationDistinguisher; import com.google.devtools.build.lib.syntax.Label; import com.google.devtools.common.options.Converters.CommaSeparatedOptionListConverter; -import com.google.devtools.common.options.EnumConverter; import com.google.devtools.common.options.Option; import java.util.List; @@ -129,19 +127,6 @@ public class ObjcCommandLineOptions extends FragmentOptions { help = "Whether to add include path entries for every individual proto file.") public boolean perProtoIncludes; - // This option exists because two configurations are not allowed to have the same cache key - // (partially derived from options). Since we have multiple transitions (see - // getPotentialSplitTransitions below) that may result in the same configuration values at runtime - // we need an artificial way to distinguish between them. This option must only be set by those - // transitions for this purpose. - // TODO(bazel-team): Remove this once we have dynamic configurations but make sure that different - // configurations (e.g. by min os version) always use different output paths. - @Option(name = "DO_NOT_USE_configuration_distinguisher", - defaultValue = "UNKNOWN", - converter = ConfigurationDistinguisherConverter.class, - category = "undocumented") - public ConfigurationDistinguisher configurationDistinguisher; - @VisibleForTesting static final String DEFAULT_MINIMUM_IOS = "7.0"; @VisibleForTesting static final String DEFAULT_IOS_CPU = "i386"; @@ -167,14 +152,6 @@ public class ObjcCommandLineOptions extends FragmentOptions { @Override public List<SplitTransition<BuildOptions>> getPotentialSplitTransitions() { - return ImmutableList.of( - IosApplication.SPLIT_ARCH_TRANSITION, IosExtension.MINIMUM_OS_AND_SPLIT_ARCH_TRANSITION); - } - - public static final class ConfigurationDistinguisherConverter - extends EnumConverter<ConfigurationDistinguisher> { - public ConfigurationDistinguisherConverter() { - super(ConfigurationDistinguisher.class, "configuration distinguisher"); - } + return ImmutableList.of(ReleaseBundlingSupport.SPLIT_ARCH_TRANSITION); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java index 870292cb8c..6d4310d5cd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java @@ -15,7 +15,6 @@ package com.google.devtools.build.lib.rules.objc; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; @@ -23,12 +22,9 @@ import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.CompilationMode; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.EventHandler; -import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.SplitArchTransition.ConfigurationDistinguisher; import com.google.devtools.build.lib.syntax.Label; -import java.util.ArrayList; import java.util.List; -import java.util.Locale; import javax.annotation.Nullable; @@ -62,7 +58,6 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { private final List<String> iosMultiCpus; private final String iosSplitCpu; private final boolean perProtoIncludes; - private final ConfigurationDistinguisher configurationDistinguisher; // We only load these labels if the mode which uses them is enabled. That is know as part of the // BuildConfiguration. This label needs to be part of a configuration because only configurations @@ -93,7 +88,6 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { this.iosMultiCpus = Preconditions.checkNotNull(objcOptions.iosMultiCpus, "iosMultiCpus"); this.iosSplitCpu = Preconditions.checkNotNull(objcOptions.iosSplitCpu, "iosSplitCpu"); this.perProtoIncludes = objcOptions.perProtoIncludes; - this.configurationDistinguisher = objcOptions.configurationDistinguisher; } public String getIosSdkVersion() { @@ -249,18 +243,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { @Nullable @Override public String getOutputDirectoryName() { - List<String> components = new ArrayList<>(); - if (!iosSplitCpu.isEmpty()) { - components.add("ios-" + iosSplitCpu); - } - if (configurationDistinguisher != ConfigurationDistinguisher.UNKNOWN) { - components.add(configurationDistinguisher.toString().toLowerCase(Locale.US)); - } - - if (components.isEmpty()) { - return null; - } - return Joiner.on('-').join(components); + return !iosSplitCpu.isEmpty() ? "ios-" + iosSplitCpu : null; } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java index 63587e5325..90483b4095 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java @@ -180,7 +180,7 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory { .setLabel(ruleContext.getLabel()) .setArchitecture(configuration.getIosCpu()) .addUserHeaderSearchPaths(searchPathEntries) - .addPropagatedDependencies(protoDeps) + .addPropagatedDependencies(protoDeps, configuration) .addCopts(configuration.getCopts()) .setProductType(LIBRARY_STATIC) .addHeaders(protoGeneratedHeaders) diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java index 762bd84d3c..56f65d3bed 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java @@ -70,6 +70,36 @@ public final class ReleaseBundlingSupport { */ public static final SafeImplicitOutputsFunction IPA = fromTemplates("%{name}.ipa"); + /** + * Transition that when applied to a target generates a configured target for each value in + * {@code --ios_multi_cpus}, such that {@code --ios_cpu} is set to a different one of those values + * in the configured targets. + */ + public static final SplitTransition<BuildOptions> SPLIT_ARCH_TRANSITION = + new SplitTransition<BuildOptions>() { + @Override + public List<BuildOptions> split(BuildOptions buildOptions) { + List<String> iosMultiCpus = buildOptions.get(ObjcCommandLineOptions.class).iosMultiCpus; + if (iosMultiCpus.isEmpty()) { + return ImmutableList.of(); + } + + ImmutableList.Builder<BuildOptions> splitBuildOptions = ImmutableList.builder(); + for (String iosCpu : iosMultiCpus) { + BuildOptions splitOptions = buildOptions.clone(); + splitOptions.get(ObjcCommandLineOptions.class).iosSplitCpu = iosCpu; + splitOptions.get(ObjcCommandLineOptions.class).iosCpu = iosCpu; + splitBuildOptions.add(splitOptions); + } + return splitBuildOptions.build(); + } + + @Override + public boolean defaultsToSelf() { + return true; + } + }; + @VisibleForTesting static final String NO_ASSET_CATALOG_ERROR_FORMAT = "a value was specified (%s), but this app does not have any asset catalogs"; @@ -124,22 +154,18 @@ public final class ReleaseBundlingSupport { * @param linkedBinary whether to look for a linked binary from this rule and dependencies or just * the latter * @param bundleDirFormat format string representing the bundle's directory with a single - * placeholder for the target name (e.g. {@code "Payload/%s.app"}) - * @param bundleMinimumOsVersion the minimum OS version this bundle's plist should be generated - * for (<b>not</b> the minimum OS version its binary is compiled with, that needs to be set - * through the configuration) + * placeholder for the target name (e.g. {@code "Payload/%s.app"}) */ ReleaseBundlingSupport( RuleContext ruleContext, ObjcProvider objcProvider, OptionsProvider optionsProvider, - LinkedBinary linkedBinary, String bundleDirFormat, String bundleMinimumOsVersion) { + LinkedBinary linkedBinary, String bundleDirFormat) { this.linkedBinary = linkedBinary; this.attributes = new Attributes(ruleContext); this.ruleContext = ruleContext; this.objcProvider = objcProvider; this.families = ImmutableSet.copyOf(attributes.families()); this.intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); - bundling = bundling( - ruleContext, objcProvider, optionsProvider, bundleDirFormat, bundleMinimumOsVersion); + bundling = bundling(ruleContext, objcProvider, optionsProvider, bundleDirFormat); bundleSupport = new BundleSupport(ruleContext, families, bundling, extraActoolArgs()); } @@ -388,7 +414,7 @@ public final class ReleaseBundlingSupport { private Bundling bundling( RuleContext ruleContext, ObjcProvider objcProvider, OptionsProvider optionsProvider, - String bundleDirFormat, String minimumOsVersion) { + String bundleDirFormat) { ImmutableList<BundleableFile> extraBundleFiles; ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); if (objcConfiguration.getBundlingPlatform() == Platform.DEVICE) { @@ -421,7 +447,6 @@ public final class ReleaseBundlingSupport { .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext)) .setPrimaryBundleId(primaryBundleId) .setFallbackBundleId(fallbackBundleId) - .setMinimumOsVersion(minimumOsVersion) .build(); } @@ -727,74 +752,4 @@ public final class ReleaseBundlingSupport { return value.isEmpty() ? null : value; } } - - /** - * Transition that results in one configured target per architecture set in {@code - * --ios_multi_cpus}. - */ - protected static class SplitArchTransition implements SplitTransition<BuildOptions> { - - @Override - public final List<BuildOptions> split(BuildOptions buildOptions) { - List<String> iosMultiCpus = buildOptions.get(ObjcCommandLineOptions.class).iosMultiCpus; - if (iosMultiCpus.isEmpty()) { - return defaultOptions(buildOptions); - } - - ImmutableList.Builder<BuildOptions> splitBuildOptions = ImmutableList.builder(); - for (String iosCpu : iosMultiCpus) { - BuildOptions splitOptions = buildOptions.clone(); - setArchitectureOptions(splitOptions, iosCpu); - setAdditionalOptions(splitOptions, buildOptions); - splitOptions.get(ObjcCommandLineOptions.class).configurationDistinguisher = - getConfigurationDistinguisher(); - splitBuildOptions.add(splitOptions); - } - return splitBuildOptions.build(); - } - - /** - * Returns the default options to use if no split architectures are specified. - * - * @param originalOptions original options before this transition - */ - protected ImmutableList<BuildOptions> defaultOptions(BuildOptions originalOptions) { - return ImmutableList.of(); - } - - /** - * Sets or overwrites flags on the given split options. - * - * <p>Invoked once for each configuration produced by this transition. - * - * @param splitOptions options to use after this transition - * @param originalOptions original options before this transition - */ - protected void setAdditionalOptions(BuildOptions splitOptions, BuildOptions originalOptions) {} - - private void setArchitectureOptions(BuildOptions splitOptions, String iosCpu) { - splitOptions.get(ObjcCommandLineOptions.class).iosSplitCpu = iosCpu; - splitOptions.get(ObjcCommandLineOptions.class).iosCpu = iosCpu; - } - - @Override - public boolean defaultsToSelf() { - return true; - } - - /** - * Returns the configuration distinguisher for this transition instance. - */ - protected ConfigurationDistinguisher getConfigurationDistinguisher() { - return ConfigurationDistinguisher.APPLICATION; - } - - /** - * Value used to avoid multiple configurations from conflicting. No two instances of this - * transition may exist with the same value in a single Bazel invocation. - */ - enum ConfigurationDistinguisher { - EXTENSION, APPLICATION, UNKNOWN - } - } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java index 8157bd73ca..af98af5dce 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java @@ -67,7 +67,7 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg ReleaseBundlingSupport releaseBundlingSupport = new ReleaseBundlingSupport( ruleContext, common.getObjcProvider(), optionsProvider(ruleContext), - LinkedBinary.DEPENDENCIES_ONLY, bundleDirFormat, bundleMinimumOsVersion(ruleContext)); + LinkedBinary.DEPENDENCIES_ONLY, bundleDirFormat); releaseBundlingSupport .registerActions() .addXcodeSettings(xcodeProviderBuilder) @@ -77,8 +77,7 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg XcodeSupport xcodeSupport = new XcodeSupport(ruleContext) .addFilesToBuild(filesToBuild) - .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), xcodeProductType, - ObjcRuleClasses.objcConfiguration(ruleContext).getDependencySingleArchitecture()) + .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), xcodeProductType) .addDummySource(xcodeProviderBuilder); for (Attribute attribute : dependencyAttributes) { @@ -107,15 +106,6 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg } /** - * Returns the minimum OS version this bundle's plist and resources should be generated for - * (<b>not</b> the minimum OS version its binary is compiled with, that needs to be set in the - * configuration). - */ - protected String bundleMinimumOsVersion(RuleContext ruleContext) { - return ObjcRuleClasses.objcConfiguration(ruleContext).getMinimumOs(); - } - - /** * Returns a provider based on this rule's options and those of its option-providing dependencies. */ protected abstract OptionsProvider optionsProvider(RuleContext ruleContext); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodel.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodel.java index a7ac20cb59..ff8601cb96 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodel.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/Xcdatamodel.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.vfs.PathFragment; /** @@ -117,4 +118,16 @@ class Xcdatamodel extends Value<Xcdatamodel> { } }); } + + /** + * Returns a sequence of all unique *.xcdatamodel directories that contain all the artifacts of + * the given models. Note that this does not return any *.xcdatamodeld directories. + */ + static Iterable<PathFragment> xcdatamodelDirs(Iterable<Xcdatamodel> models) { + ImmutableSet.Builder<PathFragment> result = new ImmutableSet.Builder<>(); + for (Xcdatamodel model : models) { + result.addAll(ObjcCommon.uniqueContainers(model.getInputs(), FileType.of(".xcdatamodel"))); + } + return result.build(); + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java index ab6b4f7384..a7cbd61883 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java @@ -49,10 +49,8 @@ import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.XcodeprojBu import java.util.Arrays; import java.util.EnumSet; -import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.Set; /** @@ -149,19 +147,23 @@ public final class XcodeProvider implements TransitiveInfoProvider { * Adds {@link XcodeProvider}s corresponding to direct dependencies of this target which should * be added in the {@code .xcodeproj} file and propagated up the dependency chain. */ - public Builder addPropagatedDependencies(Iterable<XcodeProvider> dependencies) { - return addDependencies(dependencies, /*doPropagate=*/true); + public Builder addPropagatedDependencies(Iterable<XcodeProvider> dependencies, + ObjcConfiguration configuration) { + return addDependencies(dependencies, configuration, /*doPropagate=*/true); } /** * Adds {@link XcodeProvider}s corresponding to direct dependencies of this target which should * be added in the {@code .xcodeproj} file and not propagated up the dependency chain. */ - public Builder addNonPropagatedDependencies(Iterable<XcodeProvider> dependencies) { - return addDependencies(dependencies, /*doPropagate=*/false); + public Builder addNonPropagatedDependencies(Iterable<XcodeProvider> dependencies, + ObjcConfiguration configuration) { + return addDependencies(dependencies, configuration, /*doPropagate=*/false); } - private Builder addDependencies(Iterable<XcodeProvider> dependencies, boolean doPropagate) { + private Builder addDependencies(Iterable<XcodeProvider> dependencies, + ObjcConfiguration configuration, boolean doPropagate) { + String architecture = configuration.getDependencySingleArchitecture(); for (XcodeProvider dependency : dependencies) { // TODO(bazel-team): This is messy. Maybe we should make XcodeProvider be able to specify // how to depend on it rather than require this method to choose based on the dependency's @@ -169,7 +171,7 @@ public final class XcodeProvider implements TransitiveInfoProvider { if (dependency.productType == XcodeProductType.EXTENSION) { this.extensions.add(dependency); this.inputsToXcodegen.addTransitive(dependency.inputsToXcodegen); - } else { + } else if (dependency.architecture.equals(architecture)) { if (doPropagate) { this.propagatedDependencies.add(dependency); this.propagatedDependencies.addTransitive(dependency.propagatedDependencies); @@ -352,21 +354,7 @@ public final class XcodeProvider implements TransitiveInfoProvider { } ImmutableList.Builder<TargetControl> controls = new ImmutableList.Builder<>(); - Map<Label, XcodeProvider> labelToProvider = new HashMap<>(); for (XcodeProvider provider : providerSet) { - XcodeProvider oldProvider = labelToProvider.put(provider.label, provider); - if (oldProvider != null) { - if (!oldProvider.architecture.equals(provider.architecture)) { - // Do not include duplicate dependencies whose architecture does not match this - // project's. This check avoids having multiple conflicting Xcode targets for the same - // BUILD target that are only distinguished by this field (which Xcode does not care - // about). - continue; - } - - throw new IllegalStateException("Depending on multiple versions of the same xcode target " - + "is not allowed but occurred for: " + provider.label); - } controls.addAll(provider.targetControls()); } return controls.build(); 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 366cf99448..e2d057d990 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 @@ -93,27 +93,9 @@ public final class XcodeSupport { */ XcodeSupport addXcodeSettings(XcodeProvider.Builder xcodeProviderBuilder, ObjcProvider objcProvider, XcodeProductType productType) { - return addXcodeSettings(xcodeProviderBuilder, objcProvider, productType, - ObjcRuleClasses.objcConfiguration(ruleContext).getIosCpu()); - } - - /** - * Adds common xcode settings to the given provider builder, explicitly specifying architecture - * to use. - * - * @param objcProvider provider containing all dependencies' information as well as some of this - * rule's - * @param productType type of this rule's Xcode target - * @param architecture architecture to filter all dependencies with (only matching ones will be - * included in the final targets generated) - * - * @return this xcode support - */ - XcodeSupport addXcodeSettings(Builder xcodeProviderBuilder, - ObjcProvider objcProvider, XcodeProductType productType, String architecture) { xcodeProviderBuilder .setLabel(ruleContext.getLabel()) - .setArchitecture(architecture) + .setArchitecture(ObjcRuleClasses.objcConfiguration(ruleContext).getIosCpu()) .setObjcProvider(objcProvider) .setProductType(productType); return this; @@ -127,7 +109,8 @@ public final class XcodeSupport { XcodeSupport addDependencies(Builder xcodeProviderBuilder, Attribute attribute) { xcodeProviderBuilder.addPropagatedDependencies( ruleContext.getPrerequisites( - attribute.getName(), attribute.getAccessMode(), XcodeProvider.class)); + attribute.getName(), attribute.getAccessMode(), XcodeProvider.class), + ObjcRuleClasses.objcConfiguration(ruleContext)); return this; } @@ -142,7 +125,8 @@ public final class XcodeSupport { XcodeSupport addNonPropagatedDependencies(Builder xcodeProviderBuilder, Attribute attribute) { xcodeProviderBuilder.addNonPropagatedDependencies( ruleContext.getPrerequisites( - attribute.getName(), attribute.getAccessMode(), XcodeProvider.class)); + attribute.getName(), attribute.getAccessMode(), XcodeProvider.class), + ObjcRuleClasses.objcConfiguration(ruleContext)); return this; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XibFiles.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XibFiles.java new file mode 100644 index 0000000000..9be1d06a01 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XibFiles.java @@ -0,0 +1,42 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.rules.objc; + + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.actions.Artifact; + +/** + * A sequence of xib source files. Each {@code .xib} file can be compiled to a {@code .nib} file or + * directory. Because it might be a directory, we always use zip files to store the output and use + * the {@code actooloribtoolzip} utility to run ibtool and zip the output. + */ +public final class XibFiles extends IterableWrapper<Artifact> { + public XibFiles(Iterable<Artifact> artifacts) { + super(artifacts); + } + + /** + * Returns a sequence where each element of this sequence is converted to the file which contains + * the compiled contents of the xib. + */ + public ImmutableList<Artifact> compiledZips(IntermediateArtifacts intermediateArtifacts) { + ImmutableList.Builder<Artifact> zips = new ImmutableList.Builder<>(); + for (Artifact xib : this) { + zips.add(intermediateArtifacts.compiledXibFileZip(xib)); + } + return zips.build(); + } +} |