There's no reason to treat Windows specially, users of libc++ can define
_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS just like they would on other
platforms.
See http://lists.llvm.org/pipermail/libcxx-dev/2020-October/000978.html
for more details.
Differential D88843
[libcxx] Don't treat Windows specially with visibility annotations phosek on Oct 5 2020, 11:49 AM. Authored by
Details There's no reason to treat Windows specially, users of libc++ can define See http://lists.llvm.org/pipermail/libcxx-dev/2020-October/000978.html
Diff Detail
Event TimelineComment Actions According to git blame this change was authored by @smeenai in rG546442160881b, @smeenai do you know what was the motivation for having a special handling on Windows? Comment Actions I think the reason for this restriction is that on Windows, __declspec(dllimport) changes the compiler's code generation to assume that the symbol will be imported (i.e. if the compiler sees a call to a function X which is marked __declspec(dllimport), it'll generate an indirect call to __imp_X instead). If you're linking against libc++ statically, the imported version of the symbol will of course not exist, so you want to disable the __declspec(dllimport) annotations by default if you're building just the static library for Windows. (IIRC, Microsoft's linker actually supports this case; it'll generate a dummy __imp_X for you pointing to the local X symbol, but it'll also give you a warning about doing so. I think LLD COFF supports that as well. It's just less clean to do it that way.) Since this is Windows-specific behavior (or technically dllimport-specific behavior), perhaps it makes more sense to do some Windows-specific visibility macro adjustments than overloading the cross-platform _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS for this purpose? Comment Actions I'm happy with removing this special case, especially since the linker handles it. I believe it makes more sense for a vendor shipping the static archive to disable these annotations explicitly instead. Comment Actions I'm a "vendor" building libc++ for windows, both statically and dynamically, and without this, I'll need to manually inject a #define _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS into the installed headers somehow. At least in my experience, code generation with headers lacking dllimport attributes, but linking against an import library for a DLL, works much better than building user code with dllimport but linking against a static library. (Yes, the linker can sometimes generate the __imp_ stubs for dllimport linking against oneself, but iirc it doesn't work flawlessly for things like libc++.) Also cc @thieta Comment Actions And to be clear, this isn't about manually defining _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS while building libc++ itself; it needs to be defined whenever user code includes libc++ headers. Comment Actions So to be very clear, I'd prefer this not to be committed, as it will break my build setup, and the way for me to work around it isn't very pretty. A different potential way forward would be to default to not using visibility annotations on windows, making them opt-in instead of opt-out. Because at least in my experience in mingw configurations, mismatches between actual libc++ vs option set in the user's code works much better if the visibility annotations are disabled. IIRC @thieta just ran into the same issue a few weeks ago as well and concluded the same. Comment Actions Let's add a proper LIBCXX_DISABLE_VISIBILITY_ANNOTATIONS option and config_define_if(LIBCXX_DISABLE_VISIBILITY_ANNOTATIONS _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) like we do for other __config_site macros. Then, you can configure your build with -DLIBCXX_DISABLE_VISIBILITY_ANNOTATIONS and remove the platform specific logic from libc++'s CMake. WDYT? Comment Actions That sounds good to me and would be easy to configure going forward. Not sure how well it works in practice with @phosek 's original usecase from http://lists.llvm.org/pipermail/libcxx-dev/2020-October/000978.html, wanting to use one single __config_site for libc++ for multiple targets at once though. Comment Actions Possible solution would be to allow per-target __config which is something I was going to propose separately since we have other use cases for it. That is, we would share headers across targets, but each target would have its own __config. This approach is already used by libstdc++. I have a local prototype and the implementation is pretty straightforward. Comment Actions __config_site is the only file that differs across targets, but we always concat it with __config so I assumed we're going to have a per-target copy of __config, but we could make this even granular by keeping them separate and using #include <__config_site> guarded by #if __has_include(<__config_site>) ... #endif inside __config. Would that be preferable? Comment Actions Actually, I have a patch that changes libc++ to use #include <__config_site>. I've been wanting to do that for a while. Let me put it up for review. |