diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java index 540418253cd606..bf198547455fc5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java @@ -18,8 +18,11 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; +import com.google.common.base.Predicates; 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; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; @@ -27,13 +30,16 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; import com.google.devtools.build.lib.rules.apple.Platform.PlatformType; import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes; +import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -42,6 +48,32 @@ */ public class AppleStaticLibrary implements RuleConfiguredTargetFactory { + /** + * Set of {@link ObjcProvider} keys whose values are subtracted by avoid_deps. Specifically, a + * value is propagated if present in the transitive "deps" but *not* present in the transitive + * "avoid_deps". + */ + private static final ImmutableSet> AVOID_DEPS_KEYS = + ImmutableSet.>of( + ObjcProvider.ASSET_CATALOG, + ObjcProvider.BUNDLE_FILE, + ObjcProvider.GENERAL_RESOURCE_DIR, + ObjcProvider.GENERAL_RESOURCE_FILE, + ObjcProvider.STORYBOARD, + ObjcProvider.STRINGS, + ObjcProvider.XCDATAMODEL, + ObjcProvider.XIB, + ObjcProvider.XCASSETS_DIR); + + /** + * Set of {@link ObjcProvider} whose values are propagated regardless of avoid_deps. + */ + private static final ImmutableSet> PROPAGATE_REGARDLESS_KEYS = + ImmutableSet.>of( + ObjcProvider.SDK_DYLIB, + ObjcProvider.SDK_FRAMEWORK, + ObjcProvider.WEAK_SDK_FRAMEWORK); + @VisibleForTesting static final String UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT = "Unsupported platform type \"%s\""; @@ -98,7 +130,8 @@ public final ConfiguredTarget create(RuleContext ruleContext) .validateAttributes(); ruleContext.assertNoErrors(); - objcProviderBuilder.addTransitiveAndPropagate(common.getObjcProvider()); + addTransitiveAndAvoid(objcProviderBuilder, common.getObjcProvider(), + configToAvoidDepsMap.get(childConfig)); } AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class); @@ -118,6 +151,28 @@ public final ConfiguredTarget create(RuleContext ruleContext) targetBuilder.addProvider(ObjcProvider.class, objcProviderBuilder.build()); return targetBuilder.build(); } + + private void addTransitiveAndAvoid(ObjcProvider.Builder objcProviderBuilder, + ObjcProvider provider, ImmutableList avoidProviders) { + for (Key key : PROPAGATE_REGARDLESS_KEYS) { + objcProviderBuilder.addTransitiveAndPropagate(key, provider); + } + for (Key key : AVOID_DEPS_KEYS) { + addTransitiveAndAvoid(objcProviderBuilder, key, provider, avoidProviders); + } + } + + private void addTransitiveAndAvoid(ObjcProvider.Builder objcProviderBuilder, Key key, + ObjcProvider provider, ImmutableList avoidProviders) { + HashSet avoidItemsSet = new HashSet(); + for (ObjcProvider avoidProvider : avoidProviders) { + avoidItemsSet.addAll(avoidProvider.getPropagable(key).toList()); + } + NestedSet items = provider.getPropagable(key); + + objcProviderBuilder.addAll(key, + Iterables.filter(items.toList(), Predicates.not(Predicates.in(avoidItemsSet)))); + } private ObjcCommon common( RuleContext ruleContext, diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleableFile.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleableFile.java index bbd3effcbd7be1..8a4881abd8a697 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleableFile.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleableFile.java @@ -31,6 +31,7 @@ * files. */ public final class BundleableFile extends Value { + static final int EXECUTABLE_EXTERNAL_FILE_ATTRIBUTE = 0100755 << 16; static final int DEFAULT_EXTERNAL_FILE_ATTRIBUTE = 0100644 << 16; diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java index aa5a6e2f1ec2c0..df0d955a030550 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java @@ -471,6 +471,20 @@ public NestedSet get(Key key) { } return builder.build(); } + + /** + * All artifacts, bundleable files, etc, that should be propagated to transitive dependers, of + * the type specified by {@code key}. + */ + @SuppressWarnings("unchecked") + public NestedSet getPropagable(Key key) { + Preconditions.checkNotNull(key); + NestedSetBuilder builder = new NestedSetBuilder<>(key.order); + if (items.containsKey(key)) { + builder.addTransitive((NestedSet) items.get(key)); + } + return builder.build(); + } /** * Indicates whether {@code flag} is set on this provider. @@ -559,7 +573,7 @@ public Builder addTransitiveAndPropagate(ObjcProvider provider) { } return this; } - + /** * Add all keys and values from the given provider, but propagate any normally-propagated items * only to direct dependers of this ObjcProvider.