Skip to content

Commit

Permalink
Expose C++ command lines in aspects
Browse files Browse the repository at this point in the history
Currently guarded by --experimental_action_args. With this flag aspects can access precise command lines used by C++ actions by calling their .args() method.

See 2b6a435 for more details.

RELNOTES: None.
PiperOrigin-RevId: 282540483
  • Loading branch information
hlopko authored and Copybara-Service committed Nov 26, 2019
1 parent 8f075d2 commit e7ce105
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 61 deletions.
Expand Up @@ -17,6 +17,7 @@
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.CommandLine;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.rules.cpp.CcCommon.CoptsFilter;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ExpansionException;
Expand Down Expand Up @@ -103,6 +104,20 @@ protected List<String> getArguments(
return commandLine;
}

/**
* Returns {@link CommandLine} instance that contains the exactly same command line as the {@link
* CppCompileAction} owning this {@link CompileCommandLine}.
*/
public CommandLine getFilteredFeatureConfigurationCommandLine() {
return new CommandLine() {

@Override
public Iterable<String> arguments() throws CommandLineExpansionException {
return ImmutableList.copyOf(getCompilerOptions(/* overwrittenVariables= */ null));
}
};
}

public List<String> getCompilerOptions(@Nullable CcToolchainVariables overwrittenVariables)
throws CommandLineExpansionException {
try {
Expand Down
Expand Up @@ -24,6 +24,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import com.google.common.io.ByteStreams;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.devtools.build.lib.actions.AbstractAction;
Expand All @@ -38,7 +39,9 @@
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactResolver;
import com.google.devtools.build.lib.actions.CommandAction;
import com.google.devtools.build.lib.actions.CommandLine;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.CommandLines.CommandLineAndParamFileInfo;
import com.google.devtools.build.lib.actions.CommandLines.ParamFileActionInput;
import com.google.devtools.build.lib.actions.EnvironmentalExecException;
import com.google.devtools.build.lib.actions.ExecException;
Expand All @@ -54,6 +57,7 @@
import com.google.devtools.build.lib.actions.extra.CppCompileInfo;
import com.google.devtools.build.lib.actions.extra.EnvironmentVariable;
import com.google.devtools.build.lib.actions.extra.ExtraActionInfo;
import com.google.devtools.build.lib.analysis.skylark.Args;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.collect.CollectionUtils;
import com.google.devtools.build.lib.collect.IterablesChain;
Expand All @@ -70,6 +74,10 @@
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.IncludeScanner.IncludeScanningHeaderData;
import com.google.devtools.build.lib.skyframe.ActionExecutionValue;
import com.google.devtools.build.lib.skylarkbuildapi.CommandLineArgsApi;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Sequence;
import com.google.devtools.build.lib.syntax.StarlarkList;
import com.google.devtools.build.lib.util.DependencySet;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.ShellEscaper;
Expand Down Expand Up @@ -839,6 +847,23 @@ public List<String> getArguments() throws CommandLineExpansionException {
return compileCommandLine.getArguments(paramFilePath, overwrittenVariables);
}

@Override
public Sequence<CommandLineArgsApi> getStarlarkArgs() throws EvalException {
ImmutableSet<Artifact> directoryInputs =
Streams.stream(getInputs())
.filter(artifact -> artifact.isDirectory())
.collect(ImmutableSet.toImmutableSet());

CommandLine commandLine = compileCommandLine.getFilteredFeatureConfigurationCommandLine();

CommandLineAndParamFileInfo commandLineAndParamFileInfo =
new CommandLineAndParamFileInfo(commandLine, /* paramFileInfo= */ null);

Args args = Args.forRegisteredAction(commandLineAndParamFileInfo, directoryInputs);

return StarlarkList.immutableCopyOf(ImmutableList.of(args));
}

public ParamFileActionInput getParamFileActionInput() {
return paramFileActionInput;
}
Expand Down
Expand Up @@ -23,6 +23,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Streams;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.devtools.build.lib.actions.AbstractAction;
import com.google.devtools.build.lib.actions.ActionContinuationOrResult;
Expand All @@ -36,6 +37,7 @@
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.actions.CommandAction;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.CommandLines.CommandLineAndParamFileInfo;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.actions.ExecutionInfoSpecifier;
import com.google.devtools.build.lib.actions.ExecutionRequirements;
Expand All @@ -48,12 +50,17 @@
import com.google.devtools.build.lib.actions.extra.ExtraActionInfo;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.skylark.Args;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.collect.CollectionUtils;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode;
import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkbuildapi.CommandLineArgsApi;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Sequence;
import com.google.devtools.build.lib.syntax.StarlarkList;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.ShellEscaper;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
Expand Down Expand Up @@ -257,6 +264,27 @@ public ImmutableMap<String, String> getExecutionInfo() {
return executionRequirements;
}

@Override
public Sequence<CommandLineArgsApi> getStarlarkArgs() throws EvalException {
ImmutableSet<Artifact> directoryInputs =
Streams.stream(getInputs())
.filter(artifact -> artifact.isDirectory())
.collect(ImmutableSet.toImmutableSet());

FeatureConfigurationCommandLine commandLine =
FeatureConfigurationCommandLine.from(
linkCommandLine.getFeatureConfiguration(),
linkCommandLine.getBuildVariables(),
linkCommandLine.getActionName());

CommandLineAndParamFileInfo commandLineAndParamFileInfo =
new CommandLineAndParamFileInfo(commandLine, /* paramFileInfo= */ null);

Args args = Args.forRegisteredAction(commandLineAndParamFileInfo, directoryInputs);

return StarlarkList.immutableCopyOf(ImmutableList.of(args));
}

@Override
public List<String> getArguments() throws CommandLineExpansionException {
return linkCommandLine.arguments();
Expand Down
@@ -0,0 +1,105 @@
// Copyright 2019 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.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.actions.CommandLine;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ExpansionException;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;

/**
* A representation of command line for C++ actions ({@link CppCompileAction}, {@link
* CppLinkAction}, {@link LtoBackendAction}...).
*
* <p>This class is an adapter from {@link FeatureConfiguration} and {@link CcToolchainVariables} to
* {@link CommandLine}. Using this we're able to pass C++ command lines to {@link
* com.google.devtools.build.lib.analysis.actions.SpawnAction} or to give access to C++ command
* lines to Starlark aspects.
*
* <p>See {@link CompileCommandLine#getArguments} for inline subclass of CommandLine that does all
* of this plus some more specifics for CppCompileAction.
*/
public class FeatureConfigurationCommandLine extends CommandLine {

private final FeatureConfiguration featureConfiguration;
private final CcToolchainVariables buildVariables;
private final String actionName;
private final boolean usePic;

/**
* Create a {@link CommandLine} instance from given {@link FeatureConfiguration} and {@link
* CcToolchainVariables}.
*/
public static FeatureConfigurationCommandLine from(
FeatureConfiguration featureConfiguration,
CcToolchainVariables ccToolchainVariables,
String actionName) {
return new FeatureConfigurationCommandLine(
featureConfiguration, ccToolchainVariables, actionName, /* usePic= */ false);
}

/**
* Do not use for new code.
*
* <p>TODO(hlopko): Refactor to remove the usePic field.
*
* @deprecated Only there for legacy/technical debt reasons for ThinLTO.
*/
@Deprecated
public static FeatureConfigurationCommandLine forLtoBackendAction(
FeatureConfiguration featureConfiguration,
CcToolchainVariables ccToolchainVariables,
boolean usePic) {
return new FeatureConfigurationCommandLine(
featureConfiguration, ccToolchainVariables, CppActionNames.LTO_BACKEND, usePic);
}

private FeatureConfigurationCommandLine(
FeatureConfiguration featureConfiguration,
CcToolchainVariables ccToolchainVariables,
String actionName,
boolean usePic) {
this.featureConfiguration = featureConfiguration;
this.buildVariables = ccToolchainVariables;
this.actionName = actionName;
this.usePic = usePic;
}
@Override
public Iterable<String> arguments() throws CommandLineExpansionException {
return arguments(/* artifactExpander= */ null);
}

@Override
public Iterable<String> arguments(ArtifactExpander artifactExpander)
throws CommandLineExpansionException {
ImmutableList.Builder<String> args = ImmutableList.builder();
try {
args.addAll(
featureConfiguration.getCommandLine(actionName, buildVariables, artifactExpander));
} catch (ExpansionException e) {
throw new CommandLineExpansionException(e.getMessage());
}
// If this is a PIC compile (set based on the CppConfiguration), the PIC
// option should be added after the rest of the command line so that it
// cannot be overridden. This is consistent with the ordering in the
// CppCompileAction's compiler options.
if (usePic) {
args.add("-fPIC");
}
return args.build();
}
}
Expand Up @@ -110,6 +110,10 @@ public FeatureConfiguration getFeatureConfiguration() {
return featureConfiguration;
}

public String getActionName() {
return actionName;
}

/** Returns the current type of link target set. */
public LinkTargetType getLinkTargetType() {
return linkTargetType;
Expand Down
Expand Up @@ -290,7 +290,8 @@ private void scheduleLtoBackendAction(
}

CommandLine ltoCommandLine =
new LtoBackendCommandLine(featureConfiguration, buildVariables, usePic);
FeatureConfigurationCommandLine.forLtoBackendAction(
featureConfiguration, buildVariables, usePic);
builder.addCommandLine(ltoCommandLine);

actionConstructionContext.registerAction(builder.build(actionConstructionContext));
Expand Down

This file was deleted.

0 comments on commit e7ce105

Please sign in to comment.