diff options
author | Sergio Campama <kaipi@google.com> | 2017-01-23 15:40:55 +0000 |
---|---|---|
committer | John Cater <jcater@google.com> | 2017-01-23 19:39:21 +0000 |
commit | 65df9012577e6f8749b2e448e340d5198af68a17 (patch) | |
tree | d92a2819593ce23b0222a58e5df0af7c28e66a43 /src/main/java | |
parent | 3fc4410e5dbcaedaac1a2e1a61db9226fdd7d228 (diff) |
Renames the BundleLoaderProvider to AppleExecutableBinaryProvider, and uses that provider to retrieve the executable binary to act as the bundle_loader.
Also passes the bundle loader's ObjcProvider and ObjcProtoProviders to the dylib deduping mechanism to avoid dual linking of symbols into the tests.
--
PiperOrigin-RevId: 145284598
MOS_MIGRATED_REVID=145284598
Diffstat (limited to 'src/main/java')
7 files changed, 134 insertions, 136 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java index 87dc0d5504..31a7e39fd8 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java @@ -619,7 +619,7 @@ public class BazelRuleClassProvider { builder.addNativeAspectClass(objcProtoAspect); builder.addRuleDefinition(new ObjcProtoLibraryRule(objcProtoAspect)); - builder.addRuleDefinition(new AppleBinaryRule()); + builder.addRuleDefinition(new AppleBinaryRule(objcProtoAspect)); builder.addRuleDefinition(new AppleCcToolchainRule()); builder.addRuleDefinition(new AppleDynamicLibraryRule()); builder.addRuleDefinition(new AppleStaticLibraryRule()); 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 0f46226770..298b31493d 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,16 +14,16 @@ package com.google.devtools.build.lib.rules.objc; -import static com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode.TARGET; +import static com.google.devtools.build.lib.rules.objc.AppleBinaryRule.BUNDLE_LOADER_ATTR_NAME; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MULTI_ARCH_LINKED_BINARIES; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.DylibDependingRule.DYLIBS_ATTR_NAME; import static com.google.devtools.build.lib.syntax.Type.STRING; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Functions; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableListMultimap; +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.analysis.ConfiguredTarget; @@ -42,24 +42,20 @@ import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs import java.util.Map; import java.util.Set; -/** - * Implementation for the "apple_binary" rule. - */ +/** Implementation for the "apple_binary" rule. */ public class AppleBinary implements RuleConfiguredTargetFactory { - /** - * Type of linked binary that apple_binary may create. - */ + /** Type of linked binary that apple_binary may create. */ enum BinaryType { /** - * Binaries that can be loaded by other binaries at runtime, and which can't be - * directly executed by the operating system. When linking, a bundle_loader binary may be passed - * which signals the linker on where to look for unimplemented symbols, basically declaring that - * the bundle should be loaded by that binary. Bundle binaries are usually found in Plugins, and - * one common use case is tests. Tests are bundled into an .xctest bundle which contains the - * test binary along with required resources. The test bundle is then loaded and run during - * test execution. + * Binaries that can be loaded by other binaries at runtime, and which can't be directly + * executed by the operating system. When linking, a bundle_loader binary may be passed which + * signals the linker on where to look for unimplemented symbols, basically declaring that the + * bundle should be loaded by that binary. Bundle binaries are usually found in Plugins, and one + * common use case is tests. Tests are bundled into an .xctest bundle which contains the test + * binary along with required resources. The test bundle is then loaded and run during test + * execution. */ LOADABLE_BUNDLE, @@ -73,9 +69,8 @@ public class AppleBinary implements RuleConfiguredTargetFactory { /** * Binaries meant to be loaded at load time (when the operating system is loading the binary - * into memory), which cannot be unloaded. They are usually distributed in frameworks, - * which are .framework bundles that contain the dylib as well as well as required resources to - * run. + * into memory), which cannot be unloaded. They are usually distributed in frameworks, which are + * .framework bundles that contain the dylib as well as well as required resources to run. */ DYLIB; @@ -116,22 +111,10 @@ public class AppleBinary implements RuleConfiguredTargetFactory { Platform platform = appleConfiguration.getMultiArchPlatform(platformType); ImmutableListMultimap<BuildConfiguration, ObjcProvider> configurationToNonPropagatedObjcMap = - ruleContext.getPrerequisitesByConfiguration("non_propagated_deps", Mode.SPLIT, - ObjcProvider.class); + ruleContext.getPrerequisitesByConfiguration( + "non_propagated_deps", Mode.SPLIT, ObjcProvider.class); ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap = ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT); - Iterable<ObjcProvider> dylibProviders = - ruleContext.getPrerequisites(DYLIBS_ATTR_NAME, Mode.TARGET, ObjcProvider.class); - Iterable<ObjcProtoProvider> dylibProtoProviders = - ruleContext.getPrerequisites(DYLIBS_ATTR_NAME, Mode.TARGET, ObjcProtoProvider.class); - - BundleLoaderProvider bundleLoaderProvider = - ruleContext.getPrerequisite( - AppleBinaryRule.BUNDLE_LOADER_ATTR, Mode.TARGET, BundleLoaderProvider.class); - Optional<ObjcProvider> bundleLoaderObjcProvider = Optional.absent(); - if (bundleLoaderProvider != null) { - bundleLoaderObjcProvider = Optional.of(bundleLoaderProvider.toObjcProvider()); - } Set<BuildConfiguration> childConfigurations = getChildConfigurations(ruleContext); Artifact outputArtifact = @@ -144,9 +127,8 @@ public class AppleBinary implements RuleConfiguredTargetFactory { childConfigurations, configToDepsCollectionMap, configurationToNonPropagatedObjcMap, - dylibProviders, - dylibProtoProviders, - bundleLoaderObjcProvider); + getDylibProviders(ruleContext), + getDylibProtoProviders(ruleContext)); multiArchBinarySupport.registerActions( platform, @@ -171,7 +153,8 @@ public class AppleBinary implements RuleConfiguredTargetFactory { targetBuilder.addProvider(ObjcProvider.class, objcProvider); if (getBinaryType(ruleContext) == BinaryType.EXECUTABLE) { - targetBuilder.addProvider(BundleLoaderProvider.class, new BundleLoaderProvider(objcProvider)); + targetBuilder.addProvider( + AppleExecutableBinaryProvider.class, new AppleExecutableBinaryProvider(outputArtifact)); } return targetBuilder.build(); } @@ -182,21 +165,22 @@ public class AppleBinary implements RuleConfiguredTargetFactory { ImmutableList.Builder<String> extraLinkArgs = new ImmutableList.Builder<>(); boolean didProvideBundleLoader = - ruleContext - .attributes() - .isAttributeValueExplicitlySpecified(AppleBinaryRule.BUNDLE_LOADER_ATTR); + ruleContext.attributes().isAttributeValueExplicitlySpecified(BUNDLE_LOADER_ATTR_NAME); if (didProvideBundleLoader && binaryType != BinaryType.LOADABLE_BUNDLE) { ruleContext.throwWithRuleError(BUNDLE_LOADER_NOT_IN_BUNDLE_ERROR); } - switch(binaryType) { + switch (binaryType) { case LOADABLE_BUNDLE: extraLinkArgs.add("-bundle"); if (didProvideBundleLoader) { - Artifact bundleLoader = - ruleContext.getPrerequisiteArtifact(AppleBinaryRule.BUNDLE_LOADER_ATTR, TARGET); - extraLinkArgs.add("-bundle_loader " + bundleLoader.getExecPathString()); + AppleExecutableBinaryProvider executableProvider = + ruleContext.getPrerequisite( + BUNDLE_LOADER_ATTR_NAME, Mode.TARGET, AppleExecutableBinaryProvider.class); + extraLinkArgs.add( + "-bundle_loader " + + executableProvider.getAppleExecutableBinary().getExecPathString()); } break; case DYLIB: @@ -209,10 +193,41 @@ public class AppleBinary implements RuleConfiguredTargetFactory { return new ExtraLinkArgs(extraLinkArgs.build()); } + private static Iterable<ObjcProvider> getDylibProviders(RuleContext ruleContext) { + Iterable<ObjcProvider> dylibProviders = + ruleContext.getPrerequisites(DYLIBS_ATTR_NAME, Mode.TARGET, ObjcProvider.class); + + ObjcProvider bundleLoaderObjcProvider = + ruleContext.getPrerequisite(BUNDLE_LOADER_ATTR_NAME, Mode.TARGET, ObjcProvider.class); + + if (bundleLoaderObjcProvider != null) { + dylibProviders = Iterables.concat(dylibProviders, ImmutableList.of(bundleLoaderObjcProvider)); + } + return dylibProviders; + } + + private static Iterable<ObjcProtoProvider> getDylibProtoProviders(RuleContext ruleContext) { + Iterable<ObjcProtoProvider> dylibProtoProviders = + ruleContext.getPrerequisites(DYLIBS_ATTR_NAME, Mode.TARGET, ObjcProtoProvider.class); + + ObjcProtoProvider bundleLoaderObjcProtoProvider = + ruleContext.getPrerequisite(BUNDLE_LOADER_ATTR_NAME, Mode.TARGET, ObjcProtoProvider.class); + + if (bundleLoaderObjcProtoProvider != null) { + dylibProtoProviders = + Iterables.concat(dylibProtoProviders, ImmutableList.of(bundleLoaderObjcProtoProvider)); + } + return dylibProtoProviders; + } + private static Iterable<Artifact> getExtraLinkInputs(RuleContext ruleContext) { - return Optional.fromNullable( - ruleContext.getPrerequisiteArtifact(AppleBinaryRule.BUNDLE_LOADER_ATTR, TARGET)) - .asSet(); + AppleExecutableBinaryProvider executableProvider = + ruleContext.getPrerequisite( + BUNDLE_LOADER_ATTR_NAME, Mode.TARGET, AppleExecutableBinaryProvider.class); + if (executableProvider != null) { + return ImmutableSet.<Artifact>of(executableProvider.getAppleExecutableBinary()); + } + return ImmutableSet.<Artifact>of(); } private Set<BuildConfiguration> getChildConfigurations(RuleContext ruleContext) { @@ -220,8 +235,8 @@ public class AppleBinary implements RuleConfiguredTargetFactory { // values of this rule -- this rule does not currently use the actual info provided by // this attribute. b/28403953 tracks cc toolchain usage. ImmutableListMultimap<BuildConfiguration, CcToolchainProvider> configToProvider = - ruleContext.getPrerequisitesByConfiguration(":cc_toolchain", Mode.SPLIT, - CcToolchainProvider.class); + ruleContext.getPrerequisitesByConfiguration( + ":cc_toolchain", Mode.SPLIT, CcToolchainProvider.class); return configToProvider.keySet(); } 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 f814bef168..41f9617dd8 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 @@ -38,7 +38,16 @@ import com.google.devtools.build.lib.rules.apple.AppleConfiguration; public class AppleBinaryRule implements RuleDefinition { public static final String BINARY_TYPE_ATTR = "binary_type"; - public static final String BUNDLE_LOADER_ATTR = "bundle_loader"; + public static final String BUNDLE_LOADER_ATTR_NAME = "bundle_loader"; + + private final ObjcProtoAspect objcProtoAspect; + + /** + * Constructor that returns a newly configured AppleBinaryRule object. + */ + public AppleBinaryRule(ObjcProtoAspect objcProtoAspect) { + this.objcProtoAspect = objcProtoAspect; + } /** * Template for the fat binary output (using Apple's "lipo" tool to combine binaries of @@ -107,18 +116,15 @@ public class AppleBinaryRule implements RuleDefinition { attr(BINARY_TYPE_ATTR, STRING) .value(AppleBinary.BinaryType.EXECUTABLE.toString()) .allowedValues(new AllowedValueSet(AppleBinary.BinaryType.getValues()))) - /* <!-- #BLAZE_RULE(apple_binary).ATTRIBUTE(bundle_loader) --> - The bundle loader to be used when linking this bundle. Can only be set when binary_type is - "bundle". This bundle loader may contain symbols that were not linked into the bundle to - reduce binary size. - <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ .add( - attr(BUNDLE_LOADER_ATTR, LABEL) + attr(BUNDLE_LOADER_ATTR_NAME, LABEL) + .direct_compile_time_input() .mandatoryNativeProviders( ImmutableList.<Class<? extends TransitiveInfoProvider>>of( - BundleLoaderProvider.class)) - .legacyAllowAnyFileType() - .singleArtifact()) + AppleExecutableBinaryProvider.class)) + .allowedFileTypes() + .singleArtifact() + .aspect(objcProtoAspect)) .override(builder.copy("deps").cfg(splitTransitionProvider)) .override(builder.copy("non_propagated_deps").cfg(splitTransitionProvider)) /*<!-- #BLAZE_RULE(apple_binary).IMPLICIT_OUTPUTS --> diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDynamicLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDynamicLibrary.java index 50f7d10e6d..9704fa9831 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDynamicLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDynamicLibrary.java @@ -17,7 +17,6 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MULTI_ARCH_DYNAMIC_LIBRARIES; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.DylibDependingRule.DYLIBS_ATTR_NAME; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.Artifact; @@ -71,8 +70,7 @@ public class AppleDynamicLibrary implements RuleConfiguredTargetFactory { configToDepsCollectionMap, configurationToNonPropagatedObjcMap, dylibProviders, - dylibProtoProviders, - Optional.<ObjcProvider>absent()); + dylibProtoProviders); multiArchBinarySupport.registerActions( platform, diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleExecutableBinaryProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleExecutableBinaryProvider.java new file mode 100644 index 0000000000..ddbdaf3cb0 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleExecutableBinaryProvider.java @@ -0,0 +1,51 @@ +// Copyright 2016 The Bazel Authors. 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.ImmutableMap; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; +import com.google.devtools.build.lib.packages.SkylarkClassObject; +import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor; + +/** + * Provider containing the executable binary output that was built using an apple_binary target with + * the 'executable' type. + */ +public final class AppleExecutableBinaryProvider extends SkylarkClassObject + implements TransitiveInfoProvider { + + /** Skylark constructor and identifier for AppleExecutableBinaryProvider. */ + public static final SkylarkClassObjectConstructor SKYLARK_CONSTRUCTOR = + SkylarkClassObjectConstructor.createNative("AppleExecutableBinary"); + + private final Artifact appleExecutableBinary; + + /** + * Creates a new AppleExecutableBinaryProvider provider that propagates the given apple_binary + * configured as an executable. + */ + public AppleExecutableBinaryProvider(Artifact appleExecutableBinary) { + super(SKYLARK_CONSTRUCTOR, ImmutableMap.<String, Object>of("binary", appleExecutableBinary)); + this.appleExecutableBinary = appleExecutableBinary; + } + + /** + * Returns the multi-architecture executable binary that apple_binary created. + */ + public Artifact getAppleExecutableBinary() { + return appleExecutableBinary; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleLoaderProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleLoaderProvider.java deleted file mode 100644 index c6985f64ee..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleLoaderProvider.java +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2016 The Bazel Authors. 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.ImmutableSet; -import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; - -/** - * Provider containing a subset of ObjcProvider's fields to be propagated to apple_binary targets of - * the BUNDLE type. This enables compilation and linking against symbols contained in the bundle - * loader binary without having to redeclare dependencies already part of the bundle loader's - * dependency graph. This provider explicitly filters out anything that may affect the symbols being - * linked into the dependents (SDK_DYLIB, SDK_FRAMEWORK, LINKOPT, LIBRARY and FORCE_LOAD_LIBRARY). - */ -public final class BundleLoaderProvider implements TransitiveInfoProvider { - - /** List of keys that BundleLoaderProvider should propagate to bundle binaries. */ - static final ImmutableSet<ObjcProvider.Key<?>> KEPT_KEYS = - ImmutableSet.<ObjcProvider.Key<?>>of( - ObjcProvider.HEADER, - ObjcProvider.INCLUDE, - ObjcProvider.DEFINE, - ObjcProvider.DYNAMIC_FRAMEWORK_FILE, - ObjcProvider.STATIC_FRAMEWORK_FILE, - ObjcProvider.FRAMEWORK_SEARCH_PATH_ONLY); - - private final ObjcProvider objcProvider; - - /** Creates a new BundleLoader provider that propagates a subset of ObjcProvider's fields, */ - public BundleLoaderProvider(ObjcProvider objcProvider) { - this.objcProvider = objcProvider; - } - - /** Returns an ObjcProvider representation of this provider to be used as a dependency. */ - public ObjcProvider toObjcProvider() { - ObjcProvider.Builder objcProviderBuilder = new ObjcProvider.Builder(); - for (ObjcProvider.Key<?> key : KEPT_KEYS) { - addTransitiveAndPropagate(objcProviderBuilder, key); - } - - return objcProviderBuilder - // Notice that DYNAMIC_FRAMEWORK_DIR and STATIC_FRAMEWORK_DIR are being rerouted into - // FRAMEWORK_SEARCH_PATH_ONLY, to avoid linking them into the BUNDLE binary, but making - // their headers search paths available for compilation. - .addTransitiveAndPropagate( - ObjcProvider.FRAMEWORK_SEARCH_PATH_ONLY, - objcProvider.get(ObjcProvider.DYNAMIC_FRAMEWORK_DIR)) - .addTransitiveAndPropagate( - ObjcProvider.FRAMEWORK_SEARCH_PATH_ONLY, - objcProvider.get(ObjcProvider.STATIC_FRAMEWORK_DIR)) - .build(); - } - - private <T> void addTransitiveAndPropagate( - ObjcProvider.Builder objcProviderBuilder, ObjcProvider.Key<T> key) { - objcProviderBuilder.addTransitiveAndPropagate(key, objcProvider.get(key)); - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java index 4e9caee9c9..5b69801390 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java @@ -146,8 +146,7 @@ public class MultiArchBinarySupport { ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap, ImmutableListMultimap<BuildConfiguration, ObjcProvider> configurationToNonPropagatedObjcMap, Iterable<ObjcProvider> dylibObjcProviders, - Iterable<ObjcProtoProvider> dylibProtoProviders, - Optional<ObjcProvider> bundleLoaderObjcProvider) + Iterable<ObjcProtoProvider> dylibProtoProviders) throws RuleErrorException, InterruptedException { ImmutableMap.Builder<BuildConfiguration, ObjcProvider> configurationToObjcProviderBuilder = ImmutableMap.builder(); @@ -172,8 +171,7 @@ public class MultiArchBinarySupport { Iterables.concat( dylibObjcProviders, ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class), - protosObjcProvider.asSet(), - bundleLoaderObjcProvider.asSet()); + protosObjcProvider.asSet()); ObjcCommon common = common( |