No, they are extremely broken. You can only choose:
- Link everything static.
- Link everything dynamic.
- Link user libs as static and system libs as dynamic.
There is no easy way to link a single user lib static/dynamic without resorting to hacks/workarounds like re-importing the shared library or defining weird intermediate targets. It's completely broken.
# you'll need a c compiler installed, xcode is fine on macos
git clone https://github.com/emidln/bazel_static_dynamic_c_demo
cd bazel_static_dynamic_c_demo
bazel run //:foo
ldd bazel-bin/foo # otool -L bazel-bin/foo if you're on MacOS
*You are the consumer.* You are consuming it in foo. Are you building some straw man consumer who might want to delve into my build and rearrange my libraries with no work at all? You can even do that if you want. Remove the linkstatic line from qux. Now it has two outputs: `libqux.a` (default) and a `libqux.so` (implicit). If you want to ship both of them in a release artifact, you can. If you want to mark some binaries `linkstatic = True` and statically link them you can. If you want to dyanmically link some binaries, you can do that too.
I was demonstrating that you can force some libraries to be only static and still partially link some things static and some dyanmic. If you want to get really into the weeds, you could even affect the link line and individually pick dependencies in a custom rule (that is fully compatible with the rest of the bazel tooling). Almost nobody ever needs to do that, but maybe you want to make only every other dependency dynamic to satisfy some weird slide in a talk.
You can use the "linkstatic" feature on the cc_library level. Then that library will be linked statically while other cc_library's will be dynamically linked.
The logic is backwards though. I may have multiple consumers of a library some of which may want static some of which may want dynamic. You need to create/import new targets to do this even though the original target creates both static and dynamic libs by default.
This is just false. Bazel creates both static and dynamic libs by default for every cc_library. The default is to link static, but you can control this on a per-binary basis. You don't need parallel trees of targets or even to write custom rules to access the non-default output groups that contain the shared library. This all just works out of the box.
> You're assuming you have control over all the deps and can set `linkstatic` on them.
In bazel you have complete control over all of your deps. Ultimate power and ultimate responsibility. Even an external BUILD.bazel can be patched when you bring it in (bazel has provisions for patching stuff from http_archive if you supply a patch). You can even ignore an existing BUILD.bazel and write your own if you only care about part of an external thing. If it's a target in your graph, you can certainly modify it. If there is some internal process that prevents you from modifying your own code, I can't help you. Maybe fix that or go somewhere that gives you the authority to do your job.
- Link everything static.
- Link everything dynamic.
- Link user libs as static and system libs as dynamic.
There is no easy way to link a single user lib static/dynamic without resorting to hacks/workarounds like re-importing the shared library or defining weird intermediate targets. It's completely broken.