Open keith opened 5 months ago
Cc @oquenchil
exports_filter
takes a target pattern but this attribute affects a property of the cc_shared_library
itself. LINKABLE_MORE_THAN_ONCE
is a property of each individual cc_library
, if you do something similar from cc_shared_library
, then you are potentially affecting other parts of the graph that you might not own. Say you mark the dependency library foo
as LINKABLE_MORE_THAN_ONCE
transitively from your cc_shared_library
, perhaps you don't own this cc_library
yourself but you have marked it as such (maybe you haven't even seen its code). Then a different cc_shared_library
somewhere downstream whose package you don't own either will treat the cc_library
as LINKABLE_MORE_THAN_ONCE
when it shouldn't be and you introduce a bug.
More about why this belongs in the cc_library
itself is that by looking at the cc_shared_library
you don't know whether foo
is indeed linkable more than once. Only by looking at the code itself which would be in a cc_library
target potentially in package very far away from the cc_shared_library
would you know whether it should be marked as such. The strategy of placing it in the cc_shared_library
would mostly be about finding out empirically what cc_libraries
should be on the list for your particular build at that point in time, potentially breaking later if you missed any on the list or changed other things in the graph.
In summary, doing this change as suggested would break LINKABLE_MORE_THAN_ONCE
. I'm no longer working on the C++ rules but my recommendation for the quickest fix to the current owners would be:
experimental_link_static_libraries_once
gets its experimental_*
prefix removedcc_libraries
are NOT linkable more than once by default (this is already the default value, I'm just listing it here to emphasize that it should stay like that)If this functionality is more a burden than helpful for any project, they can switch off the functionality. It can be switched off today already with the --experimental_link_static_libraries_once=false
flag.
For your particular case with LLVM if I understand correctly it is not that 750 libraries are really LINKABLE_MORE_THAN_ONCE
but that because many of those are stripped, it doesn’t really matter if different cc_shared_libraries
link them statically. If you marked them LINKABLE_MORE_THAN_ONCE
transitively and other cc_shared_libraries
in your graph linked them too without stripping them, you might get bugs.
The LINKABLE_MORE_THAN_ONCE
check could potentially be pushed to the execution phase as far as I can tell and the errors could be omitted for libraries whose symbols are not actually appearing in the final shared object. The action would have to write a list that is then used by other cc_shared_library
downstream actions that perform the same check. This would require writing a lot of tooling for the different platforms so that the symbols can be analyzed. I think writing this tooling would be more in the scope of the language tool teams than of Bazel which is just the build system after all. The community could also potentially contribute those tools.
Description of the feature request:
Currently if you have a large dependency tree that is linked into a cc_shared_library, but then potentially linked into other libraries as well, you have to either export all the transitive symbols, or mark every transitive dep with
tags = ["LINKABLE_MORE_THAN_ONCE"]
. For large dependency trees adding this tag everywhere feels pretty heavy handed, especially when it's likely most of those libraries don't know if they should be linked more than once or not.In my example in llvm, there is a shared lldb library, which links many of the transitive llvm dependency libraries. This shared library only exports a very specific set of symbols, and everything else is hidden and stripped. In this case if you depend on this shared library, as well as the other llvm libraries, you would have to mark up to 750 cc_library targets with
LINKABLE_MORE_THAN_ONCE
.I think it would be useful to consider other options for how to limit the duplicate linking here. One option could be a list of libraries on the cc_shared_library itself, so that it is the source of truth for this (ideally using some target pattern instead of individual libraries). Another option could be to have a different type of list for the ones that aren't allowed to be linked more than once instead, since that's the less common case in this example.
Any other ideas?
Which category does this issue belong to?
C++ Rules
What underlying problem are you trying to solve with this feature?
No response
Which operating system are you running Bazel on?
Linux
What is the output of
bazel info release
?7.1.1
If
bazel info release
returnsdevelopment 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 HEAD
?No response
Have you found anything relevant by searching the web?
No response
Any other information, logs, or outputs that you want to share?
No response