diff options
author | 2017-08-30 03:10:41 +0200 | |
---|---|---|
committer | 2017-08-30 13:48:58 +0200 | |
commit | fc41c430e4de4594a1d699f573d191cbad52a2fb (patch) | |
tree | 60bfc201402d9b810952ac62ba564247415294cf /src/main/java/com | |
parent | 75f97c1194c82bdd59f0a8c2809e7bfa464b01d4 (diff) |
Move ObjcProvider FLAG into a new provider type (TransitiveSourcesProvider) that is accessible to the c++ rules.
PiperOrigin-RevId: 166934390
Diffstat (limited to 'src/main/java/com')
19 files changed, 264 insertions, 74 deletions
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 7522d099b5..316f50e2bd 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 @@ public final class RuleConfiguredTargetBuilder { 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 3f28614cb7..8cd4315b08 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 @@ public final class RuleContext extends TargetContext } /** + * 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 4856b0a1e6..32c8cf9dc1 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.ImmutableList; 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.Label; 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.FeatureConfig 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.List; 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 @@ public final class CcCommon { 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 @@ public final class CcCommon { } /** + * 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 @@ public final class CcCommon { } } + /** 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 @@ public final class CcCommon { 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 a7ffab3456..6294cbe30a 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.Map; 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 @@ public final class CcLibraryHelper { 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 06e4c9b687..28c1735da9 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 @@ public class CppRuleClasses { /** 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 0000000000..a83ce68d34 --- /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 947d8e2cbc..a65a9a5538 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.RuleConfiguredTargetBuilder; 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 @@ public class AppleBinary implements RuleConfiguredTargetFactory { getDylibProtoProviders(ruleContext)); Map<String, NestedSet<Artifact>> outputGroupCollector = new TreeMap<>(); + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector = ImmutableList.builder(); multiArchBinarySupport.registerActions( platform, getExtraLinkArgs(ruleContext), @@ -148,7 +150,8 @@ public class AppleBinary implements RuleConfiguredTargetFactory { getExtraLinkInputs(ruleContext), configToDepsCollectionMap, outputArtifact, - outputGroupCollector); + outputGroupCollector, + providerCollector); NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder().add(outputArtifact); @@ -212,7 +215,10 @@ public class AppleBinary implements RuleConfiguredTargetFactory { } } - 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 b31f682c93..16eef28170 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.RuleConfiguredTargetBuilder; 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 @@ public class AppleStaticLibrary implements RuleConfiguredTargetFactory { 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 @@ public class AppleStaticLibrary implements RuleConfiguredTargetFactory { .setRuleContext(ruleContext) .setConfig(childConfig) .setOutputGroupCollector(outputGroupCollector) + .setProviderCollector(providerCollector) .build(); compilationSupport @@ -182,8 +185,8 @@ public class AppleStaticLibrary implements RuleConfiguredTargetFactory { .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 e627a7a71c..6f007061e7 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.RuleConfiguredTargetBuilder; 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 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory .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 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory .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 b787ebcaf5..c282b5fc84 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.FilesToRunProvider; import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.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 @@ public abstract class CompilationSupport { 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 @@ public abstract class CompilationSupport { boolean useDeps, Map<String, NestedSet<Artifact>> outputGroupCollector, CcToolchainProvider toolchain, + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector, boolean isTestRule, boolean usePch) { this.ruleContext = ruleContext; @@ -337,6 +340,7 @@ public abstract class CompilationSupport { 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 @@ public abstract class CompilationSupport { 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 @@ public abstract class CompilationSupport { } /** + * 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 @@ public abstract class CompilationSupport { 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 8241b68cfb..cf3752563e 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.actions.Artifact; 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.LinkStaticness; 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 @@ public class CrosstoolCompilationSupport extends CompilationSupport { 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 @@ public class CrosstoolCompilationSupport extends CompilationSupport { /*useDeps=*/ true, outputGroupCollector, null, + ImmutableList.builder(), /*isTestRule=*/ false, /*usePch=*/ true); } @@ -159,6 +161,7 @@ public class CrosstoolCompilationSupport extends CompilationSupport { boolean useDeps, Map<String, NestedSet<Artifact>> outputGroupCollector, CcToolchainProvider toolchain, + ImmutableList.Builder<TransitiveInfoProviderMap> providerCollector, boolean isTestRule, boolean usePch) { super( @@ -169,6 +172,7 @@ public class CrosstoolCompilationSupport extends CompilationSupport { useDeps, outputGroupCollector, toolchain, + providerCollector, isTestRule, usePch); } @@ -225,6 +229,15 @@ public class CrosstoolCompilationSupport extends CompilationSupport { 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 @@ public class CrosstoolCompilationSupport extends CompilationSupport { 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 @@ public class CrosstoolCompilationSupport extends CompilationSupport { 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 @@ public class CrosstoolCompilationSupport extends CompilationSupport { binaryToLink, toolchain, fdoSupport, - getFeatureConfiguration(ruleContext, toolchain, buildConfiguration, objcProvider)) + getFeatureConfiguration(ruleContext, toolchain, buildConfiguration)) .setMnemonic("ObjcLink") .addActionInputs(bazelBuiltLibraries) .addActionInputs(objcProvider.getCcLibraries()) @@ -435,7 +449,7 @@ public class CrosstoolCompilationSupport extends CompilationSupport { new CcLibraryHelper( ruleContext, semantics, - getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration, objcProvider), + getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration), CcLibraryHelper.SourceCategory.CC_AND_OBJC, ccToolchain, fdoSupport, @@ -483,10 +497,7 @@ public class CrosstoolCompilationSupport extends CompilationSupport { } 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 @@ public class CrosstoolCompilationSupport extends CompilationSupport { 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 24f1f9825b..1ca650db16 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.RuleContext; 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 @@ public final class IosTest implements RuleConfiguredTargetFactory { 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 @@ public final class IosTest implements RuleConfiguredTargetFactory { .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 8cd7c33c2d..f34aab579b 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.RuleConfiguredTargetBuilder; 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 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory { .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 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory { .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 52024afae9..c3a336b560 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 @@ package com.google.devtools.build.lib.rules.objc; 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.MODULE_MAP; 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 @@ public class LegacyCompilationSupport extends CompilationSupport { useDeps, outputGroupCollector, toolchain, + ImmutableList.builder(), isTestRule, usePch); } @@ -676,14 +675,7 @@ public class LegacyCompilationSupport extends CompilationSupport { 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 4da377ce73..79744d4d2d 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.actions.Artifact; 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 @@ public class MultiArchBinarySupport { * 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 @@ public class MultiArchBinarySupport { 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 @@ public class MultiArchBinarySupport { .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 cd08ee7d1e..cf1ab2ee59 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.DEBUG_SYMBOL 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.apple.AppleToolchain; 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 @@ public final class ObjcCommon { && 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 043605f489..a32cc320c6 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 @@ public class ObjcImport implements RuleConfiguredTargetFactory { 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 @@ public class ObjcImport implements RuleConfiguredTargetFactory { 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 bb7429f019..85e08c128b 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 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory { .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 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory { .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 0970d96606..a11c96ffb3 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 @@ public final class ObjcProvider extends NativeInfo { * 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, /** |