Cross-Platform Control of Symbols Exported by a Shared Library
See original GitHub issueDescription of feature request:
In going with Bazel’s cross-platform goals and the general magic of semantically expressing the build you want and having it work across platforms:
It’d be awesome if cc_library rules had a cross-platform attribute for controlling which symbols are exported from a shared library, forming its binary interface.
I’m imagining the best interface would be an attribute on cc_library, where you specify a list of globs, and symbols are exported iff they match one of those globs. (more on why at the end)
Feature requests: what underlying problem are you trying to solve with this feature?
It’s often important to control which symbols from a shared library. In addition to defining a clean interface, it’s important to let the linker know about the interface to strip out dead code. Also, it’s easy to end up with symbol conflicts and nasty bugs if you leak a bunch of symbols, and, e.g. accidentally (privately) statically depend on a different version of a library than another library in the same process. Bad times.
I’m working on a cross-platform project (part of why Bazel is a good fit!) and wrote platform-specific code to implement this. From the issues, online discussion, and existing Windows DEF files support in cc rules, it looks like there’s a solid amount of interest in being able to control the interface of shared libraries. This feature request is about making that functionality cross-platform instead of platform specific.
The visibility attribute (or DLL export type annotations) approach to controlling symbols typically fails, in my experience, because libraries you depend on (e.g. Boost) often set their own interfaces as default visible, which means you end up exporting their whole interface, with no easy fix. The idea of annotating code as “interface” isn’t a great one anyway, since good code contains many nested interfaces. One man’s interface is another’s implementation. Better to succinctly describe your top-level interface.
Lists of symbols to export (or not export) seems to be the best way to succinctly describe that interface. Globs are important for handling mangled C++ symbols and namespacing (C++ or as C-style symbol prefixes). Apple platforms and Android/Linux have converged around different, but equivalent ways of doing that (-exported_symbol
vs --version-script
ldscripts). Both are easily generated from a list of symbol globs. I don’t know about Windows yet, but can imagine generating a DEF file from glob over the symbols list? I feel pretty confident in the Apple/Android/Linux solution I wrote in Starlark and would be happy to share–less confident in my understanding of the Bazel native cc rules and Windows.
Thanks for your consideration, Chris
Issue Analytics
- State:
- Created 2 years ago
- Comments:19 (18 by maintainers)
Thank you for your input too.
So the story with cc_shared_library being experimental is that I wanted a major project to validate it before removing the experimental flag. The person who was migrating Tensorflow to using the rule left and no one took over that. Currently, Roboleaf (moving AOSP to Bazel) is using it so that should be enough to validate it. At the same time any other projects using it and reporting problems would be helpful.
To give you a timeline I’d say I will have enough of a signal in Q3 to feel confident about removing the flag. But I’d very much appreciate it if you tried it yourself and gave me feedback too.
Alright, I’m convinced now this sounds more generally useful than I thought at first. This will still need to be incorporated to cc_shared_library though, not cc_library.