New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 874701 link

Starred by 1 user

Issue metadata

Status: Assigned
Owner:
Last visit 25 days ago
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Bug



Sign in to add a comment

static libraries don't propagate across shared libraries in GN builds?

Project Member Reported by dpranke@chromium.org, Aug 16

Issue description

From https://crrev.com/c/1160648/3/third_party/blink/public/common/BUILD.gn#97 ...

In that CL, drott@ wants to change things so that if a target depends on //third_party/blink/public/common, they have to depend on //third_party/blink/public/common:font_unique_name_table_proto, so that a user of public/common (like //content/browser) doesn't need to directly depend on it.

So, for convenience we'll label these as A, B, and C:

//content/browser (A) ->
  //third_party/blink/public/common (B) ->
    //third_party/blink/public/common:font_unique_name_table_proto (C)

This looks like a case for public_deps, i.e., B would simply declare C as a public_dep, not a dep.

However, in  the desired build config, B is a shared_library (component), and C is a static_library, and it looks like things are implemented such that static_libraries do *not* propagate across the shared_library boundary, and so if you try to link A, you'll get linker errors from the missing C (whereas in a static build, I think this would work fine).

I believe this is by design, because it reduces the possibility for multiple linkage (C getting linked into both A and B, potentially violating ODR rules), and, in general, multiple linkage like this would be bad.

I think there are two workarounds for this. The first is for A to explicitly declare the dependency on C, which is in fact what the original CL did. The second is to change things so that C is a component, not a static library, since shared_library deps *do* propagate across, since they won't be multiply-linked. I suspect the second is probably preferable, since it would reduce multiple linkage and produce similar behavior across shared and static builds.

My questions for brettw@ are:

(1) Does this all sound correct?

(2) Do you think it might make sense for us to have some sort of flag to indicate that a static_library (or a source_set) can be safely multiply-linked and should propagate across?

My guess is that the answer is, no, it's probably to accidentally make something stop being multiple-link-safe, but I thought I'd double-check.

If your answers are "yes" and "no", respectively, then I think it's safe to close this as WontFix, unless we're both missing something, in which case drott@ can hopefully speak up :).

 
Changing C to a component sounds like the right thing. We definitely don't want to start duplicate linking static libraries all over the place.
C (font_unique_name_table_proto) is using the proto_library() template, which I think means it is built as either a source_set or static_library, yes.
https://cs.chromium.org/chromium/src/third_party/protobuf/proto_library.gni?q=proto_library&sq=package:chromium&g=0&l=321

Would it make sense for that template to output as a component instead? I am not sure it would, in which case, I am fine closing this as WontFix.

Dirk, thank you very much for taking the time to analyze this and explain in detail. It made it really clear what's going on and now I understand why I struggled with this part of the BUILD.gn changes.


Sign in to add a comment