In MinGW environments, thanks to slightly different code generation
and linker tricks, it's possible to link against a DLL C++ standard
library without dllimport attributes.
This allows using one single set of headers for linking against
either the DLL or a static library, leaving the decision entirely
up to the linking stage (where it can be switched with options like
-static-libstdc++).
This matches how libstdc++ headers work; there's no dllimport attributes
by default (unless the user has defined _GLIBCXX_DLL when including
headers).
This allows using one single set of headers while linking against
either a DLL or a static library, just like on Unix platforms.
This matches how libc++ has been used in MinGW configurations for
years (by first building the DLL, then configuring a static-only
build and installing on top, overwriting the libc++ config file
with one for static linking) by multiple MinGW toolchains, making
the dllimport-less use the official, tested configuration. This
also allows building all of libc++ in one single CMake configuration,
instead of having to do two separate builds on top of each other.
(Linking against a DLL without dllimport can break if e.g. templates
use inconsistent visibility attributes - in cases where it still
works when using explicit dllimport; such a case was fixed in
948dd664c3ed30dd853df03cb931436f280bad4a / D99932. With this as the
default configuration, we can catch such issues in CI.)
This patch allows opting in back to dllimports by defining
_LIBCPP_DLLIMPORT. (Alternatively, one could consider a CMake build
time option.)
Aw, I don't like how that gets messy and this condition overlaps with #elif defined(_LIBCPP_BUILDING_LIBRARY) below, but I tried making it better and I don't see how. I suggest we go with this and then I can refactor the whole family of visibility macros to be per-platform, which would make everything much easier to understand IMO.
Also, why do we need to introduce _LIBCPP_DLLIMPORT? Can't we use the new behavior on MinGW unconditionally?