Propagate all experimental options to the exec configuration
Experimental flags that don't propagate to the exec configuration can create very surprising failure cases for both Bazel users and devs. Unless there is a valid reason to not propagate them, they should be.
This is now enforced by a test and existing flags have been cleaned up where possible. The test strategy is the same as for `incompatible_` flags.
Closes #23326.
PiperOrigin-RevId: 682447129
Change-Id: I18d6f70301388afbab34884a813de8ac86dae3b7
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/CoreOptions.java b/src/main/java/com/google/devtools/build/lib/analysis/config/CoreOptions.java
index 0efac83..b38ac59 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/CoreOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/CoreOptions.java
@@ -253,6 +253,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.EXECUTION_STRATEGY,
effectTags = {OptionEffectTag.EXECUTION},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If this option is enabled, filesets will treat all output artifacts as regular files. "
+ "They will not traverse directories or be sensitive to symlinks.")
@@ -488,6 +489,7 @@
name = "experimental_collect_code_coverage_for_generated_files",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
help =
"If specified, Bazel will also generate collect coverage information for generated"
@@ -518,6 +520,7 @@
name = "experimental_correct_runfiles_middleman_paths",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
help =
"If set, the path of runfiles middlemen represents the real path of the runfiles tree.")
@@ -949,6 +952,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"When set, select functions with no matching clause will return an empty value, instead"
+ " of failing. This is to help use cquery diagnose failures in select.")
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/TestConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/test/TestConfiguration.java
index 4c85180..0c6080b 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/test/TestConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/test/TestConfiguration.java
@@ -108,15 +108,14 @@
public List<Pair<String, Map<TestSize, Double>>> testResources;
@Option(
- name = "test_filter",
- allowMultiple = false,
- defaultValue = "null",
- documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
- effectTags = {OptionEffectTag.UNKNOWN},
- help =
- "Specifies a filter to forward to the test framework. Used to limit "
- + "the tests run. Note that this does not affect which targets are built."
- )
+ name = "test_filter",
+ allowMultiple = false,
+ defaultValue = "null",
+ documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ help =
+ "Specifies a filter to forward to the test framework. Used to limit "
+ + "the tests run. Note that this does not affect which targets are built.")
public String testFilter;
@Option(
@@ -130,20 +129,19 @@
public boolean testRunnerFailFast;
@Option(
- name = "cache_test_results",
- defaultValue = "auto",
- abbrev = 't', // it's useful to toggle this on/off quickly
- documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
- effectTags = {OptionEffectTag.UNKNOWN},
- help =
- "If set to 'auto', Bazel reruns a test if and only if: "
- + "(1) Bazel detects changes in the test or its dependencies, "
- + "(2) the test is marked as external, "
- + "(3) multiple test runs were requested with --runs_per_test, or"
- + "(4) the test previously failed. "
- + "If set to 'yes', Bazel caches all test results except for tests marked as "
- + "external. If set to 'no', Bazel does not cache any test results."
- )
+ name = "cache_test_results",
+ defaultValue = "auto",
+ abbrev = 't', // it's useful to toggle this on/off quickly
+ documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ help =
+ "If set to 'auto', Bazel reruns a test if and only if: "
+ + "(1) Bazel detects changes in the test or its dependencies, "
+ + "(2) the test is marked as external, "
+ + "(3) multiple test runs were requested with --runs_per_test, or"
+ + "(4) the test previously failed. "
+ + "If set to 'yes', Bazel caches all test results except for tests marked as "
+ + "external. If set to 'no', Bazel does not cache any test results.")
public TriState cacheTestResults;
@Deprecated
@@ -178,6 +176,7 @@
OptionEffectTag.LOADING_AND_ANALYSIS,
OptionEffectTag.LOSES_INCREMENTAL_STATE,
},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"When enabled, --trim_test_configuration will not trim the test configuration for rules"
+ " marked testonly=1. This is meant to reduce action conflict issues when non-test"
@@ -246,6 +245,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS, OptionEffectTag.LOADING_AND_ANALYSIS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If true, then Blaze will cancel concurrently running tests on the first successful "
+ "run. This is only useful in combination with --runs_per_test_detects_flakes.")
@@ -257,14 +257,13 @@
defaultValue = "@bazel_tools//tools/test:coverage_support",
documentationCategory = OptionDocumentationCategory.TOOLCHAIN,
effectTags = {
- OptionEffectTag.CHANGES_INPUTS,
- OptionEffectTag.AFFECTS_OUTPUTS,
- OptionEffectTag.LOADING_AND_ANALYSIS
+ OptionEffectTag.CHANGES_INPUTS,
+ OptionEffectTag.AFFECTS_OUTPUTS,
+ OptionEffectTag.LOADING_AND_ANALYSIS
},
help =
"Location of support files that are required on the inputs of every test action "
- + "that collects code coverage. Defaults to '//tools/test:coverage_support'."
- )
+ + "that collects code coverage. Defaults to '//tools/test:coverage_support'.")
public Label coverageSupport;
@Option(
@@ -272,6 +271,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS, OptionEffectTag.LOADING_AND_ANALYSIS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If true, then Bazel fetches the entire coverage data directory for each test during a "
+ "coverage run.")
@@ -293,6 +293,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.EXECUTION_STRATEGY,
effectTags = {OptionEffectTag.EXECUTION},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "If true, then Bazel will run coverage postprocessing for test in a new spawn.")
public boolean splitCoveragePostProcessing;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonConfiguration.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonConfiguration.java
index 8ab6738..611a638 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonConfiguration.java
@@ -31,6 +31,7 @@
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
+import com.google.devtools.common.options.OptionMetadataTag;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.annot.StarlarkMethod;
@@ -69,6 +70,7 @@
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If true, the roots of repositories in the runfiles tree are added to PYTHONPATH, so "
+ "that imports like `import mytoplevelpackage.package.module` are valid."
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java
index bb56ee1..fa3ddcc 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java
@@ -501,6 +501,7 @@
OptionEffectTag.AFFECTS_OUTPUTS,
OptionEffectTag.LOADING_AND_ANALYSIS,
},
+ metadataTags = OptionMetadataTag.EXPERIMENTAL,
help = "Enables resource shrinking for android_binary APKs that use ProGuard.")
public boolean useExperimentalAndroidResourceShrinking;
@@ -661,6 +662,7 @@
OptionEffectTag.LOADING_AND_ANALYSIS,
OptionEffectTag.LOSES_INCREMENTAL_STATE,
},
+ metadataTags = OptionMetadataTag.EXPERIMENTAL,
help = "The default value of the exports_manifest attribute on android_library.")
public boolean exportsManifestDefault;
@@ -669,6 +671,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"Omit AndroidResourcesInfo provider from android_binary rules."
+ " Propagating resources out to other binaries is usually unintentional.")
@@ -727,6 +730,7 @@
effectTags = {
OptionEffectTag.CHANGES_INPUTS,
},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "If enabled, R Jars will be filtered from the test apk built by android_test.")
public boolean filterRJarsFromAndroidTest;
@@ -739,6 +743,7 @@
OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION,
OptionEffectTag.ACTION_COMMAND_LINES
},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If enabled, one version enforcement for android_test uses the binary_under_test's "
+ "transitive classpath, otherwise it uses the deploy jar")
@@ -751,6 +756,7 @@
effectTags = {
OptionEffectTag.EXECUTION,
},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "Enable persistent aar extractor by using workers.")
public boolean persistentAarExtractor;
@@ -929,6 +935,7 @@
effectTags = {
OptionEffectTag.CHANGES_INPUTS,
},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If enabled and the test instruments an application, all the R classes from the test's "
+ "deploy jar will be removed.")
@@ -941,6 +948,7 @@
effectTags = {
OptionEffectTag.CHANGES_INPUTS,
},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If enabled and the android_test defines a binary_under_test, the class filterering "
+ "applied to the test's deploy jar will always filter duplicate classes based "
@@ -952,6 +960,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.BUILD_TIME_OPTIMIZATION,
effectTags = {OptionEffectTag.ACTION_COMMAND_LINES},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"Filter the ProGuard ProgramJar to remove any classes also present in the LibraryJar.")
public boolean filterLibraryJarWithProgramJar;
@@ -961,6 +970,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.CHANGES_INPUTS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "Use R.txt from the merging action, instead of from the validation action.")
public boolean useRTxtFromMergedResources;
@@ -999,6 +1009,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"Disables manifest merging when an android_binary has instruments set (i.e. is used "
+ "for instrumentation testing).")
@@ -1009,6 +1020,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.CHANGES_INPUTS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"Get Java resources from _proguard.jar instead of _deploy.jar in android_binary when "
+ "bundling the final APK.")
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
index d2b88e4..e89f64e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
@@ -39,6 +39,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.NO_OP},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"No-op. Kept here for backwards compatibility. This field will be removed in a "
+ "future release.")
@@ -46,14 +47,13 @@
public boolean objcProviderFromLinked;
@Option(
- name = "xcode_version",
- defaultValue = "null",
- documentationCategory = OptionDocumentationCategory.TOOLCHAIN,
- effectTags = {OptionEffectTag.LOSES_INCREMENTAL_STATE},
- help =
- "If specified, uses Xcode of the given version for relevant build actions. "
- + "If unspecified, uses the executor default version of Xcode."
- )
+ name = "xcode_version",
+ defaultValue = "null",
+ documentationCategory = OptionDocumentationCategory.TOOLCHAIN,
+ effectTags = {OptionEffectTag.LOSES_INCREMENTAL_STATE},
+ help =
+ "If specified, uses Xcode of the given version for relevant build actions. "
+ + "If unspecified, uses the executor default version of Xcode.")
public String xcodeVersion;
@Option(
@@ -160,6 +160,7 @@
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.TOOLCHAIN,
effectTags = {OptionEffectTag.LOSES_INCREMENTAL_STATE},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If true, use the most recent Xcode that is available both locally and remotely. If"
+ " false, or if there are no mutual available versions, use the local Xcode version"
@@ -192,15 +193,14 @@
public static final String DEFAULT_CATALYST_CPU = "x86_64";
@Option(
- name = "apple_crosstool_top",
- defaultValue = "@bazel_tools//tools/cpp:toolchain",
- converter = LabelConverter.class,
- documentationCategory = OptionDocumentationCategory.TOOLCHAIN,
- effectTags = {OptionEffectTag.LOSES_INCREMENTAL_STATE, OptionEffectTag.CHANGES_INPUTS},
- help =
- "The label of the crosstool package to be used in Apple and Objc rules and their"
- + " dependencies."
- )
+ name = "apple_crosstool_top",
+ defaultValue = "@bazel_tools//tools/cpp:toolchain",
+ converter = LabelConverter.class,
+ documentationCategory = OptionDocumentationCategory.TOOLCHAIN,
+ effectTags = {OptionEffectTag.LOSES_INCREMENTAL_STATE, OptionEffectTag.CHANGES_INPUTS},
+ help =
+ "The label of the crosstool package to be used in Apple and Objc rules and their"
+ + " dependencies.")
public Label appleCrosstoolTop;
@Option(
@@ -215,14 +215,13 @@
public String applePlatformType;
@Option(
- name = "apple_split_cpu",
- defaultValue = "",
- documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
- effectTags = {OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION},
- help =
- "Don't set this value from the command line - it is derived from other flags and "
- + "configuration transitions derived from rule attributes"
- )
+ name = "apple_split_cpu",
+ defaultValue = "",
+ documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+ effectTags = {OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION},
+ help =
+ "Don't set this value from the command line - it is derived from other flags and "
+ + "configuration transitions derived from rule attributes")
public String appleSplitCpu;
// This option exists because two configurations are not allowed to have the same cache key
@@ -323,6 +322,7 @@
OptionEffectTag.LOADING_AND_ANALYSIS,
OptionEffectTag.EXECUTION
},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If set, add a \"requires-xcode:{version}\" execution requirement to every Xcode action."
+ " If the Xcode version has a hyphenated label, also add a"
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
index 2f89958..505724a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
@@ -47,7 +47,7 @@
} else if (!input.equals("no")) { // "no" is another special case that disables all modes.
CompilationMode.Converter modeConverter = new CompilationMode.Converter();
for (String mode : Splitter.on(',').split(input)) {
- modes.add(modeConverter.convert(mode, /*conversionContext=*/ null));
+ modes.add(modeConverter.convert(mode, /* conversionContext= */ null));
}
}
return modes.build().asList();
@@ -962,6 +962,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS, OptionEffectTag.LOADING_AND_ANALYSIS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "If true, coverage for clang will generate an LCOV report.")
public boolean generateLlvmLcov;
@@ -1008,6 +1009,7 @@
OptionEffectTag.EXECUTION,
OptionEffectTag.CHANGES_INPUTS
},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"Whether to narrow inputs to C/C++ compilation by parsing #include lines from input"
+ " files. This can improve performance and incrementality by decreasing the size of"
diff --git a/src/main/java/com/google/devtools/build/lib/rules/genquery/GenQueryConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/genquery/GenQueryConfiguration.java
index ce0c45f..b8d1ac8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/genquery/GenQueryConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/genquery/GenQueryConfiguration.java
@@ -21,6 +21,7 @@
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
+import com.google.devtools.common.options.OptionMetadataTag;
/** {@link Fragment} for {@link GenQuery}. */
@RequiresOptions(options = {GenQueryConfiguration.GenQueryOptions.class})
@@ -33,6 +34,7 @@
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If true, genquery loads its scope's transitive closure directly instead of by using "
+ "'TransitiveTargetValue' Skyframe work.")
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
index 449fcd2..5dbacd2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
@@ -53,6 +53,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"If enabled, disallow legacy Java toolchain flags (--javabase, --host_javabase,"
+ " --java_toolchain, --host_java_toolchain) and require the use of --platforms"
@@ -305,6 +306,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "Do not use.")
public boolean runLocalJavaOptimizations;
@@ -423,6 +425,7 @@
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help =
"Flag to help transition away from adding test support libraries to the compile-time"
+ " deps of Java test rules.")
@@ -433,6 +436,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "Whether to validate java_* sources.")
public boolean runAndroidLint;
@@ -441,6 +445,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "No-op, kept only for backwards compatibility")
public boolean limitAndroidLintToAndroidCompatible;
@@ -480,6 +485,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "No-op, kept only for backwards compatibility")
public boolean experimentalJavaHeaderInputPruning;
@@ -488,6 +494,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "If enabled, turbine is used for all annotation processing")
public boolean experimentalTurbineAnnotationProcessing;
@@ -565,6 +572,7 @@
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "Enable experimental jspecify integration.")
public boolean experimentalEnableJspecify;
@@ -573,6 +581,7 @@
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
help = "DO NOT USE")
public boolean autoCreateDeployJarForJavaTests;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java
index a96c6d5..8bc89c6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java
@@ -66,21 +66,21 @@
public Label deadCodeReport;
@Option(
- name = "experimental_j2objc_header_map",
- defaultValue = "true",
- documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
- effectTags = {OptionEffectTag.UNKNOWN},
- help = "Whether to generate J2ObjC header map in parallel of J2ObjC transpilation."
- )
+ name = "experimental_j2objc_header_map",
+ defaultValue = "true",
+ documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
+ help = "Whether to generate J2ObjC header map in parallel of J2ObjC transpilation.")
public boolean experimentalJ2ObjcHeaderMap;
@Option(
- name = "experimental_j2objc_shorter_header_path",
- defaultValue = "false",
- documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
- effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
- help = "Whether to generate with shorter header path (uses \"_ios\" instead of \"_j2objc\")."
- )
+ name = "experimental_j2objc_shorter_header_path",
+ defaultValue = "false",
+ documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+ effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
+ help = "Whether to generate with shorter header path (uses \"_ios\" instead of \"_j2objc\").")
public boolean experimentalShorterHeaderPath;
@Option(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PythonOptions.java b/src/main/java/com/google/devtools/build/lib/rules/python/PythonOptions.java
index 851ea6f..d82dcd4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/python/PythonOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/python/PythonOptions.java
@@ -263,6 +263,7 @@
name = "experimental_py_binaries_include_label",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
help = "py_binary targets include their label even when stamping is disabled.")
public boolean includeLabelInPyBinariesLinkstamp;
diff --git a/src/main/starlark/builtins_bzl/common/builtin_exec_platforms.bzl b/src/main/starlark/builtins_bzl/common/builtin_exec_platforms.bzl
index 08e1546..e17ef29 100644
--- a/src/main/starlark/builtins_bzl/common/builtin_exec_platforms.bzl
+++ b/src/main/starlark/builtins_bzl/common/builtin_exec_platforms.bzl
@@ -129,6 +129,28 @@
"//command_line_option:internal_persistent_busybox_tools",
"//command_line_option:internal_persistent_multiplex_busybox_tools",
"//command_line_option:incompatible_disable_native_android_rules",
+ "//command_line_option:android_databinding_use_androidx",
+ "//command_line_option:android_databinding_use_v3_4_args",
+ "//command_line_option:break_build_on_parallel_dex2oat_failure",
+ "//command_line_option:experimental_always_filter_duplicate_classes_from_android_test",
+ "//command_line_option:experimental_android_compress_java_resources",
+ "//command_line_option:experimental_android_databinding_v2",
+ "//command_line_option:experimental_android_library_exports_manifest_default",
+ "//command_line_option:experimental_android_resource_cycle_shrinking",
+ "//command_line_option:experimental_android_resource_name_obfuscation",
+ "//command_line_option:experimental_android_resource_path_shortening",
+ "//command_line_option:experimental_android_resource_shrinking",
+ "//command_line_option:experimental_android_rewrite_dexes_with_rex",
+ "//command_line_option:experimental_android_use_parallel_dex2oat",
+ "//command_line_option:experimental_disable_instrumentation_manifest_merge",
+ "//command_line_option:experimental_filter_library_jar_with_program_jar",
+ "//command_line_option:experimental_filter_r_jars_from_android_test",
+ "//command_line_option:experimental_get_android_java_resources_from_optimized_jar",
+ "//command_line_option:experimental_omit_resources_info_provider_from_android_binary",
+ "//command_line_option:experimental_persistent_aar_extractor",
+ "//command_line_option:experimental_remove_r_classes_from_instrumentation_test_jar",
+ "//command_line_option:experimental_use_rtxt_from_merged_resources",
+ "//command_line_option:experimental_objc_provider_from_linked",
],
outputs = [
"//command_line_option:android hwasan",
@@ -214,6 +236,7 @@
bazel_fragments["CoreOptions"] = fragment(
propagate = [
+ "//command_line_option:experimental_correct_runfiles_middleman_paths",
"//command_line_option:experimental_output_directory_naming_scheme",
"//command_line_option:host_compilation_mode",
"//command_line_option:experimental_exec_configuration_distinguisher",
@@ -247,7 +270,12 @@
"//command_line_option:experimental_exclude_defines_from_exec_config",
"//command_line_option:experimental_exclude_starlark_flags_from_exec_config",
"//command_line_option:experimental_propagate_custom_flag",
+ "//command_line_option:allow_analysis_failures",
+ "//command_line_option:experimental_collect_code_coverage_for_generated_files",
+ "//command_line_option:experimental_extended_sanity_checks",
"//command_line_option:experimental_inprocess_symlink_creation",
+ "//command_line_option:experimental_throttle_action_cache_check",
+ "//command_line_option:experimental_use_platforms_in_output_dir_legacy_heuristic",
],
inputs = ["//command_line_option:features"],
outputs = [
@@ -295,6 +323,12 @@
"//command_line_option:incompatible_use_cpp_compile_header_mnemonic",
"//command_line_option:experimental_starlark_cc_import",
"//command_line_option:incompatible_macos_set_install_name",
+ "//command_line_option:experimental_cpp_compile_resource_estimation",
+ "//command_line_option:experimental_generate_llvm_lcov",
+ "//command_line_option:experimental_omitfp",
+ "//command_line_option:experimental_platform_cc_test",
+ "//command_line_option:experimental_save_feature_state",
+ "//command_line_option:experimental_use_llvm_covmap",
],
outputs = [
"//command_line_option:crosstool_top",
@@ -320,12 +354,18 @@
},
)
-# GenQueryConfiguration$GenQueryOptions: no getExec()
+bazel_fragments["GenQueryConfiguration$GenQueryOptions"] = fragment(
+ propagate = [
+ "//command_line_option:experimental_skip_ttvs_for_genquery",
+ ],
+)
bazel_fragments["J2ObjcCommandLineOptions"] = fragment(
propagate = [
"//command_line_option:j2objc_translation_flags",
"//command_line_option:incompatible_j2objc_library_migration",
+ "//command_line_option:experimental_j2objc_header_map",
+ "//command_line_option:experimental_j2objc_shorter_header_path",
],
)
@@ -372,6 +412,12 @@
"//command_line_option:incompatible_multi_release_deploy_jars",
"//command_line_option:incompatible_disallow_java_import_exports",
"//command_line_option:incompatible_disallow_java_import_empty_jars",
+ "//command_line_option:experimental_disallow_legacy_java_toolchain_flags",
+ "//command_line_option:experimental_enable_jspecify",
+ "//command_line_option:experimental_java_header_input_pruning",
+ "//command_line_option:experimental_java_test_auto_create_deploy_jar",
+ "//command_line_option:experimental_limit_android_lint_to_android_constrained_java",
+ "//command_line_option:experimental_run_android_lint_on_java_rules",
],
inputs = [
"//command_line_option:host_jvmopt",
@@ -435,18 +481,19 @@
# Could move these toolchain configuring flags to toolchain definitions?
# And not make them flags. Must each one toggle independently of the others?
propagate = [
- "//command_line_option:incompatible_py3_is_default",
- "//command_line_option:incompatible_py2_outputs_are_suffixed",
"//command_line_option:build_python_zip",
- "//command_line_option:incompatible_use_python_toolchains",
+ "//command_line_option:experimental_py_binaries_include_label",
+ "//command_line_option:host_force_python",
"//command_line_option:incompatible_allow_python_version_transitions",
"//command_line_option:incompatible_default_to_explicit_init_py",
"//command_line_option:incompatible_disallow_legacy_py_provider",
- "//command_line_option:incompatible_remove_old_python_version_api",
+ "//command_line_option:incompatible_py2_outputs_are_suffixed",
+ "//command_line_option:incompatible_py3_is_default",
"//command_line_option:incompatible_python_disable_py2",
- "//command_line_option:python_native_rules_allowlist",
"//command_line_option:incompatible_python_disallow_native_rules",
- "//command_line_option:host_force_python",
+ "//command_line_option:incompatible_remove_old_python_version_api",
+ "//command_line_option:incompatible_use_python_toolchains",
+ "//command_line_option:python_native_rules_allowlist",
],
outputs = [
"//command_line_option:python_version",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/config/ExecutionTransitionFactoryTest.java b/src/test/java/com/google/devtools/build/lib/analysis/config/ExecutionTransitionFactoryTest.java
index 953f043..5f6973c 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/config/ExecutionTransitionFactoryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/config/ExecutionTransitionFactoryTest.java
@@ -31,6 +31,7 @@
import com.google.devtools.common.options.OptionMetadataTag;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
+import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -229,13 +230,13 @@
.filter(
// Skipping this explicitly because it is a no-op but can't be removed yet.
o -> !o.getKey().equals("incompatible_enable_android_toolchain_resolution"))
- .collect(toImmutableMap(k -> k.getKey(), v -> v.getValue()));
+ .collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
// Verify all "--incompatible_*" options also have the INCOMPATIBLE_CHANGE metadata tag.
ImmutableList<String> missingMetadataTagOptions =
- incompatibleOptions.entrySet().stream()
- .filter(o -> !o.getValue().hasOptionMetadataTag(OptionMetadataTag.INCOMPATIBLE_CHANGE))
- .map(o -> "--" + o.getValue().getDefinition().getOptionName())
+ incompatibleOptions.values().stream()
+ .filter(o -> !o.hasOptionMetadataTag(OptionMetadataTag.INCOMPATIBLE_CHANGE))
+ .map(o -> "--" + o.getDefinition().getOptionName())
.collect(toImmutableList());
assertThat(missingMetadataTagOptions).isEmpty();
@@ -258,8 +259,7 @@
new StoredEventHandler());
// Find which incompatible options are different in the exec config (shouldn't be any).
- ImmutableList.Builder<ChangedIncompatibleFlag> unpreservedOptions =
- new ImmutableList.Builder<>();
+ ImmutableList.Builder<ChangedFlag> unpreservedOptions = new ImmutableList.Builder<>();
for (OptionInfo incompatibleOption : incompatibleOptions.values()) {
Class<? extends FragmentOptions> optionClass = incompatibleOption.getOptionClass();
boolean execValue =
@@ -268,7 +268,7 @@
incompatibleOption.getDefinition().getBooleanValue(flipped.get(optionClass));
if (execValue != flippedValue) {
unpreservedOptions.add(
- new ChangedIncompatibleFlag(
+ new ChangedFlag(
incompatibleOption.getOptionClass().getName(),
incompatibleOption.getDefinition().getOptionName(),
flippedValue,
@@ -279,10 +279,80 @@
assertThat(unpreservedOptions.build()).isEmpty();
}
- /** Store details of incompatible flags that have changed values unexpectedly. */
- private record ChangedIncompatibleFlag(
+ /** Store details of flags that have changed values unexpectedly. */
+ private record ChangedFlag(
String fragment, String flag, Object expectedValue, Object foundValue) {}
+ /** Checks all experimental options propagate to the exec configuration. */
+ @Test
+ public void experimentalOptionsPreservedInExec() throws Exception {
+ BuildOptions defaultOptions =
+ BuildOptions.getDefaultBuildOptionsForFragments(
+ targetConfig.getOptions().getFragmentClasses());
+ ImmutableMap<String, OptionInfo> optionInfoMap = OptionInfo.buildMapFrom(defaultOptions);
+
+ // Find all options with the EXPERIMENTAL metadata tag or that start with "--experimental_".
+ ImmutableMap<String, OptionInfo> experimentalOptions =
+ optionInfoMap.entrySet().stream()
+ .filter(
+ o ->
+ o.getKey().startsWith("experimental_")
+ || o.getValue().hasOptionMetadataTag(OptionMetadataTag.EXPERIMENTAL))
+ .filter(o -> o.getValue().getDefinition().getType().isAssignableFrom(boolean.class))
+ .filter(o -> !o.getValue().getDefinition().isDeprecated())
+ .filter(
+ // Skipping this explicitly as propagating it causes a cycle when compiling the
+ // optimizer itself.
+ o -> !o.getKey().equals("experimental_local_java_optimizations"))
+ .collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ // Verify all "--experimental_*" options also have the EXPERIMENTAL metadata tag.
+ ImmutableList<String> missingMetadataTagOptions =
+ experimentalOptions.values().stream()
+ .filter(o -> !o.hasOptionMetadataTag(OptionMetadataTag.EXPERIMENTAL))
+ .map(o -> "--" + o.getDefinition().getOptionName())
+ .collect(toImmutableList());
+ assertThat(missingMetadataTagOptions).isEmpty();
+
+ // Flip all experimental (boolean) options to their non-default value.
+ BuildOptions flipped = defaultOptions.clone(); // To be flipped by below logic.
+ for (OptionInfo option : experimentalOptions.values()) {
+ FragmentOptions fragment = flipped.get(option.getOptionClass());
+ boolean value = option.getDefinition().getBooleanValue(fragment);
+ option.getDefinition().setValue(fragment, !value);
+ }
+
+ // Fix the details of the exec transition so that the check passes.
+ flipped.get(CoreOptions.class).starlarkExecConfig =
+ targetConfig.getOptions().get(CoreOptions.class).starlarkExecConfig;
+
+ PatchTransition execTransition = getExecTransition(EXECUTION_PLATFORM);
+ BuildOptions execOptions =
+ execTransition.patch(
+ new BuildOptionsView(flipped, execTransition.requiresOptionFragments()),
+ new StoredEventHandler());
+
+ // Find which experimental options are different in the exec config (shouldn't be any).
+ ImmutableList.Builder<ChangedFlag> unpreservedOptions = new ImmutableList.Builder<>();
+ for (OptionInfo experimentalOption : experimentalOptions.values()) {
+ Class<? extends FragmentOptions> optionClass = experimentalOption.getOptionClass();
+ boolean execValue =
+ experimentalOption.getDefinition().getBooleanValue(execOptions.get(optionClass));
+ boolean flippedValue =
+ experimentalOption.getDefinition().getBooleanValue(flipped.get(optionClass));
+ if (execValue != flippedValue) {
+ unpreservedOptions.add(
+ new ChangedFlag(
+ experimentalOption.getOptionClass().getName(),
+ experimentalOption.getDefinition().getOptionName(),
+ flippedValue,
+ execValue));
+ }
+ }
+
+ assertThat(unpreservedOptions.build()).isEmpty();
+ }
+
@Test
public void platformInOutputPathWorksInExecMode() throws Exception {
scratch.file(