diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis')
5 files changed, 131 insertions, 4 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java index dbce56b589..30861cd3ac 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java @@ -31,9 +31,11 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider; import com.google.devtools.build.lib.analysis.configuredtargets.EnvironmentGroupConfiguredTarget; +import com.google.devtools.build.lib.analysis.configuredtargets.FilesetOutputConfiguredTarget; import com.google.devtools.build.lib.analysis.configuredtargets.InputFileConfiguredTarget; import com.google.devtools.build.lib.analysis.configuredtargets.OutputFileConfiguredTarget; import com.google.devtools.build.lib.analysis.configuredtargets.PackageGroupConfiguredTarget; +import com.google.devtools.build.lib.analysis.fileset.FilesetProvider; import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleConfiguredTargetUtil; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -230,7 +232,16 @@ public final class ConfiguredTargetFactory { } TransitiveInfoCollection rule = targetContext.findDirectPrerequisite( outputFile.getGeneratingRule().getLabel(), config); + if (isFileset) { + return new FilesetOutputConfiguredTarget( + targetContext, + outputFile, + rule, + artifact, + rule.getProvider(FilesetProvider.class).getTraversals()); + } else { return new OutputFileConfiguredTarget(targetContext, outputFile, rule, artifact); + } } else if (target instanceof InputFile) { InputFile inputFile = (InputFile) target; SourceArtifact artifact = 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 0cccfb8345..3eebb2d037 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 @@ -55,6 +55,7 @@ import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.constraints.ConstraintSemantics; +import com.google.devtools.build.lib.analysis.fileset.FilesetProvider; import com.google.devtools.build.lib.analysis.platform.PlatformInfo; import com.google.devtools.build.lib.analysis.stringtemplate.TemplateContext; import com.google.devtools.build.lib.cmdline.Label; @@ -1554,12 +1555,9 @@ public final class RuleContext extends TargetContext } private boolean validateFilesetEntry(FilesetEntry filesetEntry, ConfiguredTargetAndData src) { - NestedSet<Artifact> filesToBuild = - src.getConfiguredTarget().getProvider(FileProvider.class).getFilesToBuild(); - if (filesToBuild.isSingleton() && Iterables.getOnlyElement(filesToBuild).isFileset()) { + if (src.getConfiguredTarget().getProvider(FilesetProvider.class) != null) { return true; } - if (filesetEntry.isSourceFileset()) { return true; } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/FileConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/FileConfiguredTarget.java index cd959fa858..2fec10f91e 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/FileConfiguredTarget.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/FileConfiguredTarget.java @@ -23,6 +23,7 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMapBuilder; import com.google.devtools.build.lib.analysis.VisibilityProvider; +import com.google.devtools.build.lib.analysis.fileset.FilesetProvider; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -61,6 +62,9 @@ public abstract class FileConfiguredTarget extends AbstractConfiguredTarget .put(LicensesProvider.class, this) .add(fileProvider) .add(filesToRunProvider); + if (this instanceof FilesetProvider) { + builder.put(FilesetProvider.class, this); + } if (this instanceof InstrumentedFilesProvider) { builder.put(InstrumentedFilesProvider.class, this); } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/FilesetOutputConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/FilesetOutputConfiguredTarget.java new file mode 100644 index 0000000000..08dc1ac78e --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/FilesetOutputConfiguredTarget.java @@ -0,0 +1,84 @@ +// Copyright 2014 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.analysis.configuredtargets; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.FilesetTraversalParams; +import com.google.devtools.build.lib.analysis.TargetContext; +import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.fileset.FilesetProvider; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; +import com.google.devtools.build.lib.packages.OutputFile; +import com.google.devtools.build.lib.packages.PackageSpecification.PackageGroupContents; +import com.google.devtools.build.lib.skyframe.BuildConfigurationValue; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; + +/** + * A configured target for output files generated by {@code Fileset} rules. They are almost the same + * thing as output files except that they implement {@link FilesetProvider} so that {@code Fileset} + * can figure out the link tree behind them. + * + * <p>In an ideal world, this would not be needed: Filesets would depend on other Filesets and not + * their output directories. However, sometimes a Fileset depends on the output directory of another + * Fileset. Thus, we need this hack. + */ +@AutoCodec +public final class FilesetOutputConfiguredTarget extends OutputFileConfiguredTarget + implements FilesetProvider { + private final ImmutableList<FilesetTraversalParams> filesetTraversals; + + public FilesetOutputConfiguredTarget( + TargetContext targetContext, + OutputFile outputFile, + TransitiveInfoCollection generatingRule, + Artifact outputArtifact, + ImmutableList<FilesetTraversalParams> traversals) { + this( + targetContext.getLabel(), + targetContext.getConfigurationKey(), + targetContext.getVisibility(), + generatingRule, + outputArtifact, + traversals); + Preconditions.checkState( + outputFile.getLabel().equals(targetContext.getLabel()), + "mismatch: %s %s", + outputFile, + targetContext); + } + + @AutoCodec.VisibleForSerialization + @AutoCodec.Instantiator + FilesetOutputConfiguredTarget( + Label label, + BuildConfigurationValue.Key configurationKey, + NestedSet<PackageGroupContents> visibility, + TransitiveInfoCollection generatingRule, + Artifact artifact, + ImmutableList<FilesetTraversalParams> traversals) { + super(label, configurationKey, visibility, artifact, generatingRule); + FilesetProvider provider = generatingRule.getProvider(FilesetProvider.class); + Preconditions.checkArgument(provider != null); + filesetTraversals = traversals; + } + + @Override + public ImmutableList<FilesetTraversalParams> getTraversals() { + return filesetTraversals; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/fileset/FilesetProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/fileset/FilesetProvider.java new file mode 100644 index 0000000000..225a40eb42 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/fileset/FilesetProvider.java @@ -0,0 +1,30 @@ +// Copyright 2014 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.analysis.fileset; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.actions.FilesetTraversalParams; +import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; + +/** + * Information needed by a Fileset to do the right thing when it depends on another Fileset. + */ +public interface FilesetProvider extends TransitiveInfoProvider { + /** + * Returns a list of the traversals that went into this Fileset. Only used by Skyframe-native + * filesets, so will be null if Skyframe-native filesets are not enabled. + */ + ImmutableList<FilesetTraversalParams> getTraversals(); +} |