Add py2-bin functionality, and experimental flag to gate it
IMPORTANT: This flag is not intended to be supported long term, or to be turned on by default in Bazel.
This adds --experimental_create_py2_bin_symlink. When enabled, a <prefix>-py2-bin symlink will be created that mirrors the usual <prefix>-bin symlink, except that it points to a corresponding PY2 output root. When <prefix>-bin is already PY2 (e.g. --python_version=PY2, or if --incompatible_py3_is_default is not turned on, or --use_top_level_targets_for_symlinks is enabled and the top-level target is PY2), the two symlinks have the same destination.
BUILD files:
- Add dependencies on Python rules, since -py2-bin is naturally Python-specific.
BuildRequestOptions:
- Add the flag, clarify unrelated doc.
ExecutionTool:
- Add helper to obtain config from options using the executor. Turns out we have a myriad of ways to get configurations, at different levels of abstraction over the configuration machinery and with different levels of skyframe entanglement. Since we're doing a transition to get the new config, we don't have a BuildConfigurationValue.Key handy and instead have to use a different API. Pass along this helper as a callback to the symlink utils class.
OutputDirectoryLinksUtils:
- Add ConfigGroup, a value class to hold a single config for which we want to generate symlinks, along with its derived configs (here, the py2 config). This encapsulates the (minimal) Python-specific logic.
- Add Py2BinSymlink.
ConvenienceSymlinkTest:
- Test that the flag controls availability of the symlink, that it may or may not point to the same place as -bin, and that even when -bin can't be created because you're building both PY2 and PY3 targets, you can still use -py2-bin. We implement this using a mock Python rule that uses the real Python transition (including its baggage of requiring a dummy default_python_version attr).
ConfigurationResolver:
- Fix typo that briefly confused me.
Note that this machinery can be used to enable other symlinks that point to other -bin-like configs in the future -- not that we necessarily want to do that.
RELNOTES: None
PiperOrigin-RevId: 282410753
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
index f481300..580d4c6 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
@@ -45,6 +45,8 @@
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
import com.google.devtools.build.lib.analysis.actions.SymlinkTreeActionContext;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.config.BuildOptions;
+import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.buildtool.buildevent.ExecRootPreparedEvent;
import com.google.devtools.build.lib.buildtool.buildevent.ExecutionPhaseCompleteEvent;
import com.google.devtools.build.lib.buildtool.buildevent.ExecutionStartingEvent;
@@ -96,6 +98,7 @@
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.annotation.Nullable;
/**
* This class manages the execution phase. The entry point is {@link #executeBuild}.
@@ -444,6 +447,26 @@
}
/**
+ * Obtains the {@link BuildConfiguration} for a given {@link BuildOptions} for the purpose of
+ * symlink creation.
+ *
+ * <p>In the event of a {@link InvalidConfigurationException}, a warning is emitted and null is
+ * returned.
+ */
+ @Nullable
+ private static BuildConfiguration getConfiguration(
+ SkyframeExecutor executor, Reporter reporter, BuildOptions options) {
+ try {
+ return executor.getConfiguration(reporter, options, /*keepGoing=*/ false);
+ } catch (InvalidConfigurationException e) {
+ reporter.handle(
+ Event.warn(
+ "Couldn't get configuration for convenience symlink creation: " + e.getMessage()));
+ return null;
+ }
+ }
+
+ /**
* Creates convenience symlinks based on the target configurations.
*
* <p>Exactly what target configurations we consider depends on the value of {@code
@@ -484,9 +507,11 @@
env.getDirectories().getOutputPath(workspaceName),
getReporter(),
targetConfigurations,
+ options -> getConfiguration(executor, reporter, options),
buildRequestOptions.getSymlinkPrefix(productName),
productName,
- !buildRequestOptions.incompatibleSkipGenfilesSymlink);
+ !buildRequestOptions.incompatibleSkipGenfilesSymlink,
+ buildRequestOptions.experimentalCreatePy2BinSymlink);
}
}