Repository: bazelbuild/bazel
Issue: 7.0.0rc2 regression from 6.4.0 (new throw_linked_but_not_exported_errors)
Labels: type: bug
team-Rules-CPP
untriaged

### Description of the bug:


I have a number of header-file-only libraries, and link these into a number of our shared libraries:

Since upgrading from bazel 6.4.0 to bazel 7.0.0rc2, I am getting this error:

```
ERROR: D:/units/cb_bazel/src/path/to/BUILD.bazel:3:21: in cc_shared_library rule //src/path/to/z:libz:
Traceback (most recent call last):
        File "/virtual_builtins_bzl/common/cc/cc_shared_library.bzl", line 661, column 114, in _cc_shared_library_impl
        File "/virtual_builtins_bzl/common/cc/cc_shared_library.bzl", line 527, column 42, in _filter_inputs
        File "/virtual_builtins_bzl/common/cc/cc_shared_library.bzl", line 545, column 9, in _throw_linked_but_not_exported_errors
Error in fail: The following libraries were linked statically by different cc_shared_libraries but not exported:
cc_shared_library @@//src/path/to/lib:lib:
  "@@//src/path/to:include_root",
  "@@x//:libx_headers",
  "@@cpputils//:cpputils",
If you are sure that the previous libraries are exported by the cc_shared_libraries because:
  1. You have visibility declarations in the source code
  2. Or you are passing a visibility script to the linker to export symbols from them
then add those libraries to roots or exports_filter for each cc_shared_library.
```

what these dependent libraries have in common is that they are include-only:

```
cc_library(
    name = "cpputils",
    hdrs = glob(["include/cpputils/fmt/*.h", "include/cpputils/*.hxx"]),
    includes = ["include"],
)
```


### 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?


Windows

### What is the output of `bazel info release`?


release 7.0.0rc2

### 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.


Yes, 6.4.0 did not have this issue

### 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:
Could you check whether this is fixed with `USE_BAZEL_VERSION=d15ea929e2382b7354cb900b89fc22480b60ff4d`? Could be the same root cause as https://github.com/bazelbuild/bazel/issues/19822.
No, unfortunately USE_BAZEL_VERSION=d15ea929e2382b7354cb900b89fc22480b60ff4d does not fix it, exactly the same error message is produced.

```
D:\udu\units\cb_1012_bazel>bazel info release
2023/10/23 16:41:15 Using unreleased version at commit d15ea929e2382b7354cb900b89fc22480b60ff4d
WARNING: Option 'experimental_remote_build_event_upload' is deprecated: Use --remote_build_event_upload instead
WARNING: Option 'experimental_remote_cache_compression' is deprecated: Use --remote_cache_compression instead
INFO: Invocation ID: b90d014e-9200-45cf-ae56-2a2b3812852e
development version
```
@bazel-io flag
@bazel-io fork 7.0.0
Hitting the exact same issue here, with the only (potential) difference that I disable bzlmod. How can we help debugging this ?

Also, turning the cc_shared_library into a cc_library works, with the obvious issue that it does not build the same thing in the end.
CC @oquenchil 
Fix is on the way

@bazel-io fork 7.0.0
Reopening since the fix has been rolled back.
Hi all, is this still on track for 7.0? We're trying to close out the open release blockers and prepare for the final RC on Wed.
Cc @buildbreaker2021 
@peakschris I have a potential fix, however it would be nice to have a minimal example to reproduce this to make sure that the fix is correct.
@peakschris We have the potential fix submitted, we will backport it into 7.0 and have a new rc today. Please help verify the fix when it's available. You can also test with Bazel built from HEAD with Bazelisk by setting `USE_BAZEL_VERSION=last_green`.
@meteorcloudy 

Let me know if you'd like for me to open a new issue for this, but I'm still hitting errors on 7.1.0.

I've created a small repro here: https://github.com/Ryang20718/repro-cpp-linker

if you clone it and run `bazelisk test //rust:rust_example_test` you'll hit a similar error 

```
Error in fail: The following libraries were linked statically by different cc_shared_libraries but not exported:
cc_shared_library @proj//:proj_so:
```

@Ryang20718 Yes, please file a separate issue.

@meteorcloudy I suspect that some of the issues could be due to the `--enable_bzlmod` flip and its effect on Label stringification. https://github.com/bazelbuild/bazel/pull/21622 would fix that.

Pull request review comments:

Patch that resolved the issue:
diff --git a/src/main/starlark/builtins_bzl/common/cc/cc_shared_library.bzl b/src/main/starlark/builtins_bzl/common/cc/cc_shared_library.bzl
index 7faa8086d49d5a..a70dea701550b3 100644
--- a/src/main/starlark/builtins_bzl/common/cc/cc_shared_library.bzl
+++ b/src/main/starlark/builtins_bzl/common/cc/cc_shared_library.bzl
@@ -454,6 +454,11 @@ def _filter_inputs(
             _add_linker_input_to_dict(linker_input.owner, transitive_exports[owner])
             linker_inputs_count += 1
         elif owner in targets_to_be_linked_statically_map:
+            if semantics.is_bazel and not linker_input.libraries:
+                # TODO(bazel-team): semantics.should_create_empty_archive() should be
+                # cleaned up and return False in every case. cc_libraries shouldn't
+                # produce empty archives. For now issue #19920 is only fixed in Bazel.
+                continue
             if owner in link_once_static_libs_map:
                 # We are building a dictionary that will allow us to give
                 # proper errors for libraries that have been linked multiple
diff --git a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl
index 4e94de7a36c15a..922e24dffd2e12 100644
--- a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl
+++ b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl
@@ -193,4 +193,5 @@ semantics = struct(
     check_cc_shared_library_tags = _check_cc_shared_library_tags,
     BUILD_INFO_TRANLATOR_LABEL = "@bazel_tools//tools/build_defs/build_info:cc_build_info",
     CC_PROTO_TOOLCHAIN = "@rules_cc//cc/proto:toolchain_type",
+    is_bazel = True,
 )


Test patch:
diff --git a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/BUILD.builtin_test b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/BUILD.builtin_test
index c60473a3c432e3..dd99fbbfd35b77 100644
--- a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/BUILD.builtin_test
+++ b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/BUILD.builtin_test
@@ -156,7 +156,7 @@ cc_library(
         "//conditions:default": [],
     }),
     deps = select({
-        ":is_bazel": ["qux2"],
+        ":is_bazel": ["qux2", "hdr_only"],
         "//conditions:default": [],
     }) + [
         "bar",
@@ -298,7 +298,7 @@ cc_library(
     deps = [
         "barX",
     ] + select({
-        ":is_bazel": ["qux2"],
+        ":is_bazel": ["qux2", "hdr_only"],
         "//conditions:default": [],
     }),
 )
@@ -449,6 +449,17 @@ cc_library(
     srcs = [":private_cc_library.cc"]
 )
 
+genrule(
+    name = "hdr_only_hdr",
+    outs = ["hdr_only_hdr.h"],
+    cmd = "touch $@",
+)
+
+cc_library(
+    name = "hdr_only",
+    hdrs = [":hdr_only_hdr"],
+)
+
 build_failure_test(
     name = "two_dynamic_deps_same_export_in_so_test",
     message = "Two shared libraries in dependencies export the same symbols",