Move ObjcProvider FLAG into a new provider type (TransitiveSourcesProvider) that is accessible to the c++ rules. PiperOrigin-RevId: 166934390
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java index 7522d09..316f50e 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
@@ -230,6 +230,14 @@ return this; } + /** Adds a group of {@link TransitiveInfoProviderMap} instances. */ + public <T extends TransitiveInfoProvider> RuleConfiguredTargetBuilder addProviderMaps( + Iterable<TransitiveInfoProviderMap> providerMaps) { + for (TransitiveInfoProviderMap providerMap : providerMaps) { + addProviders(providerMap); + } + return this; + } /** * Add a specific provider with a given value.
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 3f28614..8cd4315 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
@@ -866,6 +866,17 @@ } /** + * Returns all the providers of the specified type that are listed under the specified attribute + * of this target in the BUILD file, or an empty list of that attribute is not defined. + */ + public <C extends TransitiveInfoProvider> Iterable<C> getPrerequisitesSafe( + String attributeName, Mode mode, final Class<C> classType) { + return attributes().has(attributeName) + ? getPrerequisites(attributeName, mode, classType) + : ImmutableList.of(); + } + + /** * Returns all the declared providers (native and Skylark) for the specified constructor under the * specified attribute of this target in the BUILD file. */
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java index 4856b0a..32c8cf9 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.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.common.collect.Lists; import com.google.common.collect.Maps; import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.Artifact; @@ -38,6 +39,7 @@ import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.rules.apple.ApplePlatform; import com.google.devtools.build.lib.rules.cpp.CcLibraryHelper.SourceCategory; @@ -46,6 +48,7 @@ import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables; import com.google.devtools.build.lib.rules.cpp.CppConfiguration.DynamicMode; import com.google.devtools.build.lib.rules.cpp.CppConfiguration.HeadersCheckingMode; +import com.google.devtools.build.lib.rules.cpp.TransitiveSourcesProvider.SourceUsage; import com.google.devtools.build.lib.shell.ShellUtils; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileType; @@ -57,6 +60,7 @@ import java.util.Map; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import java.util.stream.Collectors; import javax.annotation.Nullable; /** @@ -219,12 +223,22 @@ return new TransitiveLipoInfoProvider(scannableBuilder.build()); } + /** Returns true if the given rule has sources in the target configuration. */ + static boolean hasSourcesInTargetConfig(RuleContext ruleContext) { + return (ruleContext.attributes().has("srcs") + && ruleContext.attributes().getAttributeDefinition("srcs").getConfigurationTransition() + == ConfigurationTransition.NONE); + } + /** - * Returns a list of ({@link Artifact}, {@link Label}) pairs. Each pair represents an input - * source file and the label of the rule that generates it (or the label of the source file - * itself if it is an input file). + * Returns a list of ({@link Artifact}, {@link Label}) pairs. Each pair represents an input source + * file and the label of the rule that generates it (or the label of the source file itself if it + * is an input file). */ - List<Pair<Artifact, Label>> getSources() { + static List<Pair<Artifact, Label>> getSources(RuleContext ruleContext) { + if (!ruleContext.attributes().has("srcs")) { + return ImmutableList.of(); + } Map<Artifact, Label> map = Maps.newLinkedHashMap(); Iterable<? extends TransitiveInfoCollection> providers = ruleContext.getPrerequisitesIf("srcs", Mode.TARGET, FileProvider.class); @@ -255,6 +269,15 @@ } /** + * Returns a list of ({@link Artifact}, {@link Label}) pairs. Each pair represents an input source + * file and the label of the rule that generates it (or the label of the source file itself if it + * is an input file). + */ + List<Pair<Artifact, Label>> getSources() { + return getSources(ruleContext); + } + + /** * Returns the files from headers and does some sanity checks. Note that this method reports * warnings to the {@link RuleContext} as a side effect, and so should only be called once for any * given rule. @@ -568,6 +591,40 @@ } } + /** Computes the {@link TransitiveSourcesProvider} for this target using the given target. */ + public static TransitiveSourcesProvider getTransitiveSourcesProvider(RuleContext ruleContext) { + List<String> sources = + getSources(ruleContext) + .stream() + .map(pair -> pair.getSecond().getCanonicalForm()) + .collect(Collectors.toList()); + return getTransitiveSourcesProvider(ruleContext, sources); + } + + /** Computes the {@link TransitiveSourcesProvider} for this target using the given target. */ + public static TransitiveSourcesProvider getTransitiveSourcesProvider( + RuleContext ruleContext, List<String> sources) { + TransitiveSourcesProvider.Builder result = new TransitiveSourcesProvider.Builder(); + Iterable<TransitiveSourcesProvider> depTransitiveSourcesProviders = + ruleContext.getPrerequisitesSafe("deps", Mode.TARGET, TransitiveSourcesProvider.class); + for (SourceUsage sourceUsage : SourceUsage.values()) { + boolean sourceIsUsed = false; + // If dependencies use this source type, then the source type is used. + sourceIsUsed |= + (Lists.newArrayList(depTransitiveSourcesProviders) + .stream() + .anyMatch(provider -> provider.uses(sourceUsage))); + + // If this target uses this source type, then the source type is used. + sourceIsUsed |= (sources.stream().anyMatch(source -> sourceUsage.matches(source))); + + if (sourceIsUsed) { + result.doesUse(sourceUsage); + } + } + return result.build(); + } + /** * Creates the feature configuration for a given rule. * @@ -611,6 +668,13 @@ requestedFeatures.addAll(sourceCategory.getActionConfigSet()); + // We check that this target has "srcs" in the target configuration to prevent failing in + // getSources() for rules like cc_embed_data, which have "srcs" in the data configuration. + if (hasSourcesInTargetConfig(ruleContext) + && getTransitiveSourcesProvider(ruleContext).uses(SourceUsage.OBJC)) { + requestedFeatures.add(CppRuleClasses.CONTAINS_OBJC_SOURCE); + } + FeatureSpecification currentFeatureSpecification = FeatureSpecification.create(requestedFeatures.build(), unsupportedFeatures); try {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java index a7ffab3..6294cbe 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
@@ -68,6 +68,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.regex.Pattern; +import java.util.stream.Collectors; import javax.annotation.Nullable; /** @@ -1085,6 +1086,18 @@ new CcLinkParamsInfo( createCcLinkParamsStore(ccLinkingOutputs, cppCompilationContext, forcePic))); } + + if (CcCommon.hasSourcesInTargetConfig(ruleContext)) { + List<String> sources = + compilationUnitSources + .stream() + .map(cppSource -> cppSource.getSource().getExecPathString()) + .collect(Collectors.toList()); + providers.put( + TransitiveSourcesProvider.class, + CcCommon.getTransitiveSourcesProvider(ruleContext, sources)); + } + return new Info( providers.build(), outputGroups,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java index 06e4c9b..28c1735 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
@@ -365,4 +365,7 @@ /** A string constant for the match-clif feature. */ public static final String MATCH_CLIF = "match_clif"; + + /** A string constant for the contains_objc_source feature. */ + public static final String CONTAINS_OBJC_SOURCE = "contains_objc_source"; }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/TransitiveSourcesProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/TransitiveSourcesProvider.java new file mode 100644 index 0000000..a83ce68 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/TransitiveSourcesProvider.java
@@ -0,0 +1,67 @@ +// Copyright 2017 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.cpp; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; +import com.google.devtools.build.lib.util.FileTypeSet; + +/** Provides information on sources in the transitive closure of a target. */ +// TODO(b/65016770): Add SWIFT to this provider. +public class TransitiveSourcesProvider implements TransitiveInfoProvider { + + /** Signal that a certain source type is used. */ + public enum SourceUsage { + CPP(FileTypeSet.of(CppFileTypes.CPP_SOURCE, CppFileTypes.OBJCPP_SOURCE)), + OBJC(FileTypeSet.of(CppFileTypes.OBJC_SOURCE)); + + private final FileTypeSet fileType; + + SourceUsage(FileTypeSet fileType) { + this.fileType = fileType; + } + + /** If true, the presence of the given source signals this source usage. */ + public boolean matches(String fileName) { + return fileType.matches(fileName); + } + } + + private final ImmutableList<SourceUsage> sources; + + private TransitiveSourcesProvider(ImmutableList<SourceUsage> sources) { + this.sources = sources; + } + + /** True if sources of the given type are used in this build. */ + public boolean uses(SourceUsage source) { + return sources.contains(source); + } + + /** Builder for TransitiveSourcesProvider */ + public static class Builder { + private final ImmutableList.Builder<SourceUsage> sources = ImmutableList.builder(); + + /** Signals that the build uses sources of the provided type. */ + public Builder doesUse(SourceUsage source) { + this.sources.add(source); + return this; + } + + public TransitiveSourcesProvider build() { + return new TransitiveSourcesProvider(this.sources.build()); + } + } +}
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 947d8e2..a65a9a5 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
@@ -33,6 +33,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; @@ -141,6 +142,7 @@ getDylibProtoProviders(ruleContext)); Map<String, NestedSet<Artifact>> outputGroupCollector = new TreeMap<>(); + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector = ImmutableList.builder(); multiArchBinarySupport.registerActions( platform, getExtraLinkArgs(ruleContext), @@ -148,7 +150,8 @@ getExtraLinkInputs(ruleContext), configToDepsCollectionMap, outputArtifact, - outputGroupCollector); + outputGroupCollector, + providerCollector); NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder().add(outputArtifact); @@ -212,7 +215,10 @@ } } - targetBuilder.addNativeDeclaredProvider(builder.build()).addOutputGroups(outputGroupCollector); + targetBuilder + .addNativeDeclaredProvider(builder.build()) + .addProviderMaps(providerCollector.build()) + .addOutputGroups(outputGroupCollector); InstrumentedFilesProvider instrumentedFilesProvider = InstrumentedFilesCollector.forward(ruleContext, "deps", "bundle_loader");
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 b31f682..16eef28 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
@@ -28,6 +28,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; 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; @@ -106,6 +107,7 @@ ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT, ObjcProtoProvider.class); Map<String, NestedSet<Artifact>> outputGroupCollector = new TreeMap<>(); + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector = ImmutableList.builder(); for (BuildConfiguration childConfig : childConfigurationsAndToolchains.keySet()) { Iterable<ObjcProtoProvider> objcProtoProviders = objcProtoProvidersMap.get(childConfig); ProtobufSupport protoSupport = @@ -143,6 +145,7 @@ .setRuleContext(ruleContext) .setConfig(childConfig) .setOutputGroupCollector(outputGroupCollector) + .setProviderCollector(providerCollector) .build(); compilationSupport @@ -182,8 +185,8 @@ .addNativeDeclaredProvider(objcProvider) .addNativeDeclaredProvider( new AppleStaticLibraryProvider( - ruleIntermediateArtifacts.combinedArchitectureArchive(), - objcProvider)) + ruleIntermediateArtifacts.combinedArchitectureArchive(), objcProvider)) + .addProviderMaps(providerCollector.build()) .addOutputGroups(outputGroupCollector); return targetBuilder.build(); }
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 e627a7a7..6f00706 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
@@ -28,6 +28,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.RunfilesSupport; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -125,10 +126,12 @@ .build(); Map<String, NestedSet<Artifact>> outputGroupCollector = new TreeMap<>(); + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector = ImmutableList.builder(); CompilationSupport compilationSupport = new CompilationSupport.Builder() .setRuleContext(ruleContext) .setOutputGroupCollector(outputGroupCollector) + .setProviderCollector(providerCollector) .build(); compilationSupport @@ -188,6 +191,7 @@ .addProvider( InstrumentedFilesProvider.class, compilationSupport.getInstrumentedFilesProvider(common)) + .addProviderMaps(providerCollector.build()) .addOutputGroups(outputGroupCollector); if (xcTestAppProvider.isPresent()) {
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 b787ebc..c282b5f 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
@@ -53,6 +53,7 @@ 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.TransitiveInfoProviderMap; 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.ParameterFileWriteAction; @@ -302,6 +303,7 @@ protected final boolean useDeps; protected final Map<String, NestedSet<Artifact>> outputGroupCollector; protected final CcToolchainProvider toolchain; + protected final ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector; protected final boolean isTestRule; protected final boolean usePch; @@ -326,6 +328,7 @@ boolean useDeps, Map<String, NestedSet<Artifact>> outputGroupCollector, CcToolchainProvider toolchain, + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector, boolean isTestRule, boolean usePch) { this.ruleContext = ruleContext; @@ -337,6 +340,7 @@ this.useDeps = useDeps; this.isTestRule = isTestRule; this.outputGroupCollector = outputGroupCollector; + this.providerCollector = providerCollector; this.usePch = usePch; // TODO(b/62143697): Remove this check once all rules are using the crosstool support. if (ruleContext @@ -360,6 +364,8 @@ private CompilationAttributes compilationAttributes; private boolean useDeps = true; private Map<String, NestedSet<Artifact>> outputGroupCollector; + private ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector = + ImmutableList.builder(); private boolean isObjcLibrary = false; private CcToolchainProvider toolchain; private boolean isTestRule = false; @@ -449,6 +455,16 @@ } /** + * Causes the provided list to be updated with providers that should be exported by this target. + */ + public Builder setProviderCollector( + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector) { + Preconditions.checkNotNull(providerCollector); + this.providerCollector = providerCollector; + return this; + } + + /** * Returns a {@link CompilationSupport} instance. This is either a {@link * CrosstoolCompilationSupport} or {@link LegacyCompilationSupport} depending on the value of * --experimental_objc_crosstool. @@ -485,6 +501,7 @@ useDeps, outputGroupCollector, toolchain, + providerCollector, isTestRule, usePch); } else {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java index 8241b68..cf37525 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java
@@ -38,11 +38,14 @@ import com.google.devtools.build.lib.analysis.AnalysisEnvironment; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMapBuilder; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; +import com.google.devtools.build.lib.rules.cpp.CcCommon; import com.google.devtools.build.lib.rules.cpp.CcLibraryHelper; import com.google.devtools.build.lib.rules.cpp.CcLibraryHelper.Info; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.CollidingProvidesException; @@ -62,7 +65,8 @@ import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.NoProcessing; import com.google.devtools.build.lib.rules.cpp.PrecompiledFiles; -import com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag; +import com.google.devtools.build.lib.rules.cpp.TransitiveSourcesProvider; +import com.google.devtools.build.lib.rules.cpp.TransitiveSourcesProvider.SourceUsage; import com.google.devtools.build.lib.rules.objc.ObjcVariablesExtension.VariableCategory; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.Collection; @@ -103,9 +107,6 @@ private static final String GENERATE_LINKMAP_FEATURE_NAME = "generate_linkmap"; - /** Enabled if this target has objc sources in its transitive closure. */ - private static final String CONTAINS_OBJC = "contains_objc_sources"; - private static final ImmutableList<String> ACTIVATED_ACTIONS = ImmutableList.of( "objc-compile", @@ -136,6 +137,7 @@ /*useDeps=*/ true, outputGroupCollector, null, + ImmutableList.builder(), /*isTestRule=*/ false, /*usePch=*/ true); } @@ -159,6 +161,7 @@ boolean useDeps, Map<String, NestedSet<Artifact>> outputGroupCollector, CcToolchainProvider toolchain, + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector, boolean isTestRule, boolean usePch) { super( @@ -169,6 +172,7 @@ useDeps, outputGroupCollector, toolchain, + providerCollector, isTestRule, usePch); } @@ -225,6 +229,15 @@ Info info = helper.build(); outputGroupCollector.putAll(info.getOutputGroups()); + TransitiveSourcesProvider sourcesProvider = + info.getProviders().getProvider(TransitiveSourcesProvider.class); + if (sourcesProvider != null) { + TransitiveInfoProviderMapBuilder providersToPropagate = + new TransitiveInfoProviderMapBuilder(); + providersToPropagate.add(sourcesProvider); + providerCollector.add(providersToPropagate.build()); + } + registerHeaderScanningActions(info, objcProvider, compilationArtifacts); return this; @@ -258,7 +271,7 @@ outputArchive, ccToolchain, fdoSupport, - getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration, objcProvider)) + getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration)) .addActionInputs(objcProvider.getObjcLibraries()) .addActionInputs(objcProvider.getCcLibraries()) .addActionInputs(objcProvider.get(IMPORTED_LIBRARY).toSet()) @@ -309,10 +322,11 @@ registerObjFilelistAction(objFiles, inputFileList); - LinkTargetType linkType = (objcProvider.is(Flag.USES_CPP)) - ? LinkTargetType.OBJCPP_EXECUTABLE - : LinkTargetType.OBJC_EXECUTABLE; - + LinkTargetType linkType = + CcCommon.getTransitiveSourcesProvider(ruleContext).uses(SourceUsage.CPP) + ? LinkTargetType.OBJCPP_EXECUTABLE + : LinkTargetType.OBJC_EXECUTABLE; + ObjcVariablesExtension.Builder extensionBuilder = new ObjcVariablesExtension.Builder() .setRuleContext(ruleContext) @@ -334,7 +348,7 @@ binaryToLink, toolchain, fdoSupport, - getFeatureConfiguration(ruleContext, toolchain, buildConfiguration, objcProvider)) + getFeatureConfiguration(ruleContext, toolchain, buildConfiguration)) .setMnemonic("ObjcLink") .addActionInputs(bazelBuiltLibraries) .addActionInputs(objcProvider.getCcLibraries()) @@ -435,7 +449,7 @@ new CcLibraryHelper( ruleContext, semantics, - getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration, objcProvider), + getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration), CcLibraryHelper.SourceCategory.CC_AND_OBJC, ccToolchain, fdoSupport, @@ -483,10 +497,7 @@ } private FeatureConfiguration getFeatureConfiguration( - RuleContext ruleContext, - CcToolchainProvider ccToolchain, - BuildConfiguration configuration, - ObjcProvider objcProvider) { + RuleContext ruleContext, CcToolchainProvider ccToolchain, BuildConfiguration configuration) { boolean isHost = ruleContext.getConfiguration().isHostConfiguration(); ImmutableSet.Builder<String> activatedCrosstoolSelectables = ImmutableSet.<String>builder() @@ -537,8 +548,8 @@ if (bitcodeMode != AppleBitcodeMode.NONE) { activatedCrosstoolSelectables.addAll(bitcodeMode.getFeatureNames()); } - if (objcProvider.is(Flag.USES_OBJC)) { - activatedCrosstoolSelectables.add(CONTAINS_OBJC); + if (CcCommon.getTransitiveSourcesProvider(ruleContext).uses(SourceUsage.OBJC)) { + activatedCrosstoolSelectables.add(CppRuleClasses.CONTAINS_OBJC_SOURCE); } activatedCrosstoolSelectables.addAll(ruleContext.getFeatures());
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 24f1f98..1ca650d 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
@@ -31,6 +31,7 @@ import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.analysis.RunfilesSupport; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; import com.google.devtools.build.lib.analysis.test.ExecutionInfo; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -158,8 +159,13 @@ ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcEntryClassProvider.class)) .build(); + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector = ImmutableList.builder(); CompilationSupport compilationSupport = - new CompilationSupport.Builder().setRuleContext(ruleContext).setIsTestRule().build(); + new CompilationSupport.Builder() + .setProviderCollector(providerCollector) + .setRuleContext(ruleContext) + .setIsTestRule() + .build(); compilationSupport .registerLinkActions( @@ -231,6 +237,7 @@ .addNativeDeclaredProvider(new ExecutionInfo(execInfoMapBuilder.build())) .addNativeDeclaredProviders(testSupport.getExtraProviders()) .addProvider(InstrumentedFilesProvider.class, instrumentedFilesProvider) + .addProviderMaps(providerCollector.build()) .setRunfilesSupport(runfilesSupport, executable) .build(); }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java index 8cd7c33..f34aab5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java
@@ -26,6 +26,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.RunfilesProvider; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.syntax.Type; @@ -94,8 +95,10 @@ .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext)) .build(); + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector = ImmutableList.builder(); new CompilationSupport.Builder() .setRuleContext(ruleContext) + .setProviderCollector(providerCollector) .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext)) .doNotUsePch() .build() @@ -110,6 +113,7 @@ .add(RunfilesProvider.class, RunfilesProvider.EMPTY) .addProvider(J2ObjcEntryClassProvider.class, j2ObjcEntryClassProvider) .addProvider(J2ObjcMappingFileProvider.class, j2ObjcMappingFileProvider) + .addProviderMaps(providerCollector.build()) .addNativeDeclaredProvider(objcProvider) .build(); }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java index 52024af..c3a336b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java
@@ -17,7 +17,6 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DEFINE; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DYNAMIC_FRAMEWORK_FILE; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FORCE_LOAD_LIBRARY; -import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_CPP; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE; @@ -27,7 +26,6 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STATIC_FRAMEWORK_FILE; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.CLANG; -import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.CLANG_PLUSPLUS; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.COMPILABLE_SRCS_TYPE; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.DSYMUTIL; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.HEADERS; @@ -159,6 +157,7 @@ useDeps, outputGroupCollector, toolchain, + ImmutableList.builder(), isTestRule, usePch); } @@ -676,14 +675,7 @@ CustomCommandLine.Builder commandLine = CustomCommandLine.builder() .addPath(xcrunwrapper(ruleContext).getExecutable().getExecPath()); - if (objcProvider.is(USES_CPP)) { - commandLine - .add(CLANG_PLUSPLUS) - .add("-stdlib=libc++") - .add("-std=gnu++11"); - } else { - commandLine.add(CLANG); - } + commandLine.add(CLANG); // TODO(b/36562173): Replace the "!isTestRule" condition with the presence of "-bundle" in // the command line.
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 4da377c..79744d4 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
@@ -25,6 +25,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.platform.ToolchainInfo; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -128,6 +129,8 @@ * this support * @param outputMapCollector a map to which output groups created by compile action generation are * added + * @param providerCollector a list to which provider maps created by compile and link action + * generation are added * @throws RuleErrorException if there are attribute errors in the current rule context */ public void registerActions( @@ -137,7 +140,8 @@ Iterable<Artifact> extraLinkInputs, ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap, Artifact outputLipoBinary, - Map<String, NestedSet<Artifact>> outputMapCollector) + Map<String, NestedSet<Artifact>> outputMapCollector, + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector) throws RuleErrorException, InterruptedException { NestedSetBuilder<Artifact> binariesToLipo = @@ -179,6 +183,7 @@ .setRuleContext(ruleContext) .setConfig(dependencySpecificConfiguration.config()) .setOutputGroupCollector(outputMapCollector) + .setProviderCollector(providerCollector) .build(); compilationSupport
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java index cd08ee7..cf1ab2e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
@@ -23,10 +23,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DEFINE; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DYNAMIC_FRAMEWORK_DIR; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DYNAMIC_FRAMEWORK_FILE; -import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FLAG; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FORCE_LOAD_LIBRARY; -import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_CPP; -import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_OBJC; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE; @@ -71,10 +68,8 @@ import com.google.devtools.build.lib.rules.cpp.CcLinkParams; import com.google.devtools.build.lib.rules.cpp.CcLinkParamsInfo; import com.google.devtools.build.lib.rules.cpp.CppCompilationContext; -import com.google.devtools.build.lib.rules.cpp.CppFileTypes; import com.google.devtools.build.lib.rules.cpp.CppModuleMap; import com.google.devtools.build.lib.util.FileType; -import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.HashSet; @@ -522,24 +517,6 @@ && J2ObjcLibrary.J2OBJC_SUPPORTED_RULES.contains(context.getRule().getRuleClass())) { objcProvider.addAll(J2OBJC_LIBRARY, artifacts.getArchive().asSet()); } - - boolean usesCpp = false; - boolean usesObjc = false; - for (Artifact sourceFile : - Iterables.concat(artifacts.getSrcs(), artifacts.getNonArcSrcs())) { - usesCpp = usesCpp || ObjcRuleClasses.CPP_SOURCES.matches(sourceFile.getExecPath()); - usesObjc = - usesObjc - || FileTypeSet.of(CppFileTypes.OBJC_SOURCE, CppFileTypes.OBJCPP_SOURCE) - .matches(sourceFile.getExecPath().getPathString()); - } - - if (usesCpp) { - objcProvider.add(FLAG, USES_CPP); - } - if (usesObjc) { - objcProvider.add(FLAG, USES_OBJC); - } } if (alwayslink) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java index 043605f..a32cc32 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
@@ -14,11 +14,13 @@ package com.google.devtools.build.lib.rules.objc; +import com.google.common.collect.ImmutableList; 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; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.cpp.CppModuleMap; import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes; @@ -56,8 +58,10 @@ Iterable<Artifact> publicHeaders = compilationAttributes.hdrs(); CppModuleMap moduleMap = intermediateArtifacts.moduleMap(); + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector = ImmutableList.builder(); new CompilationSupport.Builder() .setRuleContext(ruleContext) + .setProviderCollector(providerCollector) .build() .registerGenerateModuleMapAction(moduleMap, publicHeaders) .validateAttributes(); @@ -66,6 +70,7 @@ return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build()) .addNativeDeclaredProvider(common.getObjcProvider()) + .addProviderMaps(providerCollector.build()) .build(); } }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java index bb7429f..85e08c1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
@@ -14,11 +14,13 @@ package com.google.devtools.build.lib.rules.objc; +import com.google.common.collect.ImmutableList; 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; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -67,10 +69,12 @@ .addAll(common.getCompiledArchive().asSet()); Map<String, NestedSet<Artifact>> outputGroupCollector = new TreeMap<>(); + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector = ImmutableList.builder(); CompilationSupport compilationSupport = new CompilationSupport.Builder() .setRuleContext(ruleContext) .setOutputGroupCollector(outputGroupCollector) + .setProviderCollector(providerCollector) .setIsObjcLibrary() .build(); @@ -96,8 +100,8 @@ .addProvider( InstrumentedFilesProvider.class, compilationSupport.getInstrumentedFilesProvider(common)) - .addNativeDeclaredProvider( - new CcLinkParamsInfo(new ObjcLibraryCcLinkParamsStore(common))) + .addNativeDeclaredProvider(new CcLinkParamsInfo(new ObjcLibraryCcLinkParamsStore(common))) + .addProviderMaps(providerCollector.build()) .addOutputGroups(outputGroupCollector) .build(); }
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 0970d96..a11c96f 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
@@ -343,19 +343,8 @@ * flag. If the item is included in the key {@link #FLAG}, then the flag is considered set. */ public enum Flag { - /** - * Indicates that C++ (or Objective-C++) is used in any source file. This affects how the linker - * is invoked. - */ - USES_CPP, - - /** - * Indicates that Objective-C (or Objective-C++) is used in any source file. This affects how - * the linker is invoked. - */ - USES_OBJC, - /** Indicates that Swift dependencies are present. This affects bundling actions. */ + // TODO(b/65016770): Move to TransitiveSourcesProvider. USES_SWIFT, /**
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinaryTest.java index 01754e5..b0d0953 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinaryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinaryTest.java
@@ -223,4 +223,9 @@ public void testCompilesSources() throws Exception { checkCompilesSources(RULE_TYPE); } + + @Test + public void testLinkActionWithTransitiveCppDependency() throws Exception { + checkLinkActionWithTransitiveCppDependency(RULE_TYPE, EXTRA_LINK_ARGS); + } }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyIosExtensionBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyIosExtensionBinaryTest.java index 0fadc47..f2416ea 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyIosExtensionBinaryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyIosExtensionBinaryTest.java
@@ -29,9 +29,10 @@ return ObjcCrosstoolMode.OFF; } + @Override @Test public void testLinkActionWithTransitiveCppDependency() throws Exception { - checkLinkActionWithTransitiveCppDependency(RULE_TYPE, EXTRA_LINK_ARGS); + // Transitive source data is not known to the legacy rules. } @Test
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcBinaryTest.java index d0c08a6..55475fe 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcBinaryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcBinaryTest.java
@@ -37,9 +37,10 @@ return ObjcCrosstoolMode.OFF; } + @Override @Test public void testLinkActionWithTransitiveCppDependency() throws Exception { - checkLinkActionWithTransitiveCppDependency(RULE_TYPE, new ExtraLinkArgs()); + // Transitive sources data is not available to the legacy rules. } @Test
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java index 2028571..abbae40 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java
@@ -59,24 +59,6 @@ useConfiguration(ObjcCrosstoolMode.OFF, args); } - @Override - @Test - public void testObjcSourcesFeatureCC() throws Exception { - // Features are not exported by legacy actions. - } - - @Override - @Test - public void testObjcSourcesFeatureObjc() throws Exception { - // Features are not exported by legacy actions. - } - - @Override - @Test - public void testObjcSourcesFeatureObjcPlusPlus() throws Exception { - // Features are not exported by legacy actions. - } - @Test public void testLibFileIsCorrectForSlashInTargetName() throws Exception { ConfiguredTarget target =
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryTest.java index 4775e2d..255841d 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryTest.java
@@ -935,4 +935,9 @@ public void testGenruleDependency() throws Exception { checkGenruleDependency(RULE_TYPE); } + + @Test + public void testLinkActionWithTransitiveCppDependency() throws Exception { + checkLinkActionWithTransitiveCppDependency(RULE_TYPE, new ExtraLinkArgs()); + } }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java index 08b1d0b..056a607 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java
@@ -1566,45 +1566,4 @@ public void testCustomModuleMap() throws Exception { checkCustomModuleMap(RULE_TYPE); } - - private boolean containsObjcFeature(String srcName) throws Exception { - MockObjcSupport.setup( - mockToolsConfig, - "feature {", - " name: 'contains_objc_sources'", - " flag_set {", - " flag_group {", - " flag: 'DUMMY_FLAG'", - " }", - " action: 'c++-compile'", - " }", - "}"); - createLibraryTargetWriter("//bottom:lib").setList("srcs", srcName).write(); - createLibraryTargetWriter("//middle:lib") - .setList("srcs", "b.cc") - .setList("deps", "//bottom:lib") - .write(); - createLibraryTargetWriter("//top:lib") - .setList("srcs", "a.cc") - .setList("deps", "//middle:lib") - .write(); - - CommandAction compileAction = compileAction("//top:lib", "a.o"); - return compileAction.getArguments().contains("DUMMY_FLAG"); - } - - @Test - public void testObjcSourcesFeatureCC() throws Exception { - assertThat(containsObjcFeature("c.cc")).isFalse(); - } - - @Test - public void testObjcSourcesFeatureObjc() throws Exception { - assertThat(containsObjcFeature("c.m")).isTrue(); - } - - @Test - public void testObjcSourcesFeatureObjcPlusPlus() throws Exception { - assertThat(containsObjcFeature("c.mm")).isTrue(); - } }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java index b48d242..7baa058 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
@@ -26,7 +26,6 @@ import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.FAMILIES_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.INFOPLIST_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.CLANG; -import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.CLANG_PLUSPLUS; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.DSYMUTIL; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.LIPO; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.APP_ICON_ATTR; @@ -644,9 +643,10 @@ ruleType.scratchTarget(scratch, "srcs", "['c.m']", "deps", "['//lib2:lib2']"); CommandAction action = linkAction("//x:x"); - assertThat(action.getArguments().get(2)) - .startsWith( - MOCK_XCRUNWRAPPER_PATH + " " + CLANG_PLUSPLUS + " -stdlib=libc++ -std=gnu++11"); + String commandLine = Joiner.on(" ").join(action.getArguments()); + assertThat(commandLine).contains("wrapped_clang++"); + assertThat(commandLine).contains("-stdlib=libc++"); + assertThat(commandLine).contains("-std=gnu++11"); } protected Map<String, String> mobileProvisionProfiles(BundleMergeProtos.Control control) {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/TransitiveSourcesTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/TransitiveSourcesTest.java new file mode 100644 index 0000000..015c7d1 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/TransitiveSourcesTest.java
@@ -0,0 +1,85 @@ +// Copyright 2017 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 static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.packages.util.MockObjcSupport; +import com.google.devtools.build.lib.rules.cpp.CppCompileAction; +import com.google.devtools.build.lib.rules.cpp.CppLinkAction; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for propagation of the presence of categories of source in the transitive deps of a target. + */ +@RunWith(JUnit4.class) +public class TransitiveSourcesTest extends ObjcRuleTestCase { + + @Before + public void setup() throws Exception { + MockObjcSupport.setup( + mockToolsConfig, + "feature {", + " name: 'contains_objc_source'", + " flag_set {", + " flag_group {", + " flag: 'DUMMY_FLAG'", + " }", + " action: 'c++-compile'", + " action: 'c++-link-executable'", + " action: 'objc++-executable'", + " }", + "}"); + useConfiguration(); + } + + private CppCompileAction getCppCompileAction(String label) throws Exception { + ConfiguredTarget target = getConfiguredTarget(label); + return actionsTestUtil() + .findTransitivePrerequisitesOf( + getFilesToBuild(target).iterator().next(), CppCompileAction.class) + .get(0); + } + + private CppLinkAction getExecutableCppLinkAction(String label) throws Exception { + return (CppLinkAction) getGeneratingAction(getExecutable(label)); + } + + @Test + public void testCcBinaryTransitiveObjcFeature() throws Exception { + scratch.file("bottom/BUILD", "objc_library(name='lib', srcs=['a.m'])"); + scratch.file("middle/BUILD", "cc_library(name='lib', srcs=['a.cc'], deps=['//bottom:lib'])"); + scratch.file("top/BUILD", "cc_binary(name='bin', srcs=['a.cc'], deps=['//middle:lib'])"); + + assertThat(getCppCompileAction("//top:bin").getArguments()).contains("DUMMY_FLAG"); + assertThat(getExecutableCppLinkAction("//top:bin").getArguments()).contains("DUMMY_FLAG"); + } + + @Test + public void testAppleBinaryTransitiveObjcFeature() throws Exception { + scratch.file("bottom/BUILD", "objc_library(name='lib', srcs=['a.m'])"); + scratch.file("middle/BUILD", "cc_library(name='lib', srcs=['a.cc'], deps=['//bottom:lib'])"); + scratch.file( + "top/BUILD", + "apple_binary(name='bin', platform_type='ios', srcs=['a.cc'], deps=['//middle:lib'])"); + + assertThat(getCppCompileAction("//top:bin").getArguments()).contains("DUMMY_FLAG"); + assertThat(linkAction("//top:bin").getArguments()).contains("DUMMY_FLAG"); + } +}