Also move default_compile_flags to the top of the crosstool
Currently we move legacy_compile_flags to the top of the crosstool, and the same behavior is needed for migrated crosstools in case of default_compile_flags.
https://github.com/bazelbuild/bazel/issues/6861
https://github.com/bazelbuild/bazel/issues/5883
RELNOTES: None.
PiperOrigin-RevId: 229339668
diff --git a/site/docs/crosstool-reference.md b/site/docs/crosstool-reference.md
index 59e60ed..5ae1cd0 100644
--- a/site/docs/crosstool-reference.md
+++ b/site/docs/crosstool-reference.md
@@ -1043,4 +1043,75 @@
be enabled, `--force_pic` cannot be used.
</td>
</tr>
+ <tr>
+ <td>
+ <strong><code>static_linking_mode | dynamic_linking_mode</code></strong>
+ </td>
+ <td>Enabled by default based on linking mode.</td>
+ </tr>
+ <tr>
+ <td><strong><code>no_legacy_features</code></strong>
+ </td>
+ <td>
+ Prevents Bazel from adding legacy features to
+ the CROSSTOOL configuration when present. See the complete list of
+ features below.
+ </td>
+ </tr>
</table>
+
+#### Legacy features patching logic
+
+<p>
+ Bazel does following changes to the features and their order to stay backwards
+ compatible:
+
+ <ul>
+ <li>Moves <code>legacy_compile_flags</code> feature to the top of the toolchain</li>
+ <li>Moves <code>default_compile_flags</code> feature to the top of the toolchain</li>
+ <li>Adds <code>dependency_file</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>pic</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>per_object_debug_info</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>preprocessor_defines</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>includes</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>include_paths</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>fdo_instrument</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>fdo_optimize</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>fdo_prefetch_hints</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>autofdo</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>build_interface_libraries</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>dynamic_library_linker_tool</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>symbol_counts</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>shared_flag</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>linkstamps</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>output_execpath_flags</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>runtime_library_search_directories</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>library_search_directories</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>archiver_flags</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>libraries_to_link</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>force_pic_flags</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>user_link_flags</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>legacy_link_flags</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>static_libgcc</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>fission_support</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>strip_debug_symbols</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>coverage</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>llvm_coverage_map_format</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>gcc_coverage_map_format</code> (if not present) feature to the top of the toolchain</li>
+ <li>Adds <code>fully_static_link</code> (if not present) feature to the bottom of the toolchain</li>
+ <li>Adds <code>user_compile_flags</code> (if not present) feature to the bottom of the toolchain</li>
+ <li>Adds <code>sysroot</code> (if not present) feature to the bottom of the toolchain</li>
+ <li>Adds <code>unfiltered_compile_flags</code> (if not present) feature to the bottom of the toolchain</li>
+ <li>Adds <code>linker_param_file</code> (if not present) feature to the bottom of the toolchain</li>
+ <li>Adds <code>compiler_input_flags</code> (if not present) feature to the bottom of the toolchain</li>
+ <li>Adds <code>compiler_output_flags</code> (if not present) feature to the bottom of the toolchain</li>
+ </ul>
+</p>
+
+This is a long list of features. The plan is to get rid of them once
+[Crosstool in Starlark](https://github.com/bazelbuild/bazel/issues/5380) is
+done. For the curious reader see the implementation in
+[CppActionConfigs](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java?q=cppactionconfigs&ss=bazel),
+and for production toolchains consider adding `no_legacy_features` to make
+the toolchain more standalone.
+
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index 717cd0f..301d3d7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -887,11 +887,24 @@
// compile command line. 'legacy_compile_flags' feature contains all these flags, and so it
// needs to appear before other features from {@link CppActionConfigs}.
if (featureNames.contains(CppRuleClasses.LEGACY_COMPILE_FLAGS)) {
- legacyFeaturesBuilder.add(
+ Feature legacyCompileFlags =
featureList.stream()
.filter(feature -> feature.getName().equals(CppRuleClasses.LEGACY_COMPILE_FLAGS))
.findFirst()
- .get());
+ .get();
+ if (legacyCompileFlags != null) {
+ legacyFeaturesBuilder.add(legacyCompileFlags);
+ }
+ }
+ if (featureNames.contains(CppRuleClasses.DEFAULT_COMPILE_FLAGS)) {
+ Feature defaultCompileFlags =
+ featureList.stream()
+ .filter(feature -> feature.getName().equals(CppRuleClasses.DEFAULT_COMPILE_FLAGS))
+ .findFirst()
+ .get();
+ if (defaultCompileFlags != null) {
+ legacyFeaturesBuilder.add(defaultCompileFlags);
+ }
}
CppPlatform platform = targetLibc.equals("macos") ? CppPlatform.MAC : CppPlatform.LINUX;
@@ -907,6 +920,7 @@
legacyFeaturesBuilder.addAll(
featureList.stream()
.filter(feature -> !feature.getName().equals(CppRuleClasses.LEGACY_COMPILE_FLAGS))
+ .filter(feature -> !feature.getName().equals(CppRuleClasses.DEFAULT_COMPILE_FLAGS))
.collect(ImmutableList.toImmutableList()));
for (CToolchain.Feature feature :
CppActionConfigs.getFeaturesToAppearLastInFeaturesList(featureNames)) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
index d806d6b..ee53df9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
@@ -224,6 +224,13 @@
public static final String LEGACY_COMPILE_FLAGS = "legacy_compile_flags";
/**
+ * A string constant for the default_compile_flags feature. If this feature is present in the
+ * toolchain, and the toolchain doesn't specify no_legacy_features, bazel will move
+ * default_compile_flags before other features from {@link CppActionConfigs}.
+ */
+ public static final String DEFAULT_COMPILE_FLAGS = "default_compile_flags";
+
+ /**
* A string constant for the feature that makes us build per-object debug info files.
*/
public static final String PER_OBJECT_DEBUG_INFO = "per_object_debug_info";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppToolchainInfo.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppToolchainInfo.java
index 226e46a..c19831d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppToolchainInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppToolchainInfo.java
@@ -405,22 +405,32 @@
}
}
- // TODO(b/30109612): Remove fragile legacyCompileFlags shuffle once there are no legacy
- // crosstools.
- // Existing projects depend on flags from legacy toolchain fields appearing first on the
- // compile command line. 'legacy_compile_flags' feature contains all these flags, and so it
- // needs to appear before other features from {@link CppActionConfigs}.
- CToolchain.Feature legacyCompileFlagsFeature =
- toolchain
- .getFeatureList()
- .stream()
+ // TODO(b/30109612): Remove fragile legacyCompileFlags shuffle once there are no legacy
+ // crosstools.
+ // Existing projects depend on flags from legacy toolchain fields appearing first on the
+ // compile command line. 'legacy_compile_flags' feature contains all these flags, and so it
+ // needs to appear before other features from {@link CppActionConfigs}.
+ if (featureNames.contains(CppRuleClasses.LEGACY_COMPILE_FLAGS)) {
+ CToolchain.Feature legacyCompileFlags =
+ toolchain.getFeatureList().stream()
.filter(feature -> feature.getName().equals(CppRuleClasses.LEGACY_COMPILE_FLAGS))
.findFirst()
- .orElse(null);
- if (legacyCompileFlagsFeature != null) {
- toolchainBuilder.addFeature(legacyCompileFlagsFeature);
- toolchain = removeLegacyCompileFlagsFeatureFromToolchain(toolchain);
+ .get();
+ if (legacyCompileFlags != null) {
+ toolchainBuilder.addFeature(legacyCompileFlags);
}
+ }
+ if (featureNames.contains(CppRuleClasses.DEFAULT_COMPILE_FLAGS)) {
+ CToolchain.Feature defaultCompileFlags =
+ toolchain.getFeatureList().stream()
+ .filter(feature -> feature.getName().equals(CppRuleClasses.DEFAULT_COMPILE_FLAGS))
+ .findFirst()
+ .get();
+ if (defaultCompileFlags != null) {
+ toolchainBuilder.addFeature(defaultCompileFlags);
+ }
+ }
+ toolchain = removeSpecialFeatureFromToolchain(toolchain);
CppPlatform platform =
toolchain.getTargetLibc().equals("macosx") ? CppPlatform.MAC : CppPlatform.LINUX;
@@ -452,16 +462,15 @@
return toolchainBuilder.build();
}
- private static CToolchain removeLegacyCompileFlagsFeatureFromToolchain(CToolchain toolchain) {
+ private static CToolchain removeSpecialFeatureFromToolchain(CToolchain toolchain) {
FieldDescriptor featuresFieldDescriptor = CToolchain.getDescriptor().findFieldByName("feature");
return toolchain
.toBuilder()
.setField(
featuresFieldDescriptor,
- toolchain
- .getFeatureList()
- .stream()
+ toolchain.getFeatureList().stream()
.filter(feature -> !feature.getName().equals(CppRuleClasses.LEGACY_COMPILE_FLAGS))
+ .filter(feature -> !feature.getName().equals(CppRuleClasses.DEFAULT_COMPILE_FLAGS))
.collect(ImmutableList.toImmutableList()))
.build();
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
index aa79138..38d12c4 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
@@ -4267,6 +4267,7 @@
" feature(name = 'custom_feature'),",
" feature(name = 'legacy_compile_flags'),",
" feature(name = 'fdo_optimize'),",
+ " feature(name = 'default_compile_flags'),",
" ],",
" action_configs = [action_config(action_name = 'custom-action')],",
" artifact_name_patterns = [artifact_name_pattern(",
@@ -4307,10 +4308,11 @@
.collect(ImmutableSet.toImmutableSet());
// fdo_optimize should not be re-added to the list of features by legacy behavior
assertThat(featureNames).containsNoDuplicates();
- // legacy_compile_flags should appear first in the list of features
- assertThat(featureNames.get(0)).isEqualTo("legacy_compile_flags");
+ // legacy_compile_flags should appear first in the list of features, followed by
+ // default_compile_flags.
assertThat(featureNames)
- .containsAllOf("legacy_compile_flags", "custom_feature", "fdo_optimize")
+ .containsAllOf(
+ "legacy_compile_flags", "default_compile_flags", "custom_feature", "fdo_optimize")
.inOrder();
// assemble is one of the action_configs added as a legacy behavior, therefore it needs to be
// prepended to the action configs defined by the user.