diff options
Diffstat (limited to 'src/main/java/com')
5 files changed, 187 insertions, 75 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ExtraActionArtifactsProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ExtraActionArtifactsProvider.java index 3ea9a5a8de..4c86c6a819 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ExtraActionArtifactsProvider.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ExtraActionArtifactsProvider.java @@ -19,12 +19,17 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; -/** - * A {@link TransitiveInfoProvider} that creates extra actions. - */ +/** A {@link TransitiveInfoProvider} that creates extra actions. */ @Immutable +@AutoCodec public final class ExtraActionArtifactsProvider implements TransitiveInfoProvider { + public static final ObjectCodec<ExtraActionArtifactsProvider> CODEC = + new ExtraActionArtifactsProvider_AutoCodec(); + public static final ExtraActionArtifactsProvider EMPTY = new ExtraActionArtifactsProvider( NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER), @@ -57,7 +62,9 @@ public final class ExtraActionArtifactsProvider implements TransitiveInfoProvide private final NestedSet<Artifact> transitiveExtraActionArtifacts; /** Use {@link #create} instead. */ - private ExtraActionArtifactsProvider( + @AutoCodec.Instantiator + @VisibleForSerialization + ExtraActionArtifactsProvider( NestedSet<Artifact> extraActionArtifacts, NestedSet<Artifact> transitiveExtraActionArtifacts) { this.extraActionArtifacts = extraActionArtifacts; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/FilesToRunProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/FilesToRunProvider.java index bd3353eaf8..09c5c48f7d 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/FilesToRunProvider.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/FilesToRunProvider.java @@ -21,6 +21,8 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; @@ -29,7 +31,10 @@ import javax.annotation.Nullable; /** Returns information about executables produced by a target and the files needed to run it. */ @Immutable @SkylarkModule(name = "FilesToRunProvider", doc = "", category = SkylarkModuleCategory.PROVIDER) +@AutoCodec public final class FilesToRunProvider implements TransitiveInfoProvider { + public static final ObjectCodec<FilesToRunProvider> CODEC = new FilesToRunProvider_AutoCodec(); + /** The name of the field in Skylark used to access this class. */ public static final String SKYLARK_NAME = "files_to_run"; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupInfo.java index 73c1f8bcfa..f1c14234f1 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupInfo.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupInfo.java @@ -31,6 +31,8 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.NativeInfo; import com.google.devtools.build.lib.packages.NativeProvider; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.syntax.SkylarkIndexable; @@ -57,8 +59,11 @@ import javax.annotation.Nullable; * not mentioned on the output. */ @Immutable +@AutoCodec public final class OutputGroupInfo extends NativeInfo implements SkylarkIndexable, Iterable<String> { + public static ObjectCodec<OutputGroupInfo> CODEC = new OutputGroupInfo_AutoCodec(); + public static final String SKYLARK_NAME = "output_groups"; public static NativeProvider<OutputGroupInfo> SKYLARK_CONSTRUCTOR = new Constructor(); diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java b/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java index 8456ffd9de..654f7fa2a8 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java @@ -27,6 +27,9 @@ import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTa import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.packages.TargetUtils; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; @@ -68,7 +71,10 @@ import javax.annotation.Nullable; * which will run an executable should depend on this Middleman Artifact. */ @Immutable +@AutoCodec public final class RunfilesSupport { + public static final ObjectCodec<RunfilesSupport> CODEC = new RunfilesSupport_AutoCodec(); + private static final String RUNFILES_DIR_EXT = ".runfiles"; private final Runfiles runfiles; @@ -85,14 +91,15 @@ public final class RunfilesSupport { * Creates the RunfilesSupport helper with the given executable and runfiles. * * @param ruleContext the rule context to create the runfiles support for - * @param executable the executable for whose runfiles this runfiles support is responsible + * @param executable the executable for whose runfiles this runfiles support is responsible, may + * be null * @param runfiles the runfiles */ - private RunfilesSupport( + private static RunfilesSupport create( RuleContext ruleContext, Artifact executable, Runfiles runfiles, CommandLine args) { - owningExecutable = Preconditions.checkNotNull(executable); + Artifact owningExecutable = Preconditions.checkNotNull(executable); boolean createManifest = ruleContext.getConfiguration().buildRunfilesManifests(); - createSymlinks = createManifest && ruleContext.getConfiguration().buildRunfiles(); + boolean createSymlinks = createManifest && ruleContext.getConfiguration().buildRunfiles(); // Adding run_under target to the runfiles manifest so it would become part // of runfiles tree and would be executable everywhere. @@ -107,26 +114,56 @@ public final class RunfilesSupport { .merge(runfiles) .build(); } - this.runfiles = runfiles; - Preconditions.checkState(!runfiles.isEmpty()); - Map<PathFragment, Artifact> symlinks = getRunfilesSymlinks(); - if (!symlinks.containsValue(executable)) { + Map<PathFragment, Artifact> symlinks = runfiles.asMapWithoutRootSymlinks(); + if (executable != null && !symlinks.containsValue(executable)) { throw new IllegalStateException("main program " + executable + " not included in runfiles"); } + Artifact runfilesInputManifest; + Artifact runfilesManifest; if (createManifest) { - runfilesInputManifest = createRunfilesInputManifestArtifact(ruleContext); - runfilesManifest = createRunfilesAction(ruleContext, runfiles); + runfilesInputManifest = createRunfilesInputManifestArtifact(ruleContext, owningExecutable); + runfilesManifest = + createRunfilesAction(ruleContext, runfiles, createSymlinks, runfilesInputManifest); } else { runfilesInputManifest = null; runfilesManifest = null; } - runfilesMiddleman = + Artifact runfilesMiddleman = createRunfilesMiddleman(ruleContext, owningExecutable, runfiles, runfilesManifest); - sourcesManifest = createSourceManifest(ruleContext, runfiles); + Artifact sourcesManifest = createSourceManifest(ruleContext, runfiles, owningExecutable); + + return new RunfilesSupport( + runfiles, + runfilesInputManifest, + runfilesManifest, + runfilesMiddleman, + sourcesManifest, + owningExecutable, + createSymlinks, + args); + } + @AutoCodec.Instantiator + @VisibleForSerialization + RunfilesSupport( + Runfiles runfiles, + Artifact runfilesInputManifest, + Artifact runfilesManifest, + Artifact runfilesMiddleman, + Artifact sourcesManifest, + Artifact owningExecutable, + boolean createSymlinks, + CommandLine args) { + this.runfiles = runfiles; + this.runfilesInputManifest = runfilesInputManifest; + this.runfilesManifest = runfilesManifest; + this.runfilesMiddleman = runfilesMiddleman; + this.sourcesManifest = sourcesManifest; + this.owningExecutable = owningExecutable; + this.createSymlinks = createSymlinks; this.args = args; } @@ -138,8 +175,9 @@ public final class RunfilesSupport { } /** - * Returns the exec path of the directory where the runfiles contained in this RunfilesSupport are - * generated. + * Returns the exec path of the directory where the runfiles contained in this + * RunfilesSupport are generated. When the owning rule has no executable, + * returns null. */ public PathFragment getRunfilesDirectoryExecPath() { PathFragment executablePath = owningExecutable.getExecPath(); @@ -170,8 +208,12 @@ public final class RunfilesSupport { return runfilesInputManifest; } - private Artifact createRunfilesInputManifestArtifact(RuleContext context) { - PathFragment relativePath = owningExecutable.getRootRelativePath(); + private static Artifact createRunfilesInputManifestArtifact( + RuleContext context, Artifact owningExecutable) { + // The executable may be null for emptyRunfiles + PathFragment relativePath = (owningExecutable != null) + ? owningExecutable.getRootRelativePath() + : context.getPackageDirectory().getRelative(context.getLabel().getName()); String basename = relativePath.getBaseName(); PathFragment inputManifestPath = relativePath.replaceName(basename + ".runfiles_manifest"); return context.getDerivedArtifact(inputManifestPath, @@ -290,9 +332,12 @@ public final class RunfilesSupport { * from different places, e.g. different package paths, generated files, etc.) into a single tree, * so that programs can access them using the workspace-relative name. */ - private Artifact createRunfilesAction(ActionConstructionContext context, Runfiles runfiles) { + private static Artifact createRunfilesAction( + ActionConstructionContext context, + Runfiles runfiles, + boolean createSymlinks, + Artifact inputManifest) { // Compute the names of the runfiles directory and its MANIFEST file. - Artifact inputManifest = getRunfilesInputManifest(); context.getAnalysisEnvironment().registerAction( SourceManifestAction.forRunfiles( ManifestType.SOURCE_SYMLINKS, context.getActionOwner(), inputManifest, runfiles)); @@ -329,7 +374,8 @@ public final class RunfilesSupport { * @param runfiles the runfiles * @return the Artifact representing the file write action. */ - private Artifact createSourceManifest(ActionConstructionContext context, Runfiles runfiles) { + private static Artifact createSourceManifest( + ActionConstructionContext context, Runfiles runfiles, Artifact owningExecutable) { // Put the sources only manifest next to the MANIFEST file but call it SOURCES. PathFragment executablePath = owningExecutable.getRootRelativePath(); PathFragment sourcesManifestPath = executablePath.getParentDirectory().getChild( @@ -371,11 +417,8 @@ public final class RunfilesSupport { */ public static RunfilesSupport withExecutable( RuleContext ruleContext, Runfiles runfiles, Artifact executable) { - return new RunfilesSupport( - ruleContext, - executable, - runfiles, - computeArgs(ruleContext, CommandLine.EMPTY)); + return RunfilesSupport.create( + ruleContext, executable, runfiles, computeArgs(ruleContext, CommandLine.EMPTY)); } /** @@ -384,11 +427,8 @@ public final class RunfilesSupport { */ public static RunfilesSupport withExecutable( RuleContext ruleContext, Runfiles runfiles, Artifact executable, List<String> appendingArgs) { - return new RunfilesSupport( - ruleContext, - executable, - runfiles, - computeArgs(ruleContext, CommandLine.of(appendingArgs))); + return RunfilesSupport.create( + ruleContext, executable, runfiles, computeArgs(ruleContext, CommandLine.of(appendingArgs))); } /** @@ -397,11 +437,8 @@ public final class RunfilesSupport { */ public static RunfilesSupport withExecutable( RuleContext ruleContext, Runfiles runfiles, Artifact executable, CommandLine appendingArgs) { - return new RunfilesSupport( - ruleContext, - executable, - runfiles, - computeArgs(ruleContext, appendingArgs)); + return RunfilesSupport.create( + ruleContext, executable, runfiles, computeArgs(ruleContext, appendingArgs)); } private static CommandLine computeArgs( diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/CommandLine.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/CommandLine.java index 0e5617c042..fab69eb7cc 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/CommandLine.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/CommandLine.java @@ -21,17 +21,30 @@ import com.google.devtools.build.lib.actions.ActionKeyContext; import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander; import com.google.devtools.build.lib.actions.CommandLineExpansionException; import com.google.devtools.build.lib.collect.CollectionUtils; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.Strategy; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; import com.google.devtools.build.lib.util.Fingerprint; /** A representation of a list of arguments, often a command executed by {@link SpawnAction}. */ +@AutoCodec(strategy = Strategy.POLYMORPHIC) public abstract class CommandLine { - public static final CommandLine EMPTY = - new CommandLine() { - @Override - public Iterable<String> arguments() { - return ImmutableList.of(); - } - }; + public static final ObjectCodec<CommandLine> CODEC = new CommandLine_AutoCodec(); + + @AutoCodec + @VisibleForSerialization + static class EmptyCommandLine extends CommandLine { + public static final ObjectCodec<EmptyCommandLine> CODEC = + new CommandLine_EmptyCommandLine_AutoCodec(); + + @Override + public Iterable<String> arguments() throws CommandLineExpansionException { + return ImmutableList.of(); + } + } + + public static final CommandLine EMPTY = new EmptyCommandLine(); /** Returns the command line. */ public abstract Iterable<String> arguments() throws CommandLineExpansionException; @@ -56,15 +69,55 @@ public abstract class CommandLine { } } + @AutoCodec + @VisibleForSerialization + static class ArgumentCommandLine extends CommandLine { + public static final ObjectCodec<ArgumentCommandLine> CODEC = + new CommandLine_ArgumentCommandLine_AutoCodec(); + + private Iterable<String> args; + + ArgumentCommandLine(Iterable<String> args) { + this.args = args; + } + + @Override + public Iterable<String> arguments() throws CommandLineExpansionException { + return args; + } + } + /** Returns a {@link CommandLine} backed by a copy of the given list of arguments. */ public static CommandLine of(Iterable<String> arguments) { final Iterable<String> immutableArguments = CollectionUtils.makeImmutable(arguments); - return new CommandLine() { - @Override - public Iterable<String> arguments() { - return immutableArguments; - } - }; + return new ArgumentCommandLine(immutableArguments); + } + + @AutoCodec + @VisibleForSerialization + static class ConcatenatedCommandLine extends CommandLine { + public static final ObjectCodec<ConcatenatedCommandLine> CODEC = + new CommandLine_ConcatenatedCommandLine_AutoCodec(); + + private ImmutableList<String> executableArgs; + private CommandLine commandLine; + + @VisibleForSerialization + ConcatenatedCommandLine(ImmutableList<String> executableArgs, CommandLine commandLine) { + this.executableArgs = executableArgs; + this.commandLine = commandLine; + } + + @Override + public Iterable<String> arguments() throws CommandLineExpansionException { + return Iterables.concat(executableArgs, commandLine.arguments()); + } + + @Override + public Iterable<String> arguments(ArtifactExpander artifactExpander) + throws CommandLineExpansionException { + return Iterables.concat(executableArgs, commandLine.arguments(artifactExpander)); + } } /** @@ -76,18 +129,34 @@ public abstract class CommandLine { if (executableArgs.isEmpty()) { return commandLine; } - return new CommandLine() { - @Override - public Iterable<String> arguments() throws CommandLineExpansionException { - return Iterables.concat(executableArgs, commandLine.arguments()); - } - - @Override - public Iterable<String> arguments(ArtifactExpander artifactExpander) - throws CommandLineExpansionException { - return Iterables.concat(executableArgs, commandLine.arguments(artifactExpander)); - } - }; + return new ConcatenatedCommandLine(executableArgs, commandLine); + } + + @AutoCodec + @VisibleForSerialization + static class ReverseConcatenatedCommandLine extends CommandLine { + public static final ObjectCodec<ReverseConcatenatedCommandLine> CODEC = + new CommandLine_ReverseConcatenatedCommandLine_AutoCodec(); + + private ImmutableList<String> executableArgs; + private CommandLine commandLine; + + @VisibleForSerialization + ReverseConcatenatedCommandLine(ImmutableList<String> executableArgs, CommandLine commandLine) { + this.executableArgs = executableArgs; + this.commandLine = commandLine; + } + + @Override + public Iterable<String> arguments() throws CommandLineExpansionException { + return Iterables.concat(commandLine.arguments(), executableArgs); + } + + @Override + public Iterable<String> arguments(ArtifactExpander artifactExpander) + throws CommandLineExpansionException { + return Iterables.concat(commandLine.arguments(artifactExpander), executableArgs); + } } /** @@ -99,18 +168,7 @@ public abstract class CommandLine { if (args.isEmpty()) { return commandLine; } - return new CommandLine() { - @Override - public Iterable<String> arguments() throws CommandLineExpansionException { - return Iterables.concat(commandLine.arguments(), args); - } - - @Override - public Iterable<String> arguments(ArtifactExpander artifactExpander) - throws CommandLineExpansionException { - return Iterables.concat(commandLine.arguments(artifactExpander), args); - } - }; + return new ReverseConcatenatedCommandLine(args, commandLine); } /** |