Repository: bazelbuild/bazel
Issue: After upgrading to bazel 7.0.0 gcc fails with: --push-state: unknown option
Labels: type: bug
team-Rules-CPP
untriaged

### Description of the bug:


After upgrading to bazel 7.0.0 the builds in our internal CIs that have an old gcc compiler are failing with:
```
(08:11:06) ERROR: /home/build/.cache/native_bazel_output_base/external/io_grpc_grpc_java/compiler/BUILD.bazel:5:10: Linking external/io_grpc_grpc_java/compiler/grpc_java_plugin [for tool] failed: (Exit 1): gcc failed: error executing CppLink command (from target @@io_grpc_grpc_java//compiler:grpc_java_plugin) 
  (cd /home/build/.cache/native_bazel_output_base/sandbox/processwrapper-sandbox/7179/execroot/core && \
  exec env - \
    PATH=/bin:/usr/bin:/usr/local/bin \
    PWD=/proc/self/cwd \
    ZERO_AR_DATE=1 \
  /usr/bin/gcc @bazel-out/k8-opt-exec-ST-13d3ddad9198/bin/external/io_grpc_grpc_java/compiler/grpc_java_plugin-2.params)
# Configuration: 922915957e448184486ff0fb7f0ba0ee9f92dfb993e46799f9d5193882b93aa1
# Execution platform: @@local_config_platform//:host
```
seems that the check for is_push_state_supported in https://github.com/bazelbuild/bazel/commit/2482322fedb463e0bbecd29c5e8e6d0f087ed884 is not working well



### Which category does this issue belong to?


C++/Objective-C Rules

### What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.


_No response_

### Which operating system are you running Bazel on?


MacOS and Linux

### What is the output of `bazel info release`?


release 7.0.0

### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.


_No response_

### What's the output of `git remote get-url origin; git rev-parse master; git rev-parse HEAD` ?


_No response_

### Is this a regression? If yes, please try to identify the Bazel commit where the bug was introduced.


https://github.com/bazelbuild/bazel/commit/2482322fedb463e0bbecd29c5e8e6d0f087ed884

### Have you found anything relevant by searching the web?

_No response_

### Any other information, logs, or outputs that you want to share?

_No response_

Issue comments:
@bazel-io fork 7.0.1
@fmeum Are you looking into a fix? This seems to be the only blocker for 7.0.1
@meteorcloudy Yes, the speculative fix is https://github.com/bazelbuild/bazel/pull/20833. Unfortunately the reporter is unable to test this and it's also very challenging to cover in integration tests.
A fix for this issue has been included in [Bazel 7.0.1 RC2](https://releases.bazel.build/7.0.1/rc2/index.html). Please test out the release candidate and report any issues as soon as possible. Thanks!

Verified that 7.0.1 fixes this issue.
@bazel-io fork 7.1.0

Pull request review comments:

Patch that resolved the issue:
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
index bb33d6df320b03..fc9d8b7e034b70 100644
--- a/MODULE.bazel.lock
+++ b/MODULE.bazel.lock
@@ -2179,7 +2179,7 @@
       "general": {
         "bzlTransitiveDigest": "rjB9TSLGt3ZwbECWtF/HMgfqMsfEnDLK6fGIe65ZyfE=",
         "accumulatedFileDigests": {
-          "@@//src/test/tools/bzlmod:MODULE.bazel.lock": "5218e8c896592023f884990b7a34f9276e3ce488e753eaaa8bc6057a1aca653c",
+          "@@//src/test/tools/bzlmod:MODULE.bazel.lock": "4e2a1386686aae6d7be071ef615438178fdb93104b5b84cf8a372b6a944b27cd",
           "@@//:MODULE.bazel": "63625ac7809ba5bc83e0814e16f223ac28a98df884897ddd5bfbd69fd4e3ddbf"
         },
         "envVariables": {},
diff --git a/tools/cpp/unix_cc_configure.bzl b/tools/cpp/unix_cc_configure.bzl
index 6d6e7171edc98b..5e7b3b79f427c9 100644
--- a/tools/cpp/unix_cc_configure.bzl
+++ b/tools/cpp/unix_cc_configure.bzl
@@ -161,10 +161,9 @@ def _is_compiler_option_supported(repository_ctx, cc, option):
     ])
     return result.stderr.find(option) == -1
 
-def _is_linker_option_supported(repository_ctx, cc, option, pattern):
+def _is_linker_option_supported(repository_ctx, cc, force_linker_flags, option, pattern):
     """Checks that `option` is supported by the C linker. Doesn't %-escape the option."""
-    result = repository_ctx.execute([
-        cc,
+    result = repository_ctx.execute([cc] + force_linker_flags + [
         option,
         "-o",
         "/dev/null",
@@ -213,9 +212,9 @@ def _add_compiler_option_if_supported(repository_ctx, cc, option):
     """Returns `[option]` if supported, `[]` otherwise. Doesn't %-escape the option."""
     return [option] if _is_compiler_option_supported(repository_ctx, cc, option) else []
 
-def _add_linker_option_if_supported(repository_ctx, cc, option, pattern):
+def _add_linker_option_if_supported(repository_ctx, cc, force_linker_flags, option, pattern):
     """Returns `[option]` if supported, `[]` otherwise. Doesn't %-escape the option."""
-    return [option] if _is_linker_option_supported(repository_ctx, cc, option, pattern) else []
+    return [option] if _is_linker_option_supported(repository_ctx, cc, force_linker_flags, option, pattern) else []
 
 def _get_no_canonical_prefixes_opt(repository_ctx, cc):
     # If the compiler sometimes rewrites paths in the .d files without symlinks
@@ -420,16 +419,40 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools):
         False,
     ), ":")
 
+    gold_or_lld_linker_path = (
+        _find_linker_path(repository_ctx, cc, "lld", is_clang) or
+        _find_linker_path(repository_ctx, cc, "gold", is_clang)
+    )
+    cc_path = repository_ctx.path(cc)
+    if not str(cc_path).startswith(str(repository_ctx.path(".")) + "/"):
+        # cc is outside the repository, set -B
+        bin_search_flags = ["-B" + escape_string(str(cc_path.dirname))]
+    else:
+        # cc is inside the repository, don't set -B.
+        bin_search_flags = []
+    if not gold_or_lld_linker_path:
+        ld_path = repository_ctx.path(tool_paths["ld"])
+        if ld_path.dirname != cc_path.dirname:
+            bin_search_flags.append("-B" + str(ld_path.dirname))
+    force_linker_flags = []
+    if gold_or_lld_linker_path:
+        force_linker_flags.append("-fuse-ld=" + gold_or_lld_linker_path)
+
+    # TODO: It's unclear why these flags aren't added on macOS.
+    if bin_search_flags and not darwin:
+        force_linker_flags.extend(bin_search_flags)
     use_libcpp = darwin or bsd
     is_as_needed_supported = _is_linker_option_supported(
         repository_ctx,
         cc,
+        force_linker_flags,
         "-Wl,-no-as-needed",
         "-no-as-needed",
     )
     is_push_state_supported = _is_linker_option_supported(
         repository_ctx,
         cc,
+        force_linker_flags,
         "-Wl,--push-state",
         "--push-state",
     )
@@ -463,21 +486,6 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools):
         bazel_linklibs,
         False,
     ), ":")
-    gold_or_lld_linker_path = (
-        _find_linker_path(repository_ctx, cc, "lld", is_clang) or
-        _find_linker_path(repository_ctx, cc, "gold", is_clang)
-    )
-    cc_path = repository_ctx.path(cc)
-    if not str(cc_path).startswith(str(repository_ctx.path(".")) + "/"):
-        # cc is outside the repository, set -B
-        bin_search_flags = ["-B" + escape_string(str(cc_path.dirname))]
-    else:
-        # cc is inside the repository, don't set -B.
-        bin_search_flags = []
-    if not gold_or_lld_linker_path:
-        ld_path = repository_ctx.path(tool_paths["ld"])
-        if ld_path.dirname != cc_path.dirname:
-            bin_search_flags.append("-B" + str(ld_path.dirname))
     coverage_compile_flags, coverage_link_flags = _coverage_flags(repository_ctx, darwin)
     print_resource_dir_supported = _is_compiler_option_supported(
         repository_ctx,
@@ -610,19 +618,18 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools):
             ),
             "%{cxx_flags}": get_starlark_list(cxx_opts + _escaped_cplus_include_paths(repository_ctx)),
             "%{conly_flags}": get_starlark_list(conly_opts),
-            "%{link_flags}": get_starlark_list((
-                ["-fuse-ld=" + gold_or_lld_linker_path] if gold_or_lld_linker_path else []
-            ) + (
+            "%{link_flags}": get_starlark_list(force_linker_flags + (
                 ["-Wl,-no-as-needed"] if is_as_needed_supported else []
             ) + _add_linker_option_if_supported(
                 repository_ctx,
                 cc,
+                force_linker_flags,
                 "-Wl,-z,relro,-z,now",
                 "-z",
             ) + (
                 [
                     "-headerpad_max_install_names",
-                ] if darwin else bin_search_flags + [
+                ] if darwin else [
                     # Gold linker only? Can we enable this by default?
                     # "-Wl,--warn-execstack",
                     # "-Wl,--detect-odr-violations"
@@ -664,6 +671,7 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools):
                 ["-Wl,-dead_strip"] if darwin else _add_linker_option_if_supported(
                     repository_ctx,
                     cc,
+                    force_linker_flags,
                     "-Wl,--gc-sections",
                     "-gc-sections",
                 ),


Test patch:
diff --git a/src/test/tools/bzlmod/MODULE.bazel.lock b/src/test/tools/bzlmod/MODULE.bazel.lock
index 86ee343f5e44ff..aa7908c026fe7d 100644
--- a/src/test/tools/bzlmod/MODULE.bazel.lock
+++ b/src/test/tools/bzlmod/MODULE.bazel.lock
@@ -642,7 +642,13 @@
             }
           }
         },
-        "recordedRepoMappingEntries": []
+        "recordedRepoMappingEntries": [
+          [
+            "apple_support~1.5.0",
+            "bazel_tools",
+            "bazel_tools"
+          ]
+        ]
       }
     },
     "@@bazel_tools//tools/android:android_extensions.bzl%remote_android_tools_extensions": {
@@ -675,7 +681,7 @@
     },
     "@@bazel_tools//tools/cpp:cc_configure.bzl%cc_configure_extension": {
       "general": {
-        "bzlTransitiveDigest": "O9sf6ilKWU9Veed02jG9o2HM/xgV/UAyciuFBuxrFRY=",
+        "bzlTransitiveDigest": "mcsWHq3xORJexV5/4eCvNOLxFOQKV6eli3fkr+tEaqE=",
         "accumulatedFileDigests": {},
         "envVariables": {},
         "generatedRepoSpecs": {
@@ -694,7 +700,13 @@
             }
           }
         },
-        "recordedRepoMappingEntries": []
+        "recordedRepoMappingEntries": [
+          [
+            "bazel_tools",
+            "bazel_tools",
+            "bazel_tools"
+          ]
+        ]
       }
     },
     "@@bazel_tools//tools/osx:xcode_configure.bzl%xcode_configure_extension": {
@@ -1292,7 +1304,18 @@
             }
           }
         },
-        "recordedRepoMappingEntries": []
+        "recordedRepoMappingEntries": [
+          [
+            "rules_java~7.1.0",
+            "bazel_tools",
+            "bazel_tools"
+          ],
+          [
+            "rules_java~7.1.0",
+            "remote_java_tools",
+            "rules_java~7.1.0~toolchains~remote_java_tools"
+          ]
+        ]
       }
     },
     "@@rules_python~0.4.0//bzlmod:extensions.bzl%pip_install": {
@@ -1368,7 +1391,18 @@
             }
           }
         },
-        "recordedRepoMappingEntries": []
+        "recordedRepoMappingEntries": [
+          [
+            "rules_python~0.4.0",
+            "bazel_tools",
+            "bazel_tools"
+          ],
+          [
+            "rules_python~0.4.0",
+            "rules_python",
+            "rules_python~0.4.0"
+          ]
+        ]
       }
     }
   }