Describe the feature request
When compiling cbits-style code (code that's designed for foreign import only by its containing library), it would be nice if there was some official/automatic way to restrict the symbol visibility of the compiled bundled C code.
AIUI, there are a couple of ways to do this:
Set an attribute on the definitions. This is __attribute__((visibility)) on GCC >=4. I think Clang supports the same syntax and has done so for a long time. Still, it would be nice if we could signal (via #define?) that it's supported, so the code could still work with older compilers (assuming they're supported by GHC). GCC >=5 and at least Clang >=3.6 support the preprocessor symbol __has_attribute(foo), but I don't know if MSVC does, or if GHC even supports MSVC.
Pass -fvisibility=hidden on the command line to set the default visibility and then change it where needed via __attribute__.
In my own C library projects, I only do "visibility stuff" if both №1 and №2 are available (i.e., most of the time on modern systems). When it's available, I set -fvisibility=hidden and then put (a macro that expands to) __attribute__((visibility("default"))) on the public interface. For cbits-type stuff, there shouldn't be a public interface, so we should just be able to hide everything that's foreign imported, as it would only be referenced by the Haskell functions in the same Dynamic Shared Object (DSO).
Note that this isn't a complete solution to the problem, as AIUI static libraries can't do visibility stuff. So you do still risk symbol clashes there (or the linker just picking one, maybe?).
Additional contextcrypton-0.30renamed some of its foreign imports to prevent a symbol clash during linking. This is exactly the "old woe" mentioned by the linked GCC wiki page.
I saw someone on irc://irc.libera.chat/reflex-frp just yesterday having problems with cryptonite (I have advised him to switch to crypton) and libsodium using the same symbols:
7:04 AM Oh no! I almost had my iOS build, but in the very last build step - frontend-static-aarch64-ios-0.1 - I get 'ld: 6 duplicate symbols for architecture arm64'
7:07 AM Via different dependencies, I have two cryptography libraries, 'cryptonite' for Haskell and 'libsodium' for C. Linking them together statically clashes.
7:14 AM All 6 duplicates stem from 'blake2b-ref.o'
9:04 AM I don't think we use blake anywhere in our app. Going to local-fork either cryptonite or libsodium and rip blake2-ref out. Or does anyone here know like, a linker option to make them coexist?
9:04 AM or so?
Describe the feature request When compiling
cbits
-style code (code that's designed forforeign import
only by its containing library), it would be nice if there was some official/automatic way to restrict the symbol visibility of the compiled bundled C code.AIUI, there are a couple of ways to do this:
__attribute__((visibility))
on GCC >=4. I think Clang supports the same syntax and has done so for a long time. Still, it would be nice if we could signal (via#define
?) that it's supported, so the code could still work with older compilers (assuming they're supported by GHC). GCC >=5 and at least Clang >=3.6 support the preprocessor symbol__has_attribute(foo)
, but I don't know if MSVC does, or if GHC even supports MSVC.-fvisibility=hidden
on the command line to set the default visibility and then change it where needed via__attribute__
.In my own C library projects, I only do "visibility stuff" if both №1 and №2 are available (i.e., most of the time on modern systems). When it's available, I set
-fvisibility=hidden
and then put (a macro that expands to)__attribute__((visibility("default")))
on the public interface. Forcbits
-type stuff, there shouldn't be a public interface, so we should just be able to hide everything that'sforeign import
ed, as it would only be referenced by the Haskell functions in the same Dynamic Shared Object (DSO).Note that this isn't a complete solution to the problem, as AIUI static libraries can't do visibility stuff. So you do still risk symbol clashes there (or the linker just picking one, maybe?).
Additional context
crypton-0.30
renamed some of its foreign imports to prevent a symbol clash during linking. This is exactly the "old woe" mentioned by the linked GCC wiki page.I saw someone on irc://irc.libera.chat/reflex-frp just yesterday having problems with
cryptonite
(I have advised him to switch tocrypton
) andlibsodium
using the same symbols: